| 333 | template <typename TFloatFeatureAccessor, typename TCatFeatureAccessor, |
| 334 | typename TTextFeatureAccessor, typename TEmbeddingFeatureAccessor> |
| 335 | inline void BinarizeFeatures( |
| 336 | const TModelTrees& trees, |
| 337 | const TModelTrees::TForApplyData& applyData, |
| 338 | const TIntrusivePtr<ICtrProvider>& ctrProvider, |
| 339 | const TIntrusivePtr<TTextProcessingCollection>& textProcessingCollection, |
| 340 | const TIntrusivePtr<TEmbeddingProcessingCollection>& embeddingProcessingCollection, |
| 341 | TFloatFeatureAccessor floatAccessor, |
| 342 | TCatFeatureAccessor catFeatureAccessor, |
| 343 | TTextFeatureAccessor textFeatureAccessor, |
| 344 | TEmbeddingFeatureAccessor embeddingFeatureAccessor, |
| 345 | size_t start, |
| 346 | size_t end, |
| 347 | TCPUEvaluatorQuantizedData* cpuEvaluatorQuantizedData, |
| 348 | TArrayRef<ui32> transposedHash, |
| 349 | TArrayRef<float> ctrs, |
| 350 | TArrayRef<float> estimatedFeatures, |
| 351 | const TFeatureLayout* featureInfo = nullptr |
| 352 | ) { |
| 353 | const auto fullDocCount = end - start; |
| 354 | auto result = *(cpuEvaluatorQuantizedData->QuantizedData); |
| 355 | auto expectedQuantizedFeaturesLen = trees.GetEffectiveBinaryFeaturesBucketsCount() * fullDocCount; |
| 356 | CB_ENSURE(result.size() >= expectedQuantizedFeaturesLen, "Not enough space to store quantized features"); |
| 357 | cpuEvaluatorQuantizedData->BlocksCount = 0; |
| 358 | cpuEvaluatorQuantizedData->BlockStride = |
| 359 | trees.GetEffectiveBinaryFeaturesBucketsCount() * FORMULA_EVALUATION_BLOCK_SIZE; |
| 360 | cpuEvaluatorQuantizedData->ObjectsCount = fullDocCount; |
| 361 | ui8* resultPtr = result.data(); |
| 362 | std::fill(result.begin(), result.begin() + expectedQuantizedFeaturesLen, 0); |
| 363 | for (; start < end; start += FORMULA_EVALUATION_BLOCK_SIZE) { |
| 364 | ui8* resultPtrForBlockStart = resultPtr; |
| 365 | ++cpuEvaluatorQuantizedData->BlocksCount; |
| 366 | auto docCount = Min(end - start, FORMULA_EVALUATION_BLOCK_SIZE); |
| 367 | for (const auto& floatFeature : trees.GetFloatFeatures()) { |
| 368 | if (!floatFeature.UsedInModel()) { |
| 369 | continue; |
| 370 | } |
| 371 | TFeaturePosition position = floatFeature.Position; |
| 372 | if (featureInfo) { |
| 373 | position = featureInfo->GetRemappedPosition(floatFeature); |
| 374 | } |
| 375 | if (!floatFeature.HasNans || |
| 376 | floatFeature.NanValueTreatment == TFloatFeature::ENanValueTreatment::AsIs) { |
| 377 | BinarizeFloats<false>( |
| 378 | position, |
| 379 | docCount, |
| 380 | floatAccessor, |
| 381 | floatFeature.Borders, |
| 382 | start, |
| 383 | resultPtr |
| 384 | ); |
| 385 | } else { |
| 386 | const float infinity = std::numeric_limits<float>::infinity(); |
| 387 | if (floatFeature.NanValueTreatment == TFloatFeature::ENanValueTreatment::AsFalse) { |
| 388 | BinarizeFloats<true>( |
| 389 | position, |
| 390 | docCount, |
| 391 | floatAccessor, |
| 392 | floatFeature.Borders, |
no test coverage detected