File indexing completed on 2024-04-06 12:21:25
0001 #ifndef BITONIC_NEW_H
0002 #define BITONIC_NEW_H
0003
0004 #include <algorithm>
0005 #include <cassert>
0006
0007 #include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h"
0008
0009 inline unsigned int PowerOf2LessThan(unsigned int n) {
0010 unsigned int i = 1;
0011 unsigned int prev = 1;
0012 if (n <= 1)
0013 return n;
0014 while (i < n) {
0015 i <<= 1;
0016 if (i < n) {
0017 prev = i;
0018 } else {
0019 return prev;
0020 }
0021 }
0022
0023 assert(false);
0024 }
0025
0026 template <typename T>
0027 void bitonicMerge(T in[], int InSize, T out[], int OutSize, bool dir) {
0028
0029
0030
0031 if (InSize <= 1) {
0032 for (int i = 0; i < std::min(InSize, OutSize); ++i)
0033 out[i] = in[i];
0034 return;
0035 }
0036
0037 if (InSize > 1) {
0038 int LowerSize = PowerOf2LessThan(InSize);
0039 int UpperSize = InSize - LowerSize;
0040
0041 assert(UpperSize >= 0);
0042 assert(UpperSize <= LowerSize);
0043
0044 for (int i = 0; i < UpperSize; ++i) {
0045 if ((in[i] > in[i + LowerSize]) == dir) {
0046
0047 if (i < OutSize)
0048 out[i] = in[i + LowerSize];
0049 if (i + LowerSize < OutSize)
0050 out[i + LowerSize] = in[i];
0051 } else {
0052 if (i < OutSize)
0053 out[i] = in[i];
0054 if (i + LowerSize < OutSize)
0055 out[i + LowerSize] = in[i + LowerSize];
0056 }
0057 }
0058
0059
0060 if (LowerSize > UpperSize) {
0061 for (int i = UpperSize; i < LowerSize; ++i) {
0062 if (i < OutSize)
0063 out[i] = in[i];
0064 }
0065 }
0066
0067 T out2[LowerSize];
0068 bitonicMerge(out, LowerSize, out2, LowerSize, dir);
0069
0070 T out3[UpperSize];
0071 bitonicMerge(out + LowerSize, UpperSize, out3, UpperSize, dir);
0072
0073
0074 if (dir)
0075 {
0076 for (int i = 0; i < OutSize; ++i) {
0077 if (i < UpperSize)
0078 out[OutSize - i - 1] = out3[UpperSize - i - 1];
0079 else
0080 out[OutSize - i - 1] = out2[LowerSize - i - 1 + UpperSize];
0081 }
0082
0083 } else {
0084 for (int i = 0; i < LowerSize; ++i) {
0085 if (i < OutSize)
0086 out[i] = out2[i];
0087 }
0088 for (int i = LowerSize; i < OutSize; ++i)
0089 out[i] = out3[i - LowerSize];
0090 }
0091
0092 }
0093
0094 }
0095
0096 template <typename T>
0097 void bitonicSort(const T in[], int Start, int InSize, T out[], int OutSize, bool dir) {
0098 assert(OutSize > 0);
0099 if (InSize <= 1)
0100 {
0101 for (int i = 0; i < std::min(InSize, OutSize); ++i)
0102 out[i] = in[i + Start];
0103 return;
0104 }
0105
0106 int LowerInSize = InSize / 2;
0107 int UpperInSize = InSize - LowerInSize;
0108
0109 int LowerOutSize = std::min(OutSize, LowerInSize);
0110 int UpperOutSize = std::min(OutSize, UpperInSize);
0111
0112
0113 T OutTmp[LowerOutSize + UpperOutSize];
0114
0115
0116 bitonicSort(in,
0117 Start,
0118 LowerInSize,
0119 OutTmp,
0120 LowerOutSize,
0121 not dir);
0122
0123
0124 bitonicSort(in, Start + LowerInSize, UpperInSize, OutTmp + LowerOutSize, UpperOutSize, dir);
0125
0126
0127 int OutSize2 = LowerOutSize + UpperOutSize;
0128 T outTmp2[OutSize2];
0129 bitonicMerge(OutTmp, LowerOutSize + UpperOutSize, outTmp2, OutSize2, dir);
0130
0131 for (int i = 0; i < OutSize; ++i) {
0132 if (dir) {
0133 out[OutSize - 1 - i] = outTmp2[OutSize2 - 1 - i];
0134 } else {
0135 out[i] = outTmp2[i];
0136 }
0137 }
0138 }
0139
0140 template <typename T>
0141 void bitonic_sort_and_crop_ref(unsigned int nIn, unsigned int nOut, const T in[], T out[]) {
0142 bitonicSort(in, 0, nIn, out, nOut, 0);
0143 }
0144 #endif