OmniSciDB  04ee39c94c
anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT > Class Template Reference

Public Types

using ResultType = std::unordered_map< std::vector< KeyT >, std::vector< ValT > >
 

Public Member Functions

 AggregateEmulator (const std::vector< OP_KIND > &ops)
 
ResultType run (const int8_t *buffers, const size_t key_count, const size_t val_count, const size_t row_count, const bool is_columnar)
 
bool compare (const int8_t *buffers, const size_t key_count, const size_t val_count, const size_t group_count, const bool is_columnar, const ResultType &ref_result)
 
ResultType reduce (const std::vector< ResultType > &partial_results)
 

Private Member Functions

void runDispatch (ResultType &partial_res, const int8_t *buffers, const size_t key_count, const size_t val_count, const size_t row_count, const size_t start_row, const size_t end_row, const bool is_columnar)
 
size_t compareDispatch (const int8_t *buffers, const size_t key_count, const size_t val_count, const size_t group_count, const size_t start_group, const size_t end_group, const bool is_columnar, const ResultType &ref_result)
 

Private Attributes

std::vector< OP_KINDagg_ops_
 

Detailed Description

template<typename KeyT = int64_t, typename ValT = int64_t>
class anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT >

Definition at line 392 of file ProfileTest.cpp.

Member Typedef Documentation

◆ ResultType

template<typename KeyT = int64_t, typename ValT = int64_t>
using anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT >::ResultType = std::unordered_map<std::vector<KeyT>, std::vector<ValT> >

Definition at line 394 of file ProfileTest.cpp.

Constructor & Destructor Documentation

◆ AggregateEmulator()

template<typename KeyT = int64_t, typename ValT = int64_t>
anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT >::AggregateEmulator ( const std::vector< OP_KIND > &  ops)
inlineexplicit

Definition at line 396 of file ProfileTest.cpp.

Member Function Documentation

◆ compare()

template<typename KeyT = int64_t, typename ValT = int64_t>
bool anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT >::compare ( const int8_t *  buffers,
const size_t  key_count,
const size_t  val_count,
const size_t  group_count,
const bool  is_columnar,
const ResultType ref_result 
)
inline

Definition at line 429 of file ProfileTest.cpp.

References cpu_threads().

434  {
435  std::vector<std::future<size_t>> child_threads;
436  const size_t cpu_count = cpu_threads();
437  const auto stride = (group_count + cpu_count - 1) / cpu_count;
438  for (size_t start_group = 0; start_group < group_count; start_group += stride) {
439  const auto end_group = std::min(group_count, start_group + stride);
440  child_threads.push_back(std::async(std::launch::async,
442  this,
443  buffers,
444  key_count,
445  val_count,
446  group_count,
447  start_group,
448  end_group,
449  is_columnar,
450  ref_result));
451  }
452  size_t matches = 0;
453  for (auto& child : child_threads) {
454  matches += child.get();
455  }
456 
457  return matches == ref_result.size();
458  }
size_t compareDispatch(const int8_t *buffers, const size_t key_count, const size_t val_count, const size_t group_count, const size_t start_group, const size_t end_group, const bool is_columnar, const ResultType &ref_result)
int cpu_threads()
Definition: thread_count.h:23
+ Here is the call graph for this function:

◆ compareDispatch()

template<typename KeyT = int64_t, typename ValT = int64_t>
size_t anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT >::compareDispatch ( const int8_t *  buffers,
const size_t  key_count,
const size_t  val_count,
const size_t  group_count,
const size_t  start_group,
const size_t  end_group,
const bool  is_columnar,
const ResultType ref_result 
)
inlineprivate

Definition at line 584 of file ProfileTest.cpp.

References CHECK_EQ, CHECK_LT, anonymous_namespace{ProfileTest.cpp}::is_empty_slot(), and v().

