Skip to content

Commit

Permalink
Making common sum implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
KiterLuc committed Aug 29, 2023
1 parent fa1a45f commit d6e6487
Show file tree
Hide file tree
Showing 17 changed files with 366 additions and 370 deletions.
1 change: 1 addition & 0 deletions tiledb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ set(TILEDB_CORE_SOURCES
${TILEDB_CORE_INCLUDE_DIR}/tiledb/sm/query/query.cc
${TILEDB_CORE_INCLUDE_DIR}/tiledb/sm/query/query_condition.cc
${TILEDB_CORE_INCLUDE_DIR}/tiledb/sm/query/query_remote_buffer_storage.cc
${TILEDB_CORE_INCLUDE_DIR}/tiledb/sm/query/readers/aggregators/aggregate_sum.cc
${TILEDB_CORE_INCLUDE_DIR}/tiledb/sm/query/readers/aggregators/count_aggregator.cc
${TILEDB_CORE_INCLUDE_DIR}/tiledb/sm/query/readers/aggregators/mean_aggregator.cc
${TILEDB_CORE_INCLUDE_DIR}/tiledb/sm/query/readers/aggregators/min_max_aggregator.cc
Expand Down
2 changes: 1 addition & 1 deletion tiledb/sm/query/readers/aggregators/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ include(object_library)
# `aggregators` object library
#
commence(object_library aggregators)
this_target_sources(count_aggregator.cc mean_aggregator.cc min_max_aggregator.cc sum_aggregator.cc)
this_target_sources(aggregate_sum.cc count_aggregator.cc mean_aggregator.cc min_max_aggregator.cc sum_aggregator.cc)
this_target_object_libraries(baseline array_schema)
conclude(object_library)

Expand Down
5 changes: 1 addition & 4 deletions tiledb/sm/query/readers/aggregators/aggregate_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@
#ifndef TILEDB_AGGREGATE_BUFFER_H
#define TILEDB_AGGREGATE_BUFFER_H

#include "tiledb/common/status.h"
#include "tiledb/sm/enums/layout.h"

using namespace tiledb::common;
#include "tiledb/common/common.h"

namespace tiledb {
namespace sm {
Expand Down
77 changes: 77 additions & 0 deletions tiledb/sm/query/readers/aggregators/aggregate_sum.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* @file aggregate_sum.cc
*
* @section LICENSE
*
* The MIT License
*
* @copyright Copyright (c) 2023 TileDB, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @section DESCRIPTION
*
* This file implements class AggregateSum.
*/

#include "tiledb/sm/query/readers/aggregators/aggregate_sum.h"

namespace tiledb {
namespace sm {

/** Specialization of safe_sum for int64_t sums. */
template <>
void safe_sum<int64_t>(int64_t value, int64_t& sum) {
if (sum > 0 && value > 0 &&
(sum > (std::numeric_limits<int64_t>::max() - value))) {
throw std::overflow_error("overflow on sum");
}

if (sum < 0 && value < 0 &&
(sum < (std::numeric_limits<int64_t>::min() - value))) {
throw std::overflow_error("overflow on sum");
}

sum += value;
}

/** Specialization of safe_sum for uint64_t sums. */
template <>
void safe_sum<uint64_t>(uint64_t value, uint64_t& sum) {
if (sum > (std::numeric_limits<uint64_t>::max() - value)) {
throw std::overflow_error("overflow on sum");
}

sum += value;
}

/** Specialization of safe_sum for double sums. */
template <>
void safe_sum<double>(double value, double& sum) {
if ((sum < 0.0) == (value < 0.0) &&
(std::abs(sum) >
(std::numeric_limits<double>::max() - std::abs(value)))) {
throw std::overflow_error("overflow on sum");
}

sum += value;
}

} // namespace sm
} // namespace tiledb
197 changes: 197 additions & 0 deletions tiledb/sm/query/readers/aggregators/aggregate_sum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/**
* @file aggregate_sum.h
*
* @section LICENSE
*
* The MIT License
*
* @copyright Copyright (c) 2023 TileDB, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @section DESCRIPTION
*
* This file defines class AggregateSum.
*/

#ifndef TILEDB_AGGREGATE_SUM_H
#define TILEDB_AGGREGATE_SUM_H

#include "tiledb/sm/query/readers/aggregators/aggregate_buffer.h"
#include "tiledb/sm/query/readers/aggregators/field_info.h"

namespace tiledb {
namespace sm {

#define SUM_TYPE_DATA(T, SUM_T) \
template <> \
struct sum_type_data<T> { \
using type = T; \
typedef SUM_T sum_type; \
};

/** Convert basic type to a sum type. **/
template <typename T>
struct sum_type_data;

SUM_TYPE_DATA(int8_t, int64_t);
SUM_TYPE_DATA(uint8_t, uint64_t);
SUM_TYPE_DATA(int16_t, int64_t);
SUM_TYPE_DATA(uint16_t, uint64_t);
SUM_TYPE_DATA(int32_t, int64_t);
SUM_TYPE_DATA(uint32_t, uint64_t);
SUM_TYPE_DATA(int64_t, int64_t);
SUM_TYPE_DATA(uint64_t, uint64_t);
SUM_TYPE_DATA(float, double);
SUM_TYPE_DATA(double, double);

/**
* Sum function that prevent wrap arounds on overflow.
*
* @param value Value to add to the sum.
* @param sum Computed sum.
*/
template <typename SUM_T>
void safe_sum(SUM_T value, SUM_T& sum);

/**
* Sum function for atomics that prevent wrap arounds on overflow.
*
* @param value Value to add to the sum.
* @param sum Computed sum.
*/
template <typename SUM_T>
void safe_sum(SUM_T value, std::atomic<SUM_T>& sum) {
SUM_T cur_sum = sum;
SUM_T new_sum;
do {
new_sum = cur_sum;
safe_sum(value, new_sum);
} while (!std::atomic_compare_exchange_weak(&sum, &cur_sum, new_sum));
}

template <typename T>
class AggregateSum {
public:
/* ********************************* */
/* CONSTRUCTORS & DESTRUCTORS */
/* ********************************* */

AggregateSum(const FieldInfo field_info)
: field_info_(field_info) {
}

/* ********************************* */
/* API */
/* ********************************* */

/**
* Add the sum of cells for the input data.
*
* @tparam SUM_T Sum type.
* @tparam BITMAP_T Bitmap type.
* @param input_data Input data for the sum.
*
* @return {Sum for the cells, number of cells, optional validity value}.
*/
template <typename SUM_T, typename BITMAP_T>
tuple<SUM_T, uint64_t, optional<uint8_t>> sum(AggregateBuffer& input_data) {
SUM_T sum{0};
uint64_t count{0};
optional<uint8_t> validity{nullopt};
auto values = input_data.fixed_data_as<T>();

// Run different loops for bitmap versus no bitmap and nullable versus non
// nullable. The bitmap tells us which cells was already filtered out by
// ranges or query conditions.
if (input_data.has_bitmap()) {
auto bitmap_values = input_data.bitmap_data_as<BITMAP_T>();

if (field_info_.is_nullable_) {
validity = 0;
auto validity_values = input_data.validity_data();

// Process for nullable sums with bitmap.
for (uint64_t c = input_data.min_cell(); c < input_data.max_cell();
c++) {
if (validity_values[c] != 0 && bitmap_values[c] != 0) {
validity = 1;

auto value = static_cast<SUM_T>(values[c]);
for (BITMAP_T i = 0; i < bitmap_values[c]; i++) {
count++;
safe_sum(value, sum);
}
}
}
} else {
// Process for non nullable sums with bitmap.
for (uint64_t c = input_data.min_cell(); c < input_data.max_cell();
c++) {
auto value = static_cast<SUM_T>(values[c]);

for (BITMAP_T i = 0; i < bitmap_values[c]; i++) {
count++;
safe_sum(value, sum);
}
}
}
} else {
if (field_info_.is_nullable_) {
validity = 0;
auto validity_values = input_data.validity_data();

// Process for nullable sums with no bitmap.
for (uint64_t c = input_data.min_cell(); c < input_data.max_cell();
c++) {
if (validity_values[c] != 0) {
validity = 1;

auto value = static_cast<SUM_T>(values[c]);
count++;
safe_sum(value, sum);
}
}
} else {
// Process for non nullable sums with no bitmap.
for (uint64_t c = input_data.min_cell(); c < input_data.max_cell();
c++) {
auto value = static_cast<SUM_T>(values[c]);
count++;
safe_sum(value, sum);
}
}
}

return {sum, count, validity};
}

private:
/* ********************************* */
/* PRIVATE ATTRIBUTES */
/* ********************************* */

/** Field information. */
const FieldInfo field_info_;
};

} // namespace sm
} // namespace tiledb

#endif // TILEDB_AGGREGATE_SUM_H
2 changes: 0 additions & 2 deletions tiledb/sm/query/readers/aggregators/count_aggregator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
#include "tiledb/sm/query/query_buffer.h"
#include "tiledb/sm/query/readers/aggregators/aggregate_buffer.h"

using namespace tiledb::common;

namespace tiledb {
namespace sm {

Expand Down
5 changes: 1 addition & 4 deletions tiledb/sm/query/readers/aggregators/count_aggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,9 @@
#ifndef TILEDB_COUNT_AGGREGATOR_H
#define TILEDB_COUNT_AGGREGATOR_H

#include "tiledb/common/status.h"
#include "tiledb/sm/enums/layout.h"
#include "tiledb/common/common.h"
#include "tiledb/sm/query/readers/aggregators/iaggregator.h"

using namespace tiledb::common;

namespace tiledb {
namespace sm {

Expand Down
5 changes: 1 addition & 4 deletions tiledb/sm/query/readers/aggregators/field_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@
#ifndef TILEDB_FIELD_INFO_H
#define TILEDB_FIELD_INFO_H

#include "tiledb/common/status.h"
#include "tiledb/sm/enums/layout.h"

using namespace tiledb::common;
#include "tiledb/common/common.h"

namespace tiledb {
namespace sm {
Expand Down
6 changes: 2 additions & 4 deletions tiledb/sm/query/readers/aggregators/iaggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@
#ifndef TILEDB_IAGGREGATOR_H
#define TILEDB_IAGGREGATOR_H

#include "tiledb/common/status.h"
#include "tiledb/sm/enums/layout.h"

using namespace tiledb::common;
#include "tiledb/common/common.h"
#include "tiledb/sm/misc/constants.h"

namespace tiledb {
namespace sm {
Expand Down
Loading

0 comments on commit d6e6487

Please sign in to comment.