58 auto& clusterer = processors.tpcClusterer[sector];
59 auto& clustererNN = processors.tpcNNClusterer[sector];
62 if (glo_idx + batchStart >= clusterer.mPmemory->counters.nClusters || glo_idx >= (uint32_t)clustererNN.mNnClusterizerBatchedMode) {
66 uint32_t write_idx = glo_idx * clustererNN.mNnClusterizerElementSize;
70 CfChargePos peak = clusterer.mPfilteredPeakPositions[CAMath::Min(glo_idx + batchStart, (uint32_t)(clusterer.mPmemory->counters.nClusters - 1))];
71 const int32_t
row =
static_cast<int>(peak.row());
72 const int32_t pad =
static_cast<int>(peak.pad());
73 const int32_t
time =
static_cast<int>(peak.time());
74 const float central_charge =
static_cast<float>(chargeMap[peak].unpack());
75 const float inverse_charge = 1.f / central_charge;
77 const int32_t row_offset = GPUTPCNNClusterizerKernels::rowOffset(
row, clustererNN.mNnClusterizerSizeInputRow);
78 const int32_t iroc_row = 63 + clustererNN.mNnClusterizerSizeInputRow;
80 const int32_t npads_row = GPUTPCGeometry::NPads(
row);
81 float output_value = clustererNN.mNnClusterizerBoundaryFillValue;
83 for (int32_t target_row = -clustererNN.mNnClusterizerSizeInputRow +
row; target_row <= clustererNN.mNnClusterizerSizeInputRow +
row; ++target_row) {
85 const int32_t p_local = pad + (is_boundary ? 0 : GPUTPCNNClusterizerKernels::padOffset(
row, target_row));
86 const int32_t npads_reference = is_boundary ? 0 : GPUTPCGeometry::NPads(target_row - row_offset);
88 for (int32_t target_pad = -clustererNN.mNnClusterizerSizeInputPad + p_local; target_pad <= clustererNN.mNnClusterizerSizeInputPad + p_local; ++target_pad) {
89 is_boundary = is_boundary || GPUTPCNNClusterizerKernels::isBoundary(target_row + row_offset, target_pad, maxrow, iroc_row, npads_row, npads_reference);
91 for (int32_t target_time = -clustererNN.mNnClusterizerSizeInputTime +
time; target_time <= clustererNN.mNnClusterizerSizeInputTime +
time; ++target_time) {
92 if (is_boundary || target_time < 0 || target_time >= clustererNN.maxAllowedTimebin) {
94 output_value = clustererNN.mNnClusterizerBoundaryFillValue;
96 clustererNN.mInputData_32[write_idx] = output_value;
98 clustererNN.mInputData_16[write_idx] = (OrtDataType::Float16_t)output_value;
101 CfChargePos tmp_pos(target_row, target_pad, target_time);
102 output_value = chargeMap[tmp_pos].unpack() * inverse_charge;
104 clustererNN.mInputData_32[write_idx] = output_value;
106 clustererNN.mInputData_16[write_idx] = (OrtDataType::Float16_t)output_value;
118 if (clustererNN.mNnClusterizerAddIndexData) {
122 clustererNN.mInputData_32[write_idx + 2] =
static_cast<float>(pad) / npads_row;
126 clustererNN.mInputData_16[write_idx + 2] = (OrtDataType::Float16_t)(
static_cast<float>(pad) / npads_row);
130 if (!clustererNN.mNnClusterizerSetDeconvolutionFlags) {
131 clustererNN.mClusterFlags[2 * glo_idx] = 0;
132 clustererNN.mClusterFlags[2 * glo_idx + 1] = 0;
134 for (uint16_t
i = 0;
i < 8; ++
i) {
135 Delta2 d = cfconsts::InnerNeighbors[
i];
137 clustererNN.mClusterFlags[2 * glo_idx] += CfUtils::isPeak(isPeakMap[tmp_pos]);
139 clustererNN.mClusterFlags[2 * glo_idx + 1] = clustererNN.mClusterFlags[2 * glo_idx];
151 auto& clusterer = processors.tpcClusterer[sector];
152 auto& clustererNN = processors.tpcNNClusterer[sector];
154 if (glo_idx >= (uint32_t)clustererNN.mNnClusterizerBatchedMode * clustererNN.mNnClusterizerRowTimeSizeThreads) {
158 const uint32_t base_idx = glo_idx / clustererNN.mNnClusterizerRowTimeSizeThreads;
159 const uint32_t transient_index = glo_idx - (base_idx * clustererNN.mNnClusterizerRowTimeSizeThreads);
162 if (base_idx + batchStart >= clusterer.mPmemory->counters.nClusters) {
170 CfChargePos peak = clusterer.mPfilteredPeakPositions[CAMath::Min(base_idx + batchStart, (uint32_t)(clusterer.mPmemory->counters.nClusters - 1))];
171 const float central_charge = chargeMap[peak].unpack();
172 const int32_t
row =
static_cast<int>(peak.row());
173 const int32_t pad =
static_cast<int>(peak.pad());
174 const int32_t
time =
static_cast<int>(peak.time());
177 if (clustererNN.mNnClusterizerAddIndexData && transient_index >= clustererNN.mNnClusterizerRowTimeSize) {
178 uint32_t write_idx = base_idx * clustererNN.mNnClusterizerElementSize + clustererNN.mNnClusterizerChargeArraySize;
179 const int32_t npads = GPUTPCGeometry::NPads(
row);
183 clustererNN.mInputData_32[write_idx + 2] =
static_cast<float>(pad) / npads;
187 clustererNN.mInputData_16[write_idx + 2] = (OrtDataType::Float16_t)(
static_cast<float>(pad) / npads);
192 if (transient_index < clustererNN.mNnClusterizerRowTimeSize) {
194 const int32_t row_idx = transient_index / clustererNN.mNnClusterizerFullTimeSize;
195 const int32_t time_idx = transient_index - row_idx * clustererNN.mNnClusterizerFullTimeSize;
196 int32_t write_idx = base_idx * clustererNN.mNnClusterizerElementSize + row_idx * clustererNN.mNnClusterizerPadTimeSize + time_idx;
199 const int32_t target_row =
row + row_idx - clustererNN.mNnClusterizerSizeInputRow;
200 float output_value = clustererNN.mNnClusterizerBoundaryFillValue;
203 for (uint32_t target_pad = 0; target_pad < clustererNN.mNnClusterizerFullPadSize; ++target_pad) {
205 clustererNN.mInputData_32[write_idx] = output_value;
207 clustererNN.mInputData_16[write_idx] = (OrtDataType::Float16_t)output_value;
209 write_idx += clustererNN.mNnClusterizerFullTimeSize;
214 const int32_t target_time =
time + time_idx - clustererNN.mNnClusterizerSizeInputTime;
215 const uint8_t is_time_boundary = (target_time < 0) || (target_time >= clustererNN.maxAllowedTimebin);
216 const float inverse_central_charge = 1.f / central_charge;
217 const int32_t p_local = pad + GPUTPCNNClusterizerKernels::padOffset(
row, target_row);
218 const int32_t npads = GPUTPCGeometry::NPads(target_row);
220 const int32_t start_pad = -clustererNN.mNnClusterizerSizeInputPad + p_local;
221 const int32_t end_pad = clustererNN.mNnClusterizerSizeInputPad + p_local;
223 for (int32_t target_pad = start_pad; target_pad <= end_pad; ++target_pad) {
224 if (target_pad >= npads || target_pad < 0 || is_time_boundary) {
225 output_value = clustererNN.mNnClusterizerBoundaryFillValue;
229 output_value = chargeMap[
pos].unpack() * inverse_central_charge;
232 clustererNN.mInputData_32[write_idx] = output_value;
234 clustererNN.mInputData_16[write_idx] = (OrtDataType::Float16_t)output_value;
236 write_idx += clustererNN.mNnClusterizerFullTimeSize;
267 auto& clusterer = processors.tpcClusterer[sector];
268 auto& clustererNN = processors.tpcNNClusterer[sector];
269 if (glo_idx + batchStart >= clusterer.mPmemory->counters.nClusters || glo_idx >= (uint32_t)clustererNN.mNnClusterizerBatchedMode) {
272 if (clustererNN.mNnClusterizerUseClassification) {
273 uint32_t elem_iterator = glo_idx * clustererNN.mNnClusterizerModelClassNumOutputNodes;
274 float current_max_prob = 0.f;
275 uint32_t class_label = 0;
276 for (uint32_t pIdx = elem_iterator; pIdx < elem_iterator + clustererNN.mNnClusterizerModelClassNumOutputNodes; pIdx++) {
277 if (pIdx == elem_iterator) {
279 current_max_prob = clustererNN.mModelProbabilities_32[pIdx];
281 current_max_prob =
static_cast<float>(clustererNN.mModelProbabilities_16[pIdx]);
285 current_max_prob = CAMath::Max(current_max_prob, clustererNN.mModelProbabilities_32[pIdx]);
287 current_max_prob = CAMath::Max(current_max_prob, clustererNN.mModelProbabilities_16[pIdx].ToFloat());
292 clustererNN.mOutputDataClass[glo_idx + batchStart] = class_label;
293 if (class_label > 1) {
294 clustererNN.mClusterFlags[2 * glo_idx] = 1;
295 clustererNN.mClusterFlags[2 * glo_idx + 1] = 1;
298 clustererNN.mOutputDataClass[glo_idx + batchStart] = 1;
306 auto& clusterer = processors.tpcClusterer[sector];
307 auto& clustererNN = processors.tpcNNClusterer[sector];
308 if (glo_idx >= (uint32_t)clustererNN.mNnClusterizerBatchedMode) {
312 uint32_t maxClusterNum = clusterer.mPmemory->counters.nClusters;
313 uint32_t full_glo_idx = glo_idx + batchStart;
314 int32_t model_output_index = glo_idx * clustererNN.mNnClusterizerModelReg1NumOutputNodes;
317 uint32_t peakIndex = CAMath::Min(full_glo_idx, maxClusterNum - 1);
318 CfChargePos peak = clusterer.mPfilteredPeakPositions[peakIndex];
319 float central_charge =
static_cast<float>(chargeMap[peak].unpack());
324 if (full_glo_idx >= maxClusterNum) {
328 GPUTPCCFClusterizer::buildCluster(
329 clusterer.Param().rec,
334 smem.innerAboveThreshold,
348 GPUTPCCFClusterizer::buildCluster(
349 clusterer.Param().rec,
354 smem.innerAboveThreshold,
358 if ((clusterer.mPmemory->fragment).isOverlap(peak.time())) {
359 if (clusterer.mPclusterPosInRow) {
360 clusterer.mPclusterPosInRow[full_glo_idx] = clusterer.mNMaxClusterPerRow;
365 bool notSinglePad =
false, notSingleTime =
false;
366 for (uint16_t
i = 0;
i < 8;
i++) {
367 Delta2 d = cfconsts::InnerNeighbors[
i];
369 float v =
static_cast<float>(chargeMap[tmp_pos].unpack());
370 notSinglePad |= (d.
x != 0) && (
v > 0.f);
371 notSingleTime |= (d.
y != 0) && (
v > 0.f);
374 float publishPadPosition = 0.f, publishTimePosition = 0.f;
376 publishPadPosition =
static_cast<float>(peak.pad()) + clustererNN.mOutputDataReg1_32[model_output_index];
377 publishTimePosition =
static_cast<float>(peak.time()) + clustererNN.mOutputDataReg1_32[model_output_index + 1];
378 isBoundaryPublish(full_glo_idx,
static_cast<int32_t
>(peak.row()), publishPadPosition, publishTimePosition);
379 pc.setFull(central_charge * clustererNN.mOutputDataReg1_32[model_output_index + 4],
381 notSinglePad ? clustererNN.mOutputDataReg1_32[model_output_index + 2] : 0.f,
382 (clusterer.mPmemory->fragment).
start + publishTimePosition,
383 notSingleTime ? clustererNN.mOutputDataReg1_32[model_output_index + 3] : 0.f,
384 clustererNN.mClusterFlags[2 * glo_idx],
385 clustererNN.mClusterFlags[2 * glo_idx + 1]);
387 publishPadPosition =
static_cast<float>(peak.pad()) + clustererNN.mOutputDataReg1_16[model_output_index].ToFloat();
388 publishTimePosition =
static_cast<float>(peak.time()) + clustererNN.mOutputDataReg1_16[model_output_index + 1].ToFloat();
389 isBoundaryPublish(full_glo_idx,
static_cast<int32_t
>(peak.row()), publishPadPosition, publishTimePosition);
390 pc.setFull(central_charge * clustererNN.mOutputDataReg1_16[model_output_index + 4].ToFloat(),
392 notSinglePad ? clustererNN.mOutputDataReg1_16[model_output_index + 2].ToFloat() : 0.f,
393 (clusterer.mPmemory->fragment).
start + publishTimePosition,
394 notSingleTime ? clustererNN.mOutputDataReg1_16[model_output_index + 3].ToFloat() : 0.f,
395 clustererNN.mClusterFlags[2 * glo_idx],
396 clustererNN.mClusterFlags[2 * glo_idx + 1]);
469 bool rejectCluster = !pc.toNative(peak, central_charge, myCluster, clusterer.Param(), chargeMap);
470 if (clustererNN.mNnClusterizerUseClassification) {
471 rejectCluster |= (clustererNN.mOutputDataClass[peakIndex] <= 0);
474 if (clusterer.mPclusterPosInRow) {
475 clusterer.mPclusterPosInRow[full_glo_idx] = clusterer.mNMaxClusterPerRow;
480 uint32_t rowIndex = 0;
481 if (clusterOut !=
nullptr) {
482 rowIndex = GPUTPCCFClusterizer::sortIntoBuckets(
486 clusterer.mNMaxClusterPerRow,
487 clusterer.mPclusterInRow,
489 if (clusterer.mPclusterPosInRow !=
nullptr) {
490 clusterer.mPclusterPosInRow[full_glo_idx] = rowIndex;
492 }
else if (clusterer.mPclusterPosInRow) {
493 rowIndex = clusterer.mPclusterPosInRow[full_glo_idx];
495 CPU_ONLY(labelAcc->
commit(peak.row(), rowIndex, clusterer.mNMaxClusterPerRow));
502 auto& clusterer = processors.tpcClusterer[sector];
503 auto& clustererNN = processors.tpcNNClusterer[sector];
504 if (glo_idx >= (uint32_t)clustererNN.mNnClusterizerBatchedMode) {
508 uint32_t maxClusterNum = clusterer.mPmemory->counters.nClusters;
510 CfChargePos peak = clusterer.mPfilteredPeakPositions[CAMath::Min(glo_idx + batchStart, (uint32_t)(clusterer.mPmemory->counters.nClusters - 1))];
511 float central_charge =
static_cast<float>(chargeMap[peak].unpack());
516 uint32_t full_glo_idx = glo_idx + batchStart;
518 if (full_glo_idx >= maxClusterNum) {
522 GPUTPCCFClusterizer::buildCluster(
523 clusterer.Param().rec,
528 smem.innerAboveThreshold,
535 uint32_t model_output_index = glo_idx * clustererNN.mNnClusterizerModelReg2NumOutputNodes;
542 GPUTPCCFClusterizer::buildCluster(
543 clusterer.Param().rec,
548 smem.innerAboveThreshold,
552 if ((clusterer.mPmemory->fragment).isOverlap(peak.time())) {
553 if (clusterer.mPclusterPosInRow) {
554 clusterer.mPclusterPosInRow[full_glo_idx] = clusterer.mNMaxClusterPerRow;
560 float publishPadPosition = 0.f, publishTimePosition = 0.f;
562 publishPadPosition =
static_cast<float>(peak.pad()) + clustererNN.mOutputDataReg2_32[model_output_index];
563 publishTimePosition =
static_cast<float>(peak.time()) + clustererNN.mOutputDataReg2_32[model_output_index + 1];
564 isBoundaryPublish(full_glo_idx,
static_cast<int32_t
>(peak.row()), publishPadPosition, publishTimePosition);
565 pc.setFull(central_charge * clustererNN.mOutputDataReg2_32[model_output_index + 8],
567 clustererNN.mOutputDataReg2_32[model_output_index + 4],
568 (clusterer.mPmemory->fragment).start + publishTimePosition,
569 clustererNN.mOutputDataReg2_32[model_output_index + 6],
570 clustererNN.mClusterFlags[2 * glo_idx],
571 clustererNN.mClusterFlags[2 * glo_idx + 1]);
573 publishPadPosition =
static_cast<float>(peak.pad()) + clustererNN.mOutputDataReg2_16[model_output_index].ToFloat();
574 publishTimePosition =
static_cast<float>(peak.time()) + clustererNN.mOutputDataReg2_16[model_output_index + 1].ToFloat();
575 isBoundaryPublish(full_glo_idx,
static_cast<int32_t
>(peak.row()), publishPadPosition, publishTimePosition);
576 pc.setFull(central_charge * clustererNN.mOutputDataReg2_16[model_output_index + 8].ToFloat(),
578 clustererNN.mOutputDataReg2_16[model_output_index + 4].ToFloat(),
579 (clusterer.mPmemory->fragment).start + publishTimePosition,
580 clustererNN.mOutputDataReg2_16[model_output_index + 6].ToFloat(),
581 clustererNN.mClusterFlags[2 * glo_idx],
582 clustererNN.mClusterFlags[2 * glo_idx + 1]);
586 bool rejectCluster = !pc.toNative(peak, central_charge, myCluster, clusterer.Param(), chargeMap);
587 if (clustererNN.mNnClusterizerUseClassification) {
588 rejectCluster |= (clustererNN.mOutputDataClass[CAMath::Min(full_glo_idx, (uint32_t)clusterer.mPmemory->counters.nClusters - 1)] <= 0);
591 if (clusterer.mPclusterPosInRow) {
592 clusterer.mPclusterPosInRow[full_glo_idx] = clusterer.mNMaxClusterPerRow;
597 uint32_t rowIndex = 0;
598 if (clusterOut !=
nullptr) {
599 rowIndex = GPUTPCCFClusterizer::sortIntoBuckets(
603 clusterer.mNMaxClusterPerRow,
604 clusterer.mPclusterInRow,
606 if (clusterer.mPclusterPosInRow !=
nullptr) {
607 clusterer.mPclusterPosInRow[full_glo_idx] = rowIndex;
609 }
else if (clusterer.mPclusterPosInRow) {
610 rowIndex = clusterer.mPclusterPosInRow[full_glo_idx];
612 CPU_ONLY(labelAcc->
commit(peak.row(), rowIndex, clusterer.mNMaxClusterPerRow));
616 publishPadPosition =
static_cast<float>(peak.pad()) + clustererNN.mOutputDataReg2_32[model_output_index + 1];
617 publishTimePosition =
static_cast<float>(peak.time()) + clustererNN.mOutputDataReg2_32[model_output_index + 3];
618 isBoundaryPublish(full_glo_idx,
static_cast<int32_t
>(peak.row()), publishPadPosition, publishTimePosition);
619 pc.setFull(central_charge * clustererNN.mOutputDataReg2_32[model_output_index + 9],
621 clustererNN.mOutputDataReg2_32[model_output_index + 5],
622 (clusterer.mPmemory->fragment).start + publishTimePosition,
623 clustererNN.mOutputDataReg2_32[model_output_index + 7],
624 clustererNN.mClusterFlags[2 * glo_idx],
625 clustererNN.mClusterFlags[2 * glo_idx + 1]);
627 publishPadPosition =
static_cast<float>(peak.pad()) + clustererNN.mOutputDataReg2_16[model_output_index + 1].ToFloat();
628 publishTimePosition =
static_cast<float>(peak.time()) + clustererNN.mOutputDataReg2_16[model_output_index + 3].ToFloat();
629 isBoundaryPublish(full_glo_idx,
static_cast<int32_t
>(peak.row()), publishPadPosition, publishTimePosition);
630 pc.setFull(central_charge * clustererNN.mOutputDataReg2_16[model_output_index + 9].ToFloat(),
632 clustererNN.mOutputDataReg2_16[model_output_index + 5].ToFloat(),
633 (clusterer.mPmemory->fragment).start + publishTimePosition,
634 clustererNN.mOutputDataReg2_16[model_output_index + 7].ToFloat(),
635 clustererNN.mClusterFlags[2 * glo_idx],
636 clustererNN.mClusterFlags[2 * glo_idx + 1]);
639 rejectCluster = !pc.toNative(peak, central_charge, myCluster, clusterer.Param(), chargeMap);
640 if (clustererNN.mNnClusterizerUseClassification) {
641 rejectCluster |= (clustererNN.mOutputDataClass[CAMath::Min(full_glo_idx, (uint32_t)clusterer.mPmemory->counters.nClusters - 1)] <= 0);
644 if (clusterer.mPclusterPosInRow) {
645 clusterer.mPclusterPosInRow[full_glo_idx] = clusterer.mNMaxClusterPerRow;
650 if (clusterOut !=
nullptr) {
651 rowIndex = GPUTPCCFClusterizer::sortIntoBuckets(
655 clusterer.mNMaxClusterPerRow,
656 clusterer.mPclusterInRow,
658 if (clusterer.mPclusterPosInRow !=
nullptr) {
659 clusterer.mPclusterPosInRow[full_glo_idx] = rowIndex;
661 }
else if (clusterer.mPclusterPosInRow) {
662 rowIndex = clusterer.mPclusterPosInRow[full_glo_idx];