Project
Loading...
Searching...
No Matches
Utils.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
15
16#ifndef ITSTRACKINGGPU_UTILS_H_
17#define ITSTRACKINGGPU_UTILS_H_
18
19#include <vector>
20#include <string>
21#include <tuple>
22
25
26#include "GPUCommonDef.h"
27#include "GPUCommonHelpers.h"
28#include "GPUCommonLogger.h"
29#include "GPUCommonDefAPI.h"
30
31#ifdef GPUCA_GPUCODE
32#include <thrust/device_ptr.h>
33#ifndef __HIPCC__
34#define THRUST_NAMESPACE thrust::cuda
35#else
36#define THRUST_NAMESPACE thrust::hip
37#endif
38#endif
39
40#ifdef ITS_GPU_LOG
41#if defined(__HIPCC__)
42#define GPULogSync() GPUChkErrS(hipDeviceSynchronize())
43#elif defined(__CUDACC__)
44#define GPULogSync() GPUChkErrS(cudaDeviceSynchronize())
45#else
46#define GPULogSync()
47#endif
48#define GPULog(...) \
49 do { \
50 LOGP(info, __VA_ARGS__); \
51 GPULogSync(); \
52 } while (0)
53#else
54#define GPULog(...)
55#endif
56
57namespace o2::its
58{
59// FWD declarations
60template <int>
61class IndexTableUtils;
62class Tracklet;
63
64template <typename T1, typename T2>
65using gpuPair = std::pair<T1, T2>;
66
67namespace gpu
68{
69
70template <typename T>
71struct gpuSpan {
72 using value_type = T;
73 using ptr = T*;
74 using ref = T&;
75
76 GPUd() gpuSpan() : _data(nullptr), _size(0) {}
77 GPUd() gpuSpan(ptr data, unsigned int dim) : _data(data), _size(dim) {}
78 GPUd() ref operator[](unsigned int idx) const { return _data[idx]; }
79 GPUd() unsigned int size() const { return _size; }
80 GPUd() bool empty() const { return _size == 0; }
81 GPUd() ref front() const { return _data[0]; }
82 GPUd() ref back() const { return _data[_size - 1]; }
83 GPUd() ptr begin() const { return _data; }
84 GPUd() ptr end() const { return _data + _size; }
85
86 protected:
88 unsigned int _size;
89};
90
91template <typename T>
92struct gpuSpan<const T> {
93 using value_type = T;
94 using ptr = const T*;
95 using ref = const T&;
96
97 GPUd() gpuSpan() : _data(nullptr), _size(0) {}
98 GPUd() gpuSpan(ptr data, unsigned int dim) : _data(data), _size(dim) {}
100 GPUd() ref operator[](unsigned int idx) const { return _data[idx]; }
101 GPUd() unsigned int size() const { return _size; }
102 GPUd() bool empty() const { return _size == 0; }
103 GPUd() ref front() const { return _data[0]; }
104 GPUd() ref back() const { return _data[_size - 1]; }
105 GPUd() ptr begin() const { return _data; }
106 GPUd() ptr end() const { return _data + _size; }
107
108 protected:
110 unsigned int _size;
111};
112
113// Abstract stream class
115{
116 public:
117#if defined(__HIPCC__)
118 using Handle = hipStream_t;
119 static constexpr Handle DefaultStream = 0;
120 static constexpr unsigned int DefaultFlag = hipStreamNonBlocking;
121 using Event = hipEvent_t;
122#elif defined(__CUDACC__)
123 using Handle = cudaStream_t;
124 static constexpr Handle DefaultStream = 0;
125 static constexpr unsigned int DefaultFlag = cudaStreamNonBlocking;
126 using Event = cudaEvent_t;
127#else
128 using Handle = void*;
129 static constexpr Handle DefaultStream = nullptr;
130 static constexpr unsigned int DefaultFlag = 0;
131 using Event = void*;
132#endif
133
134 Stream(unsigned int flags = DefaultFlag)
135 {
136#if defined(__HIPCC__)
137 GPUChkErrS(hipStreamCreateWithFlags(&mHandle, flags));
138 GPUChkErrS(hipEventCreateWithFlags(&mEvent, hipEventDisableTiming));
139#elif defined(__CUDACC__)
140 GPUChkErrS(cudaStreamCreateWithFlags(&mHandle, flags));
141 GPUChkErrS(cudaEventCreateWithFlags(&mEvent, cudaEventDisableTiming));
142#endif
143 }
144
145 Stream(Handle h) : mHandle(h) {}
147 {
148 if (mHandle != DefaultStream) {
149#if defined(__HIPCC__)
150 GPUChkErrS(hipStreamDestroy(mHandle));
151 GPUChkErrS(hipEventDestroy(mEvent));
152#elif defined(__CUDACC__)
153 GPUChkErrS(cudaStreamDestroy(mHandle));
154 GPUChkErrS(cudaEventDestroy(mEvent));
155#endif
156 }
157 }
158
159 operator bool() const { return mHandle != DefaultStream; }
160 const Handle& get() { return mHandle; }
161 const Handle& getStream() { return mHandle; }
162 const Event& getEvent() { return mEvent; }
163 void sync() const
164 {
165#if defined(__HIPCC__)
166 GPUChkErrS(hipStreamSynchronize(mHandle));
167#elif defined(__CUDACC__)
168 GPUChkErrS(cudaStreamSynchronize(mHandle));
169#endif
170 }
171 void record()
172 {
173#if defined(__HIPCC__)
174 GPUChkErrS(hipEventRecord(mEvent, mHandle));
175#elif defined(__CUDACC__)
176 GPUChkErrS(cudaEventRecord(mEvent, mHandle));
177#endif
178 }
179
180 private:
181 Handle mHandle{DefaultStream};
182 Event mEvent{nullptr};
183};
184
185// Abstract vector for streams.
187{
188 public:
189 size_t size() const noexcept { return mStreams.size(); }
190 void resize(size_t n) { mStreams.resize(n); }
191 void clear() { mStreams.clear(); }
192 auto& operator[](size_t i) { return mStreams[i]; }
193 void push_back(const Stream& stream) { mStreams.push_back(stream); }
194 void sync(bool device = true)
195 {
196 if (device) {
197#if defined(__HIPCC__)
198 GPUChkErrS(hipDeviceSynchronize());
199#elif defined(__CUDACC__)
200 GPUChkErrS(cudaDeviceSynchronize());
201#endif
202 } else {
203 for (auto& s : mStreams) {
204 s.sync();
205 }
206 }
207 }
208 void waitEvent(size_t iStream, size_t iEvent)
209 {
210#if defined(__HIPCC__)
211 GPUChkErrS(hipStreamWaitEvent(mStreams[iStream].get(), mStreams[iEvent].getEvent()));
212#elif defined(__CUDACC__)
213 GPUChkErrS(cudaStreamWaitEvent(mStreams[iStream].get(), mStreams[iEvent].getEvent()));
214#endif
215 }
216
217 private:
218 std::vector<Stream> mStreams;
219};
220
221#ifdef ITS_MEASURE_GPU_TIME
222class GPUTimer
223{
224 public:
225 GPUTimer(const std::string& name)
226 : mName(name)
227 {
228 mStreams.emplace_back(Stream::DefaultStream);
229 startTimers();
230 }
231 GPUTimer(Streams& streams, const std::string& name)
232 : mName(name)
233 {
234 for (size_t i{0}; i < streams.size(); ++i) {
235 mStreams.push_back(streams[i].get());
236 }
237 startTimers();
238 }
239 GPUTimer(Streams& streams, const std::string& name, size_t end, size_t start = 0)
240 : mName(name)
241 {
242 for (size_t sta{start}; sta < end; ++sta) {
243 mStreams.push_back(streams[sta].get());
244 }
245 startTimers();
246 }
247 GPUTimer(Stream& stream, const std::string& name, const int id = 0)
248 : mName(name)
249 {
250 mStreams.push_back(stream.get());
251 mName += ":id" + std::to_string(id);
252 startTimers();
253 }
254 ~GPUTimer()
255 {
256 for (size_t i{0}; i < mStreams.size(); ++i) {
257 float ms = 0.0f;
258#if defined(__HIPCC__)
259 GPUChkErrS(hipEventRecord(mStops[i], mStreams[i]));
260 GPUChkErrS(hipEventSynchronize(mStops[i]));
261 GPUChkErrS(hipEventElapsedTime(&ms, mStarts[i], mStops[i]));
262 GPUChkErrS(hipEventDestroy(mStarts[i]));
263 GPUChkErrS(hipEventDestroy(mStops[i]));
264#elif defined(__CUDACC__)
265 GPUChkErrS(cudaEventRecord(mStops[i], mStreams[i]));
266 GPUChkErrS(cudaEventSynchronize(mStops[i]));
267 GPUChkErrS(cudaEventElapsedTime(&ms, mStarts[i], mStops[i]));
268 GPUChkErrS(cudaEventDestroy(mStarts[i]));
269 GPUChkErrS(cudaEventDestroy(mStops[i]));
270#endif
271 LOGP(info, "Elapsed time for {}:{} {} ms", mName, i, ms);
272 }
273 }
274
275 void startTimers()
276 {
277 mStarts.resize(mStreams.size());
278 mStops.resize(mStreams.size());
279 for (size_t i{0}; i < mStreams.size(); ++i) {
280#if defined(__HIPCC__)
281 GPUChkErrS(hipEventCreate(&mStarts[i]));
282 GPUChkErrS(hipEventCreate(&mStops[i]));
283 GPUChkErrS(hipEventRecord(mStarts[i], mStreams[i]));
284#elif defined(__CUDACC__)
285 GPUChkErrS(cudaEventCreate(&mStarts[i]));
286 GPUChkErrS(cudaEventCreate(&mStops[i]));
287 GPUChkErrS(cudaEventRecord(mStarts[i], mStreams[i]));
288#endif
289 }
290 }
291
292 private:
293 std::string mName;
294 std::vector<Stream::Event> mStarts, mStops;
295 std::vector<Stream::Handle> mStreams;
296};
297#else // ITS_MEASURE_GPU_TIME not defined
299{
300 public:
301 template <typename... Args>
302 GPUTimer(Args&&...)
303 {
304 }
305};
306#endif
307
308#ifdef GPUCA_GPUCODE
309template <typename T>
310struct TypedAllocator {
311 using value_type = T;
312 using pointer = thrust::device_ptr<T>;
313 using const_pointer = thrust::device_ptr<const T>;
314 using size_type = std::size_t;
315 using difference_type = std::ptrdiff_t;
316
317 TypedAllocator() noexcept : mInternalAllocator(nullptr) {}
318 explicit TypedAllocator(ExternalAllocator* a) noexcept : mInternalAllocator(a) {}
319
320 template <typename U>
321 TypedAllocator(const TypedAllocator<U>& o) noexcept : mInternalAllocator(o.mInternalAllocator)
322 {
323 }
324
325 pointer allocate(size_type n)
326 {
327 void* raw = mInternalAllocator->allocateStack(n * sizeof(T));
328 return thrust::device_pointer_cast(static_cast<T*>(raw));
329 }
330
331 void deallocate(pointer p, size_type n) noexcept
332 {
333 if (!p) {
334 return;
335 }
336 void* raw = thrust::raw_pointer_cast(p);
337 mInternalAllocator->deallocate(static_cast<char*>(raw), n * sizeof(T));
338 }
339
340 bool operator==(TypedAllocator const& o) const noexcept
341 {
342 return mInternalAllocator == o.mInternalAllocator;
343 }
344 bool operator!=(TypedAllocator const& o) const noexcept
345 {
346 return !(*this == o);
347 }
348
349 private:
350 ExternalAllocator* mInternalAllocator;
351};
352
353// first i in [beg,end) with a[i] >= key
354template <typename T>
355GPUdii() int deviceLowerBound(const T* a, int beg, int end, const T key)
356{
357 while (beg < end) {
358 const int mid = beg + (end - beg) / 2;
359 if (a[mid] < key) {
360 beg = mid + 1;
361 } else {
362 end = mid;
363 }
364 }
365 return beg;
366}
367
368// first i in [beg,end) with a[i] > key
369template <typename T>
370GPUdii() int deviceUpperBound(const T* a, int beg, int end, const T key)
371{
372 while (beg < end) {
373 const int mid = beg + (end - beg) / 2;
374 if (a[mid] <= key) {
375 beg = mid + 1;
376 } else {
377 end = mid;
378 }
379 }
380 return beg;
381}
382
383GPUdii() gpuSpan<const Cluster> getClustersOnLayer(const int rof,
384 const int totROFs,
385 const int layer,
386 const int** roframesClus,
387 const Cluster** clusters)
388{
389 if (rof < 0 || rof >= totROFs) {
390 return gpuSpan<const Cluster>();
391 }
392 const int start_clus_id{roframesClus[layer][rof]};
393 const int stop_rof = rof >= totROFs - 1 ? totROFs : rof + 1;
394 const unsigned int delta = roframesClus[layer][stop_rof] - start_clus_id;
395 return gpuSpan<const Cluster>(&(clusters[layer][start_clus_id]), delta);
396}
397
398#endif
399} // namespace gpu
400} // namespace o2::its
401
402#endif
int32_t i
#define GPUdii()
#define GPUChkErrS(x)
o2::raw::RawFileWriter * raw
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc bool
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc Replace constant variables static by constexpr expressions Compile RTC in deterministic with NO_FAST_MATH flags and GPUCA_DETERMINISTIC_MODE define Use RTC to optimize GPU code h configStandalone Processing proc_rtctech Use a file lock to serialize access to the cache folder Print launch bounds used for RTC code as debugging for exit after Allow RTC with slave GPUReconstruction instances with optConstexpr and optSpecialcode Maximum number of RTC cache files per backend in the cache the oldest are Prepend RTC compilation commands by this string Load a parameter object containing the launch bounds from a file h configStandalone Processing proc_param TPC Cluster Z Error Parameterization h configStandalone Processing settings for neural network proc_nn std::string Specify inference device(cpu(default), rocm, cuda)") AddOption(nnInferenceDeviceId
StringRef key
Class for time synchronization of RawReader instances.
HMPID cluster implementation.
Definition Cluster.h:27
GPUTimer(Args &&...)
Definition Utils.h:302
const Handle & getStream()
Definition Utils.h:161
void sync() const
Definition Utils.h:163
const Handle & get()
Definition Utils.h:160
static constexpr Handle DefaultStream
Definition Utils.h:129
static constexpr unsigned int DefaultFlag
Definition Utils.h:130
const Event & getEvent()
Definition Utils.h:162
Stream(unsigned int flags=DefaultFlag)
Definition Utils.h:134
Stream(Handle h)
Definition Utils.h:145
void resize(size_t n)
Definition Utils.h:190
void push_back(const Stream &stream)
Definition Utils.h:193
void waitEvent(size_t iStream, size_t iEvent)
Definition Utils.h:208
void sync(bool device=true)
Definition Utils.h:194
auto & operator[](size_t i)
Definition Utils.h:192
size_t size() const noexcept
Definition Utils.h:189
GLdouble n
Definition glcorearb.h:1982
GLenum void ** pointer
Definition glcorearb.h:805
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLuint end
Definition glcorearb.h:469
GLuint const GLchar * name
Definition glcorearb.h:781
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLuint GLuint stream
Definition glcorearb.h:1806
auto get(const std::byte *buffer, size_t=0)
Definition DataHeader.h:457
std::pair< T1, T2 > gpuPair
Definition Utils.h:65
const int end
bool operator!=(const DsChannelId &a, const DsChannelId &b)
Definition DsChannelId.h:66
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
void empty(int)
GPUd() gpuSpan(const gpuSpan< T > &other)
Definition Utils.h:99
GPUd() ref front() const
Definition Utils.h:103
GPUd() bool empty() const
Definition Utils.h:102
GPUd() ref operator[](unsigned int idx) const
Definition Utils.h:100
GPUd() ptr end() const
Definition Utils.h:106
GPUd() unsigned int size() const
Definition Utils.h:101
GPUd() ptr begin() const
Definition Utils.h:105
GPUd() ref back() const
Definition Utils.h:104
GPUd() bool empty() const
Definition Utils.h:80
unsigned int dim
Definition Utils.h:77
GPUd() ptr begin() const
Definition Utils.h:83
GPUd() ref operator[](unsigned int idx) const
Definition Utils.h:78
GPUd() gpuSpan()
Definition Utils.h:76
GPUd() ptr end() const
Definition Utils.h:84
GPUd() unsigned int size() const
Definition Utils.h:79
unsigned int _size
Definition Utils.h:88
GPUd() ref back() const
Definition Utils.h:82
GPUd() ref front() const
Definition Utils.h:81
bool operator==(const CoarseLocation &a, const CoarseLocation &b)
VectorOfTObjectPtrs other
std::vector< Cluster > clusters