Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pass ExecCtx and result by reference to apply() #2376

Closed
Closed
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
40 changes: 20 additions & 20 deletions velox/benchmarks/basic/Preproc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class BaseFunction : public exec::VectorFunction {
const SelectivityVector& rows,
std::vector<VectorPtr>& args,
const TypePtr& resultType,
exec::EvalCtx* context,
VectorPtr* result) const override {
exec::EvalCtx& context,
VectorPtr& result) const override {
if (args[0]->isConstantEncoding() &&
args[1]->encoding() == VectorEncoding::Simple::FLAT) {
// Fast path for (flat, const).
Expand All @@ -51,7 +51,7 @@ class BaseFunction : public exec::VectorFunction {
auto rawResults =
getRawResults(rows, args[1], rawValues, resultType, context, result);

context->applyToSelectedNoThrow(rows, [&](auto row) {
context.applyToSelectedNoThrow(rows, [&](auto row) {
rawResults[row] = Operation::apply(constant, rawValues[row]);
});
} else if (
Expand All @@ -65,7 +65,7 @@ class BaseFunction : public exec::VectorFunction {
auto rawResults =
getRawResults(rows, args[0], rawValues, resultType, context, result);

context->applyToSelectedNoThrow(rows, [&](auto row) {
context.applyToSelectedNoThrow(rows, [&](auto row) {
rawResults[row] = Operation::apply(rawValues[row], constant);
});
} else if (
Expand All @@ -78,20 +78,20 @@ class BaseFunction : public exec::VectorFunction {
auto rawB = flatB->mutableRawValues();

T* rawResults = nullptr;
if (!(*result)) {
if (!result) {
if (BaseVector::isReusableFlatVector(args[0])) {
rawResults = rawA;
*result = std::move(args[0]);
result = std::move(args[0]);
} else if (BaseVector::isReusableFlatVector(args[1])) {
rawResults = rawB;
*result = std::move(args[1]);
result = std::move(args[1]);
}
}
if (!rawResults) {
rawResults = prepareResults(rows, resultType, context, result);
}

context->applyToSelectedNoThrow(rows, [&](auto row) {
context.applyToSelectedNoThrow(rows, [&](auto row) {
rawResults[row] = Operation::apply(rawA[row], rawB[row]);
});
} else {
Expand All @@ -100,11 +100,11 @@ class BaseFunction : public exec::VectorFunction {
auto a = decodedArgs.at(0);
auto b = decodedArgs.at(1);

BaseVector::ensureWritable(rows, resultType, context->pool(), result);
BaseVector::ensureWritable(rows, resultType, context.pool(), result);
auto rawResults =
(*result)->asUnchecked<FlatVector<T>>()->mutableRawValues();
result->asUnchecked<FlatVector<T>>()->mutableRawValues();

context->applyToSelectedNoThrow(rows, [&](auto row) {
context.applyToSelectedNoThrow(rows, [&](auto row) {
rawResults[row] =
Operation::apply(a->valueAt<T>(row), b->valueAt<T>(row));
});
Expand All @@ -115,25 +115,25 @@ class BaseFunction : public exec::VectorFunction {
T* prepareResults(
const SelectivityVector& rows,
const TypePtr& resultType,
exec::EvalCtx* context,
VectorPtr* result) const {
BaseVector::ensureWritable(rows, resultType, context->pool(), result);
(*result)->clearNulls(rows);
return (*result)->asUnchecked<FlatVector<T>>()->mutableRawValues();
exec::EvalCtx& context,
VectorPtr& result) const {
BaseVector::ensureWritable(rows, resultType, context.pool(), result);
result->clearNulls(rows);
return result->asUnchecked<FlatVector<T>>()->mutableRawValues();
}

T* getRawResults(
const SelectivityVector& rows,
VectorPtr& flat,
T* rawValues,
const TypePtr& resultType,
exec::EvalCtx* context,
VectorPtr* result) const {
exec::EvalCtx& context,
VectorPtr& result) const {
// Check if input can be reused for results.
T* rawResults;
if (!(*result) && BaseVector::isReusableFlatVector(flat)) {
if (!result && BaseVector::isReusableFlatVector(flat)) {
rawResults = rawValues;
*result = std::move(flat);
result = std::move(flat);
} else {
rawResults = prepareResults(rows, resultType, context, result);
}
Expand Down
16 changes: 8 additions & 8 deletions velox/docs/develop/lambda-functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ to "b":
.. code-block:: sql
> select filter(a, x -> x >= b)
[3, 4]
[5, 6, 7]
Expand Down Expand Up @@ -86,7 +86,7 @@ compact form. In most cases lambda expression is the same for all rows, but it
is possible for different rows to be associated with different lambdas as we
have seen above. FunctionVector stores a list of different lambdas along with a
set of rows each lambda applies to. Each lambda is represented as an object of
type Callable which allows for evaluating the lambda on a set of rows.
type Callable which allows for evaluating the lambda on a set of rows.

.. code-block:: c++

Expand All @@ -96,9 +96,9 @@ type Callable which allows for evaluating the lambda on a set of rows.
void apply(
const SelectivityVector& rows,
BufferPtr wrapCapture,
exec::EvalCtx* context,
exec::EvalCtx& context,
const std::vector<VectorPtr>& args,
VectorPtr* result);
VectorPtr& result);
};

The "apply" method of Callable is similar to the "apply" method of
Expand Down Expand Up @@ -210,20 +210,20 @@ in a test:
.. code-block:: c++

auto rowType = ROW({"a", "b"}, {ARRAY(BIGINT()), BIGINT()});

registerLambda("lambda", ROW({"x"}, {BIGINT()}), rowType, "x >= b"));

auto result =
evaluate<BaseVector>("filter(a, function('lambda'))", data);

The first argument to registerLambda is the name for the lambda. This name can
later be used to refer to the lambda in a function call.
later be used to refer to the lambda in a function call.

The second argument is the signature of the lambda, e.g. the list of lambda
parameters along with their names and types.
parameters along with their names and types.

The third argument is the type of the input data to the overall expression. This
is used to resolve the types of captures.
is used to resolve the types of captures.

The last argument is the lambda body as SQL expression.

Expand Down
30 changes: 15 additions & 15 deletions velox/docs/develop/scalar-functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -803,8 +803,8 @@ implement the “apply” method.
const SelectivityVector& rows,
std::vector<VectorPtr>& args,
Expr* caller,
EvalCtx* context,
VectorPtr* result) const
EvalCtx& context,
VectorPtr& result) const

Input rows
^^^^^^^^^^
Expand Down Expand Up @@ -918,13 +918,13 @@ Here is an example of using moveOrCopyResult to implement map_keys function:
const SelectivityVector& rows,
std::vector<VectorPtr>& args,
exec::Expr* /* caller */,
exec::EvalCtx* context,
VectorPtr* result) const override {
exec::EvalCtx& context,
VectorPtr& result) const override {
auto mapVector = args[0]->as<MapVector>();
auto mapKeys = mapVector->mapKeys();
auto localResult = std::make_shared<ArrayVector>(
context->pool(),
context.pool(),
ARRAY(mapKeys->type()),
mapVector->nulls(),
rows.end(),
Expand All @@ -933,7 +933,7 @@ Here is an example of using moveOrCopyResult to implement map_keys function:
mapKeys,
mapVector->getNullCount());

context->moveOrCopyResult(localResult, rows, result);
context.moveOrCopyResult(localResult, rows, result);
}

Use BaseVector::ensureWritable method to initialize “result” to a flat
Expand All @@ -958,12 +958,12 @@ cardinality function for maps:
const SelectivityVector& rows,
std::vector<VectorPtr>& args,
exec::Expr* /* caller */,
exec::EvalCtx* context,
VectorPtr* result) const override {
exec::EvalCtx& context,
VectorPtr& result) const override {
BaseVector::ensureWritable(rows, BIGINT(), context->pool(), result);
BaseVector::ensureWritable(rows, BIGINT(), context.pool(), result);
BufferPtr resultValues =
(*result)->as<FlatVector<int64_t>>()->mutableValues(rows.size());
result->as<FlatVector<int64_t>>()->mutableValues(rows.size());
auto rawResult = resultValues->asMutable<int64_t>();

auto mapVector = args[0]->as<MapVector>();
Expand All @@ -987,8 +987,8 @@ as a simple function. I’m using it here for illustration purposes only.
.. code-block:: c++

// Initialize flat results vector.
BaseVector::ensureWritable(rows, DOUBLE(), context->pool(), result);
auto rawResults = (*result)->as<FlatVector<int64_t>>()->mutableRawValues();
BaseVector::ensureWritable(rows, DOUBLE(), context.pool(), result);
auto rawResults = result->as<FlatVector<int64_t>>()->mutableRawValues();

// Decode the arguments.
DecodedArgs decodedArgs(rows, args, context);
Expand Down Expand Up @@ -1074,7 +1074,7 @@ catch block.
try {
// ... calculate and store the result for the row
} catch (const std::exception& e) {
context->setError(row, std::current_exception());
context.setError(row, std::current_exception());
}
});

Expand All @@ -1083,14 +1083,14 @@ instead of the explicit try-catch block above:

.. code-block:: c++

context->applyToSelectedNoThrow(rows, [&](auto row) {
context.applyToSelectedNoThrow(rows, [&](auto row) {
// ... calculate and store the result for the row
});


Simple functions are compatible with the TRY expression by default. The framework
wraps the “call” and “callNullable” methods in a try-catch and reports errors
using context->setError.
using context.setError.

Registration
^^^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion velox/docs/monthly-updates/march-2022.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Now consider a function that generates Array<int64_t> as an output. The result v

VectorPtr result;
// Here type is ArrayType(BIGINT()).
BaseVector::ensureWritable(rows, type, pool_, &result);
BaseVector::ensureWritable(rows, type, pool_, result);

// Define a vector writer. ArrayWriterT is a temp holder. Eventually, Array will be used
// once old writers are deprecated.
Expand Down
18 changes: 9 additions & 9 deletions velox/duckdb/functions/DuckFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,10 @@ VectorPtr createVeloxVector(
const SelectivityVector& rows,
LogicalType type,
size_t count,
exec::EvalCtx* context) {
exec::EvalCtx& context) {
auto resultType = toVeloxType(type);
auto result = BaseVector::create(resultType, count, context->pool());
context->ensureWritable(rows, resultType, result);
auto result = BaseVector::create(resultType, count, context.pool());
context.ensureWritable(rows, resultType, result);
return result;
}

Expand Down Expand Up @@ -420,30 +420,30 @@ class DuckDBFunction : public exec::VectorFunction {
const SelectivityVector& rows,
std::vector<VectorPtr>& args,
const TypePtr& /* outputType */,
EvalCtx* context,
VectorPtr* result) const override {
EvalCtx& context,
VectorPtr& result) const override {
// FIXME: this binding does not need to be performed on every function call
std::vector<LogicalType> inputTypes;
for (auto& arg : args) {
inputTypes.push_back(fromVeloxType(arg->typeKind()));
}

duckdb::VeloxPoolAllocator duckDBAllocator(*context->pool());
duckdb::VeloxPoolAllocator duckDBAllocator(*context.pool());
auto state = initializeState(move(inputTypes), duckDBAllocator);
assert(state->functionIndex < set_.size());
auto& function = set_[state->functionIndex];
idx_t nrow = rows.size();

if (!*result) {
*result = createVeloxVector(rows, function.return_type, nrow, context);
if (!result) {
result = createVeloxVector(rows, function.return_type, nrow, context);
}
for (auto offset = 0; offset < nrow; offset += STANDARD_VECTOR_SIZE) {
// reset the input chunk by referencing the base chunk
state->input->Reset();
// convert arguments to duck arguments
toDuck(rows, args, offset, *state->castChunk, *state->input);
// run the function
callFunction(function, *state, offset, *result);
callFunction(function, *state, offset, result);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ void SelectiveStringDictionaryColumnReader::getValues(

if (scanSpec_->makeFlat()) {
BaseVector::ensureWritable(
SelectivityVector::empty(), (*result)->type(), &memoryPool_, result);
SelectivityVector::empty(), (*result)->type(), &memoryPool_, *result);
}
}

Expand Down
8 changes: 4 additions & 4 deletions velox/examples/OpaqueType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ class MapResolverVectorFunction : public exec::VectorFunction {
const SelectivityVector& rows,
std::vector<VectorPtr>& args,
const TypePtr& outputType,
exec::EvalCtx* context,
VectorPtr* result) const override {
exec::EvalCtx& context,
VectorPtr& result) const override {
// We cannot make any assumptions about the encoding of the input vectors.
// In order to access their data as FlatVectors, we need to decode them
// first:
Expand All @@ -134,8 +134,8 @@ class MapResolverVectorFunction : public exec::VectorFunction {

// Ensure we have an output vector where we can write the output opaqued
// values.
context->ensureWritable(rows, outputType, *result);
auto* output = (*result)->as<KindToFlatVector<TypeKind::OPAQUE>::type>();
context.ensureWritable(rows, outputType, result);
auto* output = result->as<KindToFlatVector<TypeKind::OPAQUE>::type>();

// `applyToSelected()` will execute the lambda below on each row enabled in
// the input selectivity vector (rows). We don't need to check for null
Expand Down
12 changes: 6 additions & 6 deletions velox/exec/tests/FunctionResolutionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ class VectorFunctionTwoArgs : public exec::VectorFunction {
const SelectivityVector& rows,
std::vector<VectorPtr>& /*args*/,
const TypePtr& /*outputType*/,
exec::EvalCtx* context,
VectorPtr* result) const override {
BaseVector::ensureWritable(rows, BOOLEAN(), context->pool(), result);
auto resultVector = (*result)->asUnchecked<FlatVector<bool>>();
exec::EvalCtx& context,
VectorPtr& result) const override {
BaseVector::ensureWritable(rows, BOOLEAN(), context.pool(), result);
auto resultVector = result->asUnchecked<FlatVector<bool>>();

rows.applyToSelected([&](auto row) { resultVector->set(row, false); });
}
Expand All @@ -64,8 +64,8 @@ class VectorFunctionOneArg : public VectorFunctionTwoArgs {
const SelectivityVector& rows,
std::vector<VectorPtr>& args,
const TypePtr& ptr,
exec::EvalCtx* context,
VectorPtr* result) const override {
exec::EvalCtx& context,
VectorPtr& result) const override {
VELOX_CHECK_EQ(args.size(), 1);
VectorFunctionTwoArgs::apply(rows, args, ptr, context, result);
}
Expand Down
10 changes: 5 additions & 5 deletions velox/experimental/codegen/benchmark/CodegenBenchmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,8 @@ class CodegenBenchmark : public CodegenTestCore {
arguments, // See D27826068
// batch.get()->children(),
nullptr,
&context,
&batchResult);
context,
batchResult);
return batchResult;
}

Expand All @@ -336,8 +336,8 @@ class CodegenBenchmark : public CodegenTestCore {
arguments, // See D27826068
// batch.get()->children(),
nullptr,
&context,
&filterResult);
context,
filterResult);

auto numOut = facebook::velox::exec::processFilterResults(
filterResult->as<RowVector>()->childAt(0),
Expand All @@ -358,7 +358,7 @@ class CodegenBenchmark : public CodegenTestCore {
dynamic_cast<facebook::velox::exec::VectorFunction*>(
info.projectionFunc.get())
->apply(
rows, batch.get()->children(), nullptr, &context, &batchResult);
rows, batch.get()->children(), nullptr, context, batchResult);

if (numOut != batch->size()) {
batchResult = facebook::velox::exec::wrap(
Expand Down
Loading