42#ifndef ALICEO2_BASE_REPRESENTATIONBENCH_H_
43#define ALICEO2_BASE_REPRESENTATIONBENCH_H_
48#include "TGeoBoolNode.h"
49#include "TGeoCompositeShape.h"
50#include "TGeoMatrix.h"
113 acc ^=
bits + 0x9e3779b97f4a7c15ULL + (acc << 6) + (acc >> 2);
125template <
typename Pass>
130 if (callsPerPass <= 0 || passes <= 0) {
133 for (
int i = 0;
i < warmupPasses; ++
i) {
136 std::vector<double> perPass;
137 perPass.reserve(passes);
138 for (
int i = 0;
i < passes; ++
i) {
139 const auto t0 = std::chrono::steady_clock::now();
140 const uint64_t
sum = pass();
141 const auto t1 = std::chrono::steady_clock::now();
143 perPass.push_back(std::chrono::duration<double, std::nano>(
t1 -
t0).
count() /
144 static_cast<double>(callsPerPass));
146 std::sort(perPass.begin(), perPass.end());
184 std::ifstream statm(
"/proc/self/statm");
186 long long totalPages = 0;
187 long long residentPages = 0;
188 statm >> totalPages >> residentPages;
189 out.
residentBytes = residentPages *
static_cast<long long>(::sysconf(_SC_PAGESIZE));
191#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 33))
192 const struct mallinfo2 info = ::mallinfo2();
193 out.
heapInUseBytes =
static_cast<long long>(info.uordblks) +
static_cast<long long>(info.hblkhd);
220 std::ifstream in(
path, std::ios::binary | std::ios::ate);
221 return in ?
static_cast<long long>(in.tellg()) : 0;
248 uint64_t
state = 88172645463325252ULL;
251 state =
state * 6364136223846793005ULL + 1442695040888963407ULL;
252 return static_cast<double>((
state >> 11) & ((1ULL << 53) - 1)) /
static_cast<double>(1ULL << 53);
267 const Point3D& bboxMin,
const Point3D& bboxMax,
int nPoints,
268 int nRays, uint64_t seed = 20260802ULL,
double inflate = 0.12)
276 for (
int k = 0; k < 3; ++k) {
277 const double half = 0.5 * (bboxMax[k] - bboxMin[k]);
278 centre[k] = 0.5 * (bboxMax[k] + bboxMin[k]);
279 lo[k] = centre[k] -
half * (1. + inflate);
280 hi[k] = centre[k] +
half * (1. + inflate);
282 auto drawPoint = [&]() {
284 for (
int k = 0; k < 3; ++k) {
285 p[k] = lo[k] + (hi[k] - lo[k]) * rng.next();
289 out.
points.reserve(nPoints);
291 for (
int i = 0;
i < nPoints; ++
i) {
292 const Point3D p = drawPoint();
293 const bool in =
reference->Contains(p.data());
298 const int budget = 400 * std::max(1, nRays);
300 while (
static_cast<int>(out.
outsideRays.size()) < nRays && attempts < budget) {
302 const Point3D p = drawPoint();
310 for (
int k = 0; k < 3; ++k) {
311 target[k] = bboxMin[k] + (bboxMax[k] - bboxMin[k]) * rng.next();
314 const double norm = std::sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
318 for (
int k = 0; k < 3; ++k) {
324 while (
static_cast<int>(out.
insideRays.size()) < nRays && attempts < budget) {
326 const Point3D p = drawPoint();
330 const double z = 2. * rng.next() - 1.;
331 const double phi = 2. * 3.14159265358979323846 * rng.next();
332 const double r = std::sqrt(std::max(0., 1. -
z *
z));
333 out.
insideRays.push_back({p, {
r * std::cos(phi),
r * std::sin(phi),
z}});
348 return timePasses(
static_cast<long long>(s.points.size()), warmup, passes, [&]() {
350 for (const auto& p : s.points) {
351 acc = detail::mix(acc, shape->Contains(p.data()) ? 1. : 0.);
364 return timePasses(
static_cast<long long>(s.points.size()), warmup, passes, [&]() {
366 for (size_t i = 0; i < s.points.size(); ++i) {
367 acc = detail::mix(acc, shape->Safety(s.points[i].data(), s.pointIsInside[i] ? kTRUE : kFALSE));
377 TimingStat stat =
timePasses(
static_cast<long long>(s.outsideRays.size()), warmup, passes, [&]() {
379 for (const auto& ray : s.outsideRays) {
380 const double d = shape->DistFromOutside(ray.origin.data(), ray.dir.data(), 3, TGeoShape::Big(), nullptr);
381 hits += (d < TGeoShape::Big()) ? 1 : 0;
383 acc = detail::mix(acc, d);
387 stat.
hitFraction = calls > 0 ?
static_cast<double>(hits) /
static_cast<double>(calls) : -1.;
395 TimingStat stat =
timePasses(
static_cast<long long>(s.insideRays.size()), warmup, passes, [&]() {
397 for (const auto& ray : s.insideRays) {
398 const double d = shape->DistFromInside(ray.origin.data(), ray.dir.data(), 3, TGeoShape::Big(), nullptr);
399 hits += (d < TGeoShape::Big()) ? 1 : 0;
401 acc = detail::mix(acc, d);
405 stat.
hitFraction = calls > 0 ?
static_cast<double>(hits) /
static_cast<double>(calls) : -1.;
442 const double rMin = 0.2;
443 const double rMax = 0.5;
444 const double dz = 1.0;
445 const double pitch = 0.8;
447 std::vector<TGeoShape*>
nodes;
448 std::vector<TGeoMatrix*>
offsets;
449 for (
int i = 0;
i < leaves; ++
i) {
450 auto* tube =
new TGeoTube(leafName(
i).c_str(), rMin, rMax, dz);
451 nodes.push_back(tube);
452 auto*
m =
new TGeoTranslation((
i - 0.5 * (leaves - 1)) * pitch, 0., 0.);
453 m->SetName((leafName(
i) +
"_m").c_str());
454 m->RegisterYourself();
458 return nodes.front();
461 auto join = [&](TGeoShape*
a, TGeoMatrix* ma, TGeoShape*
b, TGeoMatrix* mb) -> TGeoShape* {
462 auto*
node =
new TGeoUnion(
a,
b, ma, mb);
463 auto* composite =
new TGeoCompositeShape((tag +
"_u" +
std::to_string(serial++)).c_str(),
node);
466 if (shape == LadderShape::Chain) {
467 TGeoShape* acc =
nodes[0];
468 TGeoMatrix* accMatrix =
offsets[0];
469 for (
int i = 1;
i < leaves; ++
i) {
476 std::vector<TGeoMatrix*> levelMatrix =
offsets;
477 while (
level.size() > 1) {
478 std::vector<TGeoShape*> next;
479 std::vector<TGeoMatrix*> nextMatrix;
480 for (
size_t i = 0;
i <
level.size();
i += 2) {
481 if (
i + 1 <
level.size()) {
482 next.push_back(join(
level[
i], levelMatrix[
i],
level[
i + 1], levelMatrix[
i + 1]));
483 nextMatrix.push_back(
nullptr);
486 nextMatrix.push_back(levelMatrix[
i]);
490 levelMatrix.swap(nextMatrix);
492 return level.front();
500 long long leaves = 0;
508 const auto* composite =
dynamic_cast<const TGeoCompositeShape*
>(shape);
509 if (composite ==
nullptr || composite->GetBoolNode() ==
nullptr) {
514 const TGeoBoolNode*
node = composite->GetBoolNode();
543 for (
int i = 0;
i < mBurn; ++
i) {
544 acc = std::sqrt(acc * acc + point[
i % 3] * point[
i % 3] + 1.);
551 return TGeoBBox::Contains(point) && ballast(point) > 0.;
553 double Safety(
const double* point,
bool in = kTRUE)
const override
555 return TGeoBBox::Safety(point, in) + 0. * ballast(point);
558 double step = TGeoShape::Big(),
double* safe =
nullptr)
const override
560 return TGeoBBox::DistFromOutside(point, dir, iact, step, safe) + 0. * ballast(point);
563 double step = TGeoShape::Big(),
double* safe =
nullptr)
const override
565 return TGeoBBox::DistFromInside(point, dir, iact, step, safe) + 0. * ballast(point);
std::unique_ptr< expressions::Node > node
Validation and timing harness for TGeoShape navigation, typed on plain TGeoShape*.
bool Contains(const double *point) const override
BallastShape(const char *name, double dx, double dy, double dz, int burn)
double ballast(const double *point) const
double DistFromInside(const double *point, const double *dir, int iact=1, double step=TGeoShape::Big(), double *safe=nullptr) const override
double Safety(const double *point, bool in=kTRUE) const override
double DistFromOutside(const double *point, const double *dir, int iact=1, double step=TGeoShape::Big(), double *safe=nullptr) const override
float sum(float s, o2::dcs::DataPointValue v)
GLuint GLsizei const GLuint const GLintptr * offsets
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
GLint GLint GLsizei GLsizei GLsizei depth
GLsizei const GLchar *const * path
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
GLboolean GLboolean GLboolean GLboolean a
GLdouble GLdouble GLdouble z
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
uint64_t mix(uint64_t acc, double value)
TimingStat timeSafetyPass(const TGeoShape *shape, const QuerySamples &s, int warmup, int passes)
long long fileBytes(const std::string &path)
QuerySamples buildQuerySamples(const TGeoShape *reference, const std::string &referenceName, const Point3D &bboxMin, const Point3D &bboxMax, int nPoints, int nRays, uint64_t seed=20260802ULL, double inflate=0.12)
TGeoShape * buildBooleanLadder(int leaves, LadderShape shape, const std::string &tag)
TimingStat timeContainsPass(const TGeoShape *shape, const QuerySamples &s, int warmup, int passes)
MemorySnapshot readMemory()
MemorySnapshot operator-(const MemorySnapshot &a, const MemorySnapshot &b)
TimingStat timePasses(long long callsPerPass, int warmupPasses, int passes, Pass &&pass)
TimingStat timeDistInPass(const TGeoShape *shape, const QuerySamples &s, int warmup, int passes)
TimingStat timeDistOutPass(const TGeoShape *shape, const QuerySamples &s, int warmup, int passes)
BooleanTreeStats booleanTreeStats(const TGeoShape *shape)
std::array< double, 3 > Point3D
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
long long nodes
TGeoCompositeShape / TGeoBoolNode pairs.
std::vector< char > pointIsInside
the reference's Contains() for each, as a fixed label
std::vector< Ray > insideRays
origin inside per the reference, isotropic direction
std::vector< Ray > outsideRays
origin outside per the reference, aimed into the bbox
std::string partitionedBy
std::vector< Point3D > points
all query points, mixed inside/outside, in bbox order
long long primitives
triangles / analytic patches / boolean leaves
long long sidecarBytes
the file the representation was loaded from, on disk
long long bytes
the arithmetic below, exact for the arrays it counts