File indexing completed on 2024-04-06 12:15:46
0001 #include <algorithm>
0002 #include <cassert>
0003 #include <iostream>
0004 #include <limits>
0005 #include <random>
0006
0007 #include "HeterogeneousCore/CUDAUtilities/interface/HistoContainer.h"
0008 #include "HeterogeneousCore/CUDAUtilities/interface/requireDevices.h"
0009
0010 using namespace cms::cuda;
0011
0012 template <typename T, int NBINS = 128, int S = 8 * sizeof(T), int DELTA = 1000>
0013 void go() {
0014 std::mt19937 eng;
0015
0016 int rmin = std::numeric_limits<T>::min();
0017 int rmax = std::numeric_limits<T>::max();
0018 if (NBINS != 128) {
0019 rmin = 0;
0020 rmax = NBINS * 2 - 1;
0021 }
0022
0023 std::uniform_int_distribution<T> rgen(rmin, rmax);
0024
0025 constexpr int N = 12000;
0026 T v[N];
0027
0028 using HistR = HistoContainer<T, NBINS, -1, S>;
0029 using Hist = HistoContainer<T, NBINS, N, S>;
0030 using Hist4 = HistoContainer<T, NBINS, N, S, uint16_t, 4>;
0031 std::cout << "HistoContainerR " << HistR::nbits() << ' ' << HistR::nbins() << ' ' << HistR::totbins() << ' '
0032 << HistR::ctNOnes() << ' ' << HistR::ctCapacity() << ' ' << (rmax - rmin) / HistR::nbins() << std::endl;
0033 std::cout << "bins " << int(Hist::bin(0)) << ' ' << int(Hist::bin(rmin)) << ' ' << int(Hist::bin(rmax)) << std::endl;
0034
0035 std::cout << "HistoContainer " << Hist::nbits() << ' ' << Hist::nbins() << ' ' << Hist::totbins() << ' '
0036 << Hist::ctCapacity() << ' ' << (rmax - rmin) / Hist::nbins() << std::endl;
0037 std::cout << "bins " << int(Hist::bin(0)) << ' ' << int(Hist::bin(rmin)) << ' ' << int(Hist::bin(rmax)) << std::endl;
0038 std::cout << "HistoContainer4 " << Hist4::nbits() << ' ' << Hist4::nbins() << ' ' << Hist4::totbins() << ' '
0039 << Hist4::ctCapacity() << ' ' << (rmax - rmin) / Hist::nbins() << std::endl;
0040 for (auto nh = 0; nh < 4; ++nh)
0041 std::cout << "bins " << int(Hist4::bin(0)) + Hist4::histOff(nh) << ' ' << int(Hist::bin(rmin)) + Hist4::histOff(nh)
0042 << ' ' << int(Hist::bin(rmax)) + Hist4::histOff(nh) << std::endl;
0043
0044 uint32_t mem[N];
0045 HistR hr;
0046 typename HistR::View view{&hr, nullptr, mem, -1, N};
0047 hr.initStorage(view);
0048 std::cout << "HistoContainerR " << hr.capacity() << std::endl;
0049 assert(hr.capacity() == N);
0050 Hist h;
0051 Hist4 h4;
0052 assert(h.capacity() == N);
0053 assert(h4.capacity() == N);
0054
0055 for (int it = 0; it < 5; ++it) {
0056 for (long long j = 0; j < N; j++)
0057 v[j] = rgen(eng);
0058 if (it == 2)
0059 for (long long j = N / 2; j < N / 2 + N / 4; j++)
0060 v[j] = 4;
0061 hr.zero();
0062 h.zero();
0063 h4.zero();
0064 assert(hr.size() == 0);
0065 assert(h.size() == 0);
0066 assert(h4.size() == 0);
0067 for (long long j = 0; j < N; j++) {
0068 hr.count(v[j]);
0069 h.count(v[j]);
0070 if (j < 2000)
0071 h4.count(v[j], 2);
0072 else
0073 h4.count(v[j], j % 4);
0074 }
0075 assert(hr.size() == 0);
0076 assert(h.size() == 0);
0077 assert(h4.size() == 0);
0078 hr.finalize();
0079 h.finalize();
0080 h4.finalize();
0081 assert(h.size() == N);
0082 assert(h4.size() == N);
0083 for (long long j = 0; j < N; j++) {
0084 hr.fill(v[j], j);
0085 h.fill(v[j], j);
0086 if (j < 2000)
0087 h4.fill(v[j], j, 2);
0088 else
0089 h4.fill(v[j], j, j % 4);
0090 }
0091 assert(hr.off[0] == 0);
0092 assert(h.off[0] == 0);
0093 assert(h4.off[0] == 0);
0094 assert(hr.size() == N);
0095 assert(h.size() == N);
0096 assert(h4.size() == N);
0097
0098 auto verify = [&](uint32_t i, uint32_t j, uint32_t k, uint32_t t1, uint32_t t2) {
0099 assert((int32_t)t1 < N);
0100 assert((int32_t)t2 < N);
0101 if (i != j && T(v[t1] - v[t2]) <= 0)
0102 std::cout << "for " << i << ':' << v[k] << " failed " << v[t1] << ' ' << v[t2] << std::endl;
0103 };
0104
0105 for (uint32_t i = 0; i < Hist::nbins(); ++i) {
0106 assert(h.size(i) == hr.size(i));
0107 assert(*h.begin(i) == *hr.begin(i));
0108 }
0109
0110 for (uint32_t i = 0; i < Hist::nbins(); ++i) {
0111 if (0 == h.size(i))
0112 continue;
0113 auto k = *h.begin(i);
0114 assert(k < N);
0115 auto kl = NBINS != 128 ? h.bin(std::max(rmin, v[k] - DELTA)) : h.bin(v[k] - T(DELTA));
0116 auto kh = NBINS != 128 ? h.bin(std::min(rmax, v[k] + DELTA)) : h.bin(v[k] + T(DELTA));
0117 if (NBINS == 128) {
0118 assert(kl != i);
0119 assert(kh != i);
0120 }
0121 if (NBINS != 128) {
0122 assert(kl <= i);
0123 assert(kh >= i);
0124 }
0125
0126 for (auto j = h.begin(kl); j < h.end(kl); ++j)
0127 verify(i, kl, k, k, (*j));
0128 for (auto j = h.begin(kh); j < h.end(kh); ++j)
0129 verify(i, kh, k, (*j), k);
0130 }
0131 }
0132
0133 for (long long j = 0; j < N; j++) {
0134 auto b0 = h.bin(v[j]);
0135 int w = 0;
0136 int tot = 0;
0137 auto ftest = [&](int k) {
0138 assert(k >= 0 && k < N);
0139 tot++;
0140 };
0141 forEachInBins(h, v[j], w, ftest);
0142 int rtot = h.end(b0) - h.begin(b0);
0143 assert(tot == rtot);
0144 w = 1;
0145 tot = 0;
0146 forEachInBins(h, v[j], w, ftest);
0147 int bp = b0 + 1;
0148 int bm = b0 - 1;
0149 if (bp < int(h.nbins()))
0150 rtot += h.end(bp) - h.begin(bp);
0151 if (bm >= 0)
0152 rtot += h.end(bm) - h.begin(bm);
0153 assert(tot == rtot);
0154 w = 2;
0155 tot = 0;
0156 forEachInBins(h, v[j], w, ftest);
0157 bp++;
0158 bm--;
0159 if (bp < int(h.nbins()))
0160 rtot += h.end(bp) - h.begin(bp);
0161 if (bm >= 0)
0162 rtot += h.end(bm) - h.begin(bm);
0163 assert(tot == rtot);
0164 }
0165 }
0166
0167 int main() {
0168 cms::cudatest::requireDevices();
0169
0170 go<int16_t>();
0171 go<uint8_t, 128, 8, 4>();
0172 go<uint16_t, 313 / 2, 9, 4>();
0173
0174 return 0;
0175 }