| 2 | |
| 3 | namespace NCatboostCuda { |
| 4 | void TTreeCtrDataSet::BuildFeatureIndex() { |
| 5 | CB_ENSURE(InverseCtrIndex.size() == 0, "Error: build could be done only once"); |
| 6 | |
| 7 | for (const ui32 feature : CatFeatures) { |
| 8 | TFeatureTensor tensor = BaseFeatureTensor; |
| 9 | tensor.AddCatFeature(feature); |
| 10 | const auto& configs = GetCtrsConfigsForTensor(tensor); |
| 11 | for (auto& config : configs) { |
| 12 | TCtr ctr; |
| 13 | ctr.FeatureTensor = tensor; |
| 14 | ctr.Configuration = config; |
| 15 | const ui32 idx = static_cast<const ui32>(InverseCtrIndex.size()); |
| 16 | InverseCtrIndex[ctr] = idx; |
| 17 | Ctrs.push_back(ctr); |
| 18 | const auto borderCount = FeaturesManager.GetCtrBinarization(ctr).BorderCount; |
| 19 | MaxBorderCount = Max<ui32>(MaxBorderCount, borderCount); |
| 20 | const ui32 bordersSize = 1 + borderCount; |
| 21 | const ui32 offset = static_cast<const ui32>(CtrBorderSlices.size() ? CtrBorderSlices.back().Right |
| 22 | : 0); |
| 23 | const TSlice bordersSlice = TSlice(offset, offset + bordersSize); |
| 24 | CtrBorderSlices.push_back(bordersSlice); |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | TFeaturesMapping featuresMapping = CreateFeaturesMapping(); |
| 29 | |
| 30 | auto bordersMapping = featuresMapping.Transform([&](TSlice deviceSlice) { |
| 31 | ui32 size = 0; |
| 32 | for (ui32 feature = static_cast<ui32>(deviceSlice.Left); feature < deviceSlice.Right; ++feature) { |
| 33 | size += CtrBorderSlices[feature].Size(); |
| 34 | } |
| 35 | return size; |
| 36 | }); |
| 37 | CtrBorders.Reset(bordersMapping); |
| 38 | |
| 39 | if (CtrBorderSlices.size()) { |
| 40 | //borders are so small, that it should be almost always faster to write all border vec then by parts |
| 41 | TVector<float> borders(CtrBorderSlices.back().Right); |
| 42 | bool needWrite = false; |
| 43 | |
| 44 | for (ui32 i = 0; i < Ctrs.size(); ++i) { |
| 45 | const auto& ctr = Ctrs[i]; |
| 46 | AreCtrBordersComputed.push_back(false); |
| 47 | if (FeaturesManager.IsKnown(ctr)) { |
| 48 | const auto& ctrBorders = FeaturesManager.GetBorders(FeaturesManager.GetId(ctr)); |
| 49 | const ui64 offset = CtrBorderSlices[i].Left; |
| 50 | borders[offset] = ctrBorders.size(); |
| 51 | std::copy(ctrBorders.begin(), ctrBorders.end(), borders.begin() + offset + 1); |
| 52 | CB_ENSURE(ctrBorders.size() < CtrBorderSlices[i].Size()); |
| 53 | AreCtrBordersComputed.back() = true; |
| 54 | needWrite = true; |
| 55 | } |
| 56 | } |
| 57 | if (needWrite) { |
| 58 | CtrBorders.Write(borders); |
| 59 | } |
| 60 | } |
| 61 | } |
no test coverage detected