auto createBenchmarkLambda()

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));
  }