in velox/experimental/codegen/benchmark/CodegenBenchmark.h [245:396]
auto createBenchmarkLambda(
const std::string& benchmarkName,
const std::string& filterExpr,
const std::vector<std::string>& projectionExprs,
const std::shared_ptr<const RowType>& inputRowType,
size_t batchCount,
size_t rowPerBatch,
const TransformFlags& flags,
bool perRowNumber) {
auto benchmarkIndex = prepareBenchmarkInfo<SQLType...>(
benchmarkName,
filterExpr,
projectionExprs,
inputRowType,
batchCount,
rowPerBatch,
flags);
auto numberIteration = perRowNumber ? rowPerBatch * batchCount : 1;
// reference run
auto referenceLambda = [ this, benchmarkIndex, numberIteration ]() -> auto {
BenchmarkInfo& info = this->benchmarkInfos[benchmarkIndex];
info.referenceResults.clear();
info.clearStringEncoding();
info.referenceResults = runQuery(
info.refPlanNodes,
this->benchmarkInfos[benchmarkIndex].referenceTaskCursors);
return numberIteration;
};
// codegen'd run
auto compiledLambda = [ this, benchmarkIndex, numberIteration ]() -> auto {
BenchmarkInfo& info = this->benchmarkInfos[benchmarkIndex];
info.compiledResults.clear();
info.compiledResults =
runQuery(info.compiledPlanNodes, info.compiledTaskCursors);
return numberIteration;
};
// running thee naked ICompiledCall class
auto generatedFunctionLambda =
[ this, benchmarkIndex, numberIteration, inputRowType ]() -> auto {
// We are including in the benchmark both the allocation of results
// and the selectivity vector building and setting. It's not clear
// that this is the right thing to do. Maybe we should move row to
// BenchmarkInfo
BenchmarkInfo& info = this->benchmarkInfos[benchmarkIndex];
info.clearStringEncoding();
SelectivityVector rows(info.inputVector[0]->size(), true);
info.generatedFunctionResults.clear();
auto evalBatch =
[this, &rows, &info, inputRowType](RowVectorPtr& batch) -> VectorPtr {
// Put the arguments in the correct expected order
std::vector<VectorPtr> arguments;
arguments.resize(info.argNameToIndex.size());
for (auto i = 0; i < inputRowType->size(); i++) {
if (!info.argNameToIndex.count(inputRowType->nameOf(i))) {
continue;
}
arguments[info.argNameToIndex[inputRowType->nameOf(i)]] =
batch.get()->children()[i];
};
auto context = exec::EvalCtx(execCtx_.get(), nullptr, batch.get());
VectorPtr batchResult;
if (info.filterFunc == nullptr) {
// no filter
dynamic_cast<facebook::velox::exec::VectorFunction*>(
info.projectionFunc.get())
->apply(
rows,
arguments, // See D27826068
// batch.get()->children(),
nullptr,
&context,
&batchResult);
return batchResult;
}
// has separately compiled filter
rows.setAll();
VectorPtr filterResult;
FilterEvalCtx filterContext;
dynamic_cast<facebook::velox::exec::VectorFunction*>(
info.filterFunc.get())
->apply(
rows,
arguments, // See D27826068
// batch.get()->children(),
nullptr,
&context,
&filterResult);
auto numOut = facebook::velox::exec::processFilterResults(
filterResult->as<RowVector>()->childAt(0),
rows,
filterContext,
context.pool());
if (numOut == 0) {
// nothing passed filter, no need to evaluate projection
return nullptr;
}
if (numOut != batch->size()) {
rows.setFromBits(
filterContext.selectedBits->as<uint64_t>(), batch->size());
}
dynamic_cast<facebook::velox::exec::VectorFunction*>(
info.projectionFunc.get())
->apply(
rows, batch.get()->children(), nullptr, &context, &batchResult);
if (numOut != batch->size()) {
batchResult = facebook::velox::exec::wrap(
numOut,
filterContext.selectedIndices,
std::dynamic_pointer_cast<RowVector>(batchResult));
}
return batchResult;
};
for (auto& batch : info.inputVector) {
auto batchResult = evalBatch(batch);
if (batchResult != nullptr && batchResult->size() > 0) {
info.generatedFunctionResults.push_back(
std::dynamic_pointer_cast<RowVector>(batchResult));
}
};
return numberIteration;
};
// Compiled time run
auto compileTimeLambda =
[ this, benchmarkIndex, numberIteration ]() -> auto {
auto& info = benchmarkInfos[benchmarkIndex];
codegenTransformation_->transform(*info.refPlanNodes);
return numberIteration;
};
return std::make_tuple(
std::move(referenceLambda),
std::move(compiledLambda),
std::move(generatedFunctionLambda),
std::move(compileTimeLambda));
}