Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-04-17 02:46:52

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       // std::cout << kl << ' ' << kh << std::endl;
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 }