| 135 | |
| 136 | |
| 137 | TVector<TVector<double>> ApplyModelMulti( |
| 138 | const TFullModel& model, |
| 139 | const TObjectsDataProvider& objectsData, |
| 140 | const EPredictionType predictionType, |
| 141 | int begin, /*= 0*/ |
| 142 | int end, /*= 0*/ |
| 143 | ILocalExecutor* executor, |
| 144 | const NCB::TMaybeData<TConstArrayRef<TConstArrayRef<float>>>& baseline) |
| 145 | { |
| 146 | if (baseline) { |
| 147 | // TODO: only one dimension of baseline is checked, what about others? |
| 148 | CB_ENSURE( |
| 149 | baseline->size() == model.GetDimensionsCount(), |
| 150 | "Baseline should have the same dimension count as model: expected " << model.GetDimensionsCount() |
| 151 | << " got " << baseline->size() |
| 152 | ); |
| 153 | } |
| 154 | |
| 155 | const int docCount = SafeIntegerCast<int>(objectsData.GetObjectCount()); |
| 156 | const int approxesDimension = model.GetDimensionsCount(); |
| 157 | TVector<double> approxesFlat(docCount * approxesDimension); |
| 158 | if (docCount > 0) { |
| 159 | FixupTreeEnd(model.GetTreeCount(), begin, &end); |
| 160 | PrepareObjectsDataProviderForEvaluation(objectsData); |
| 161 | |
| 162 | const int executorThreadCount = executor ? executor->GetThreadCount() : 0; |
| 163 | auto blockParams = GetBlockParams(executorThreadCount, docCount, end - begin); |
| 164 | |
| 165 | TApplyVisitor visitor(model, begin, end, 0, approxesFlat); |
| 166 | |
| 167 | const ui32 subBlockSize = ui32(NModelEvaluation::FORMULA_EVALUATION_BLOCK_SIZE * 64); |
| 168 | |
| 169 | const auto applyOnBlock = [&](int blockId) { |
| 170 | const int blockFirstIdx = blockParams.FirstId + blockId * blockParams.GetBlockSize(); |
| 171 | const int blockLastIdx = Min(blockParams.LastId, blockFirstIdx + blockParams.GetBlockSize()); |
| 172 | |
| 173 | BlockedEvaluation(model, objectsData, (ui32)blockFirstIdx, (ui32)blockLastIdx, subBlockSize, &visitor); |
| 174 | }; |
| 175 | if (executor) { |
| 176 | executor->ExecRangeWithThrow(applyOnBlock, 0, blockParams.GetBlockCount(), ILocalExecutor::WAIT_COMPLETE); |
| 177 | } else { |
| 178 | applyOnBlock(0); |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | TVector<TVector<double>> approxes(approxesDimension); |
| 183 | if (approxesDimension == 1) { //shortcut |
| 184 | approxes[0].swap(approxesFlat); |
| 185 | } else { |
| 186 | for (int dim = 0; dim < approxesDimension; ++dim) { |
| 187 | approxes[dim].yresize(docCount); |
| 188 | for (int doc = 0; doc < docCount; ++doc) { |
| 189 | approxes[dim][doc] = approxesFlat[approxesDimension * doc + dim]; |
| 190 | }; |
| 191 | } |
| 192 | } |
| 193 | if (baseline) { |
| 194 | for (int i = 0; i < approxesDimension; ++i) { |
no test coverage detected