591  {
592  CHECK_LT(size_t(0), key_count);
593  size_t matches = 0;
594  const size_t row_size = sizeof(KeyT) * key_count + sizeof(ValT) * val_count;
595  for (size_t i = start_group; i < end_group; ++i) {
596  std::vector<KeyT> keys(key_count);
597  const auto key_buffers = reinterpret_cast<const KeyT*>(buffers);
598  if (is_columnar) {
599  for (size_t k = 0; k < key_count; ++k) {
600  keys[k] = key_buffers[i + k * group_count];
601  }
602  } else {
603  for (size_t k = 0; k < key_count; ++k) {
604  keys[k] = reinterpret_cast<const KeyT*>(buffers + i * row_size)[k];
605  }
606  }
607  if (is_empty_slot(keys[0])) {
608  continue;
609  }
610  auto row_it = ref_result.find(keys);
611  if (row_it == ref_result.end()) {
612  return 0;
613  }
614  auto& ref_vals = row_it->second;
615  CHECK_EQ(val_count, ref_vals.size());
616  std::vector<ValT> actual_vals(val_count);
617  for (size_t v = 0; v < val_count; ++v) {
618  if (is_columnar) {
619  auto val_buffers =
620  reinterpret_cast<const ValT*>(key_buffers + key_count * group_count);
621  actual_vals[v] = val_buffers[i + v * group_count];
622  } else {
623  auto val_buffers = reinterpret_cast<const ValT*>(buffers + row_size * i +
624  sizeof(KeyT) * key_count);
625  actual_vals[v] = val_buffers[v];
626  }
627  }
628  for (size_t v = 0; v < val_count; ++v) {
629  if (actual_vals[v] != ref_vals[v]) {
630  return 0;
631  }
632  }
633  ++matches;
634  }
635  return matches;
636  }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
T v(const TargetValue &r)
#define CHECK_LT(x, y)
Definition: Logger.h:197
+ Here is the call graph for this function:

◆ reduce()

template<typename KeyT = int64_t, typename ValT = int64_t>
ResultType anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT >::reduce ( const std::vector< ResultType > &  partial_results)
inline

Definition at line 460 of file ProfileTest.cpp.

References CHECK, CHECK_EQ, anonymous_namespace{ProfileTest.cpp}::is_empty_slot(), OP_COUNT, OP_MAX, OP_MIN, OP_SUM, and v().

460  {
461  ResultType final_result;
462  if (partial_results.size() == 1) {
463  final_result = partial_results[0];
464  return final_result;
465  }
466  for (auto& groups : partial_results) {
467  for (auto& grp : groups) {
468  auto& keys = grp.first;
469  if (is_empty_slot(keys[0])) {
470  continue;
471  }
472  if (!final_result.count(keys)) {
473  final_result.insert(std::make_pair(keys, grp.second));
474  continue;
475  }
476  const auto val_count = agg_ops_.size();
477  CHECK_EQ(val_count, final_result[keys].size());
478  CHECK_EQ(val_count, grp.second.size());
479  for (size_t v = 0; v < val_count; ++v) {
480  const ValT value = grp.second[v];
481  switch (agg_ops_[v]) {
482  case OP_COUNT:
483  case OP_SUM:
484  final_result[keys][v] += value;
485  break;
486  case OP_MIN:
487  final_result[keys][v] = std::min(final_result[keys][v], value);
488  break;
489  case OP_MAX:
490  final_result[keys][v] = std::max(final_result[keys][v], value);
491  break;
492  default:
493  CHECK(false);
494  }
495  }
496  }
497  }
498  return final_result;
499  }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
T v(const TargetValue &r)
#define CHECK(condition)
Definition: Logger.h:187
std::unordered_map< std::vector< KeyT >, std::vector< ValT > > ResultType
+ Here is the call graph for this function:

◆ run()

template<typename KeyT = int64_t, typename ValT = int64_t>
ResultType anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT >::run ( const int8_t *  buffers,
const size_t  key_count,
const size_t  val_count,
const size_t  row_count,
const bool  is_columnar 
)
inline

Definition at line 398 of file ProfileTest.cpp.

References cpu_threads().

402  {
403  std::vector<std::future<void>> child_threads;
404  const size_t cpu_count = cpu_threads();
405  const size_t stride = (row_count + cpu_count - 1) / cpu_count;
406  std::vector<ResultType> partial_results(cpu_count);
407  for (size_t start_row = 0, i = 0; start_row < row_count; start_row += stride, ++i) {
408  const auto end_row = std::min(row_count, start_row + stride);
409  child_threads.push_back(std::async(std::launch::async,
411  this,
412  std::ref(partial_results[i]),
413  buffers,
414  key_count,
415  val_count,
416  row_count,
417  start_row,
418  end_row,
419  is_columnar));
420  }
421 
422  for (auto& child : child_threads) {
423  child.get();
424  }
425 
426  return reduce(partial_results);
427  }
ResultType reduce(const std::vector< ResultType > &partial_results)
int cpu_threads()
Definition: thread_count.h:23
void runDispatch(ResultType &partial_res, const int8_t *buffers, const size_t key_count, const size_t val_count, const size_t row_count, const size_t start_row, const size_t end_row, const bool is_columnar)
+ Here is the call graph for this function:

◆ runDispatch()

template<typename KeyT = int64_t, typename ValT = int64_t>
void anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT >::runDispatch ( ResultType partial_res,
const int8_t *  buffers,
const size_t  key_count,
const size_t  val_count,
const size_t  row_count,
const size_t  start_row,
const size_t  end_row,
const bool  is_columnar 
)
inlineprivate

Definition at line 502 of file ProfileTest.cpp.

References CHECK, CHECK_EQ, anonymous_namespace{ProfileTest.cpp}::is_empty_slot(), OP_COUNT, OP_MAX, OP_MIN, OP_SUM, and v().

509  {
510  CHECK_EQ(agg_ops_.size(), val_count);
511  const size_t row_size = sizeof(KeyT) * key_count + sizeof(ValT) * val_count;
512  for (size_t i = start_row; i < end_row; ++i) {
513  std::vector<KeyT> keys(key_count);
514  auto key_buffers = reinterpret_cast<const KeyT*>(buffers);
515  if (is_columnar) {
516  for (size_t k = 0; k < key_count; ++k) {
517  keys[k] = key_buffers[i + k * row_count];
518  }
519  } else {
520  for (size_t k = 0; k < key_count; ++k) {
521  keys[k] = reinterpret_cast<const KeyT*>(buffers + i * row_size)[k];
522  }
523  }
524  CHECK_EQ(keys.size(), key_count);
525  if (is_empty_slot(keys[0])) {
526  continue;
527  }
528 
529  const bool inserted = partial_res.count(keys) != 0;
530  if (inserted) {
531  CHECK_EQ(partial_res[keys].size(), val_count);
532  } else {
533  partial_res[keys] = std::vector<ValT>(val_count);
534  }
535 
536  for (size_t v = 0; v < val_count; ++v) {
537  ValT value;
538  if (is_columnar) {
539  auto val_buffer =
540  reinterpret_cast<const ValT*>(key_buffers + key_count * row_count);
541  value = val_buffer[i + v * row_count];
542  } else {
543  auto val_buffer = reinterpret_cast<const ValT*>(buffers + row_size * i +
544  sizeof(KeyT) * key_count);
545  value = val_buffer[v];
546  }
547 
548  switch (agg_ops_[v]) {
549  case OP_COUNT:
550  if (inserted) {
551  ++partial_res[keys][v];
552  } else {
553  partial_res[keys][v] = 1;
554  }
555  break;
556  case OP_SUM:
557  if (inserted) {
558  partial_res[keys][v] += value;
559  } else {
560  partial_res[keys][v] = value;
561  }
562  break;
563  case OP_MIN:
564  if (inserted) {
565  partial_res[keys][v] = std::min(partial_res[keys][v], value);
566  } else {
567  partial_res[keys][v] = value;
568  }
569  break;
570  case OP_MAX:
571  if (inserted) {
572  partial_res[keys][v] = std::max(partial_res[keys][v], value);
573  } else {
574  partial_res[keys][v] = value;
575  }
576  break;
577  default:
578  CHECK(false);
579  }
580  }
581  }
582  }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
T v(const TargetValue &r)
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:

Member Data Documentation

◆ agg_ops_

template<typename KeyT = int64_t, typename ValT = int64_t>
std::vector<OP_KIND> anonymous_namespace{ProfileTest.cpp}::AggregateEmulator< KeyT, ValT >::agg_ops_
private

Definition at line 638 of file ProfileTest.cpp.


The documentation for this class was generated from the following file: