OmniSciDB  c1a53651b2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TableFunctionsCommon.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __CUDACC__
18 
19 #include "TableFunctionsCommon.hpp"
20 
21 #include <filesystem>
22 #include <memory>
23 #include <regex>
24 #include <string>
25 
26 #include <tbb/parallel_for.h>
27 #include <tbb/task_arena.h>
28 
29 #define NANOSECONDS_PER_SECOND 1000000000
30 
31 template <typename T>
32 NEVER_INLINE HOST std::pair<T, T> get_column_min_max(const Column<T>& col) {
33  T col_min = std::numeric_limits<T>::max();
34  T col_max = std::numeric_limits<T>::lowest();
35  const int64_t num_rows = col.size();
36  const size_t max_thread_count = std::thread::hardware_concurrency();
37  const size_t max_inputs_per_thread = 20000;
38  const size_t num_threads = std::min(
39  max_thread_count, ((num_rows + max_inputs_per_thread - 1) / max_inputs_per_thread));
40 
41  std::vector<T> local_col_mins(num_threads, std::numeric_limits<T>::max());
42  std::vector<T> local_col_maxes(num_threads, std::numeric_limits<T>::lowest());
43  tbb::task_arena limited_arena(num_threads);
44 
45  limited_arena.execute([&] {
46  tbb::parallel_for(tbb::blocked_range<int64_t>(0, num_rows),
47  [&](const tbb::blocked_range<int64_t>& r) {
48  const int64_t start_idx = r.begin();
49  const int64_t end_idx = r.end();
50  T local_col_min = std::numeric_limits<T>::max();
51  T local_col_max = std::numeric_limits<T>::lowest();
52  for (int64_t r = start_idx; r < end_idx; ++r) {
53  const T val = col[r];
54  if (val == inline_null_value<T>()) {
55  continue;
56  }
57  if (val < local_col_min) {
58  local_col_min = val;
59  }
60  if (val > local_col_max) {
61  local_col_max = val;
62  }
63  }
64  size_t thread_idx = tbb::this_task_arena::current_thread_index();
65  if (local_col_min < local_col_mins[thread_idx]) {
66  local_col_mins[thread_idx] = local_col_min;
67  }
68  if (local_col_max > local_col_maxes[thread_idx]) {
69  local_col_maxes[thread_idx] = local_col_max;
70  }
71  });
72  });
73 
74  for (size_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
75  if (local_col_mins[thread_idx] < col_min) {
76  col_min = local_col_mins[thread_idx];
77  }
78  if (local_col_maxes[thread_idx] > col_max) {
79  col_max = local_col_maxes[thread_idx];
80  }
81  }
82  return std::make_pair(col_min, col_max);
83 }
84 
85 template NEVER_INLINE HOST std::pair<int8_t, int8_t> get_column_min_max(
86  const Column<int8_t>& col);
87 template NEVER_INLINE HOST std::pair<int16_t, int16_t> get_column_min_max(
88  const Column<int16_t>& col);
89 template NEVER_INLINE HOST std::pair<int32_t, int32_t> get_column_min_max(
90  const Column<int32_t>& col);
91 template NEVER_INLINE HOST std::pair<int64_t, int64_t> get_column_min_max(
92  const Column<int64_t>& col);
93 template NEVER_INLINE HOST std::pair<float, float> get_column_min_max(
94  const Column<float>& col);
95 template NEVER_INLINE HOST std::pair<double, double> get_column_min_max(
96  const Column<double>& col);
97 
98 std::pair<int32_t, int32_t> get_column_min_max(const Column<TextEncodingDict>& col) {
99  Column<int32_t> int_alias_col(reinterpret_cast<int32_t*>(col.getPtr()), col.size());
100  return get_column_min_max(int_alias_col);
101 }
102 
103 // Todo(todd): we should use a functor approach for gathering whatever stats
104 // a table function needs so we're not repeating boilerplate code (although
105 // should confirm it doesn't have an adverse affect on performance).
106 // Leaving as a follow-up though until we have more examples of real-world
107 // usage patterns.
108 
109 template <typename T>
110 NEVER_INLINE HOST double get_column_mean(const T* data, const int64_t num_rows) {
111  // const int64_t num_rows = col.size();
112  const size_t max_thread_count = std::thread::hardware_concurrency();
113  const size_t max_inputs_per_thread = 20000;
114  const size_t num_threads = std::min(
115  max_thread_count, ((num_rows + max_inputs_per_thread - 1) / max_inputs_per_thread));
116 
117  std::vector<double> local_col_sums(num_threads, 0.);
118  std::vector<int64_t> local_col_non_null_counts(num_threads, 0L);
119  tbb::task_arena limited_arena(num_threads);
120  limited_arena.execute([&] {
121  tbb::parallel_for(tbb::blocked_range<int64_t>(0, num_rows),
122  [&](const tbb::blocked_range<int64_t>& r) {
123  const int64_t start_idx = r.begin();
124  const int64_t end_idx = r.end();
125  double local_col_sum = 0.;
126  int64_t local_col_non_null_count = 0;
127  for (int64_t r = start_idx; r < end_idx; ++r) {
128  const T val = data[r];
129  if (val == inline_null_value<T>()) {
130  continue;
131  }
132  local_col_sum += data[r];
133  local_col_non_null_count++;
134  }
135  size_t thread_idx = tbb::this_task_arena::current_thread_index();
136  local_col_sums[thread_idx] += local_col_sum;
137  local_col_non_null_counts[thread_idx] += local_col_non_null_count;
138  });
139  });
140 
141  double col_sum = 0.0;
142  int64_t col_non_null_count = 0L;
143 
144  for (size_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
145  col_sum += local_col_sums[thread_idx];
146  col_non_null_count += local_col_non_null_counts[thread_idx];
147  }
148 
149  return col_non_null_count == 0 ? 0 : col_sum / col_non_null_count;
150 }
151 
152 template NEVER_INLINE HOST double get_column_mean(const int8_t* data,
153  const int64_t num_rows);
154 
155 template NEVER_INLINE HOST double get_column_mean(const int16_t* data,
156  const int64_t num_rows);
157 
158 template NEVER_INLINE HOST double get_column_mean(const int32_t* data,
159  const int64_t num_rows);
160 
161 template NEVER_INLINE HOST double get_column_mean(const int64_t* data,
162  const int64_t num_rows);
163 
164 template NEVER_INLINE HOST double get_column_mean(const float* data,
165  const int64_t num_rows);
166 
167 template NEVER_INLINE HOST double get_column_mean(const double* data,
168  const int64_t num_rows);
169 
170 template <typename T>
172  return get_column_mean(col.getPtr(), col.size());
173 }
174 
175 template NEVER_INLINE HOST double get_column_mean(const Column<int8_t>& col);
176 template NEVER_INLINE HOST double get_column_mean(const Column<int16_t>& col);
177 template NEVER_INLINE HOST double get_column_mean(const Column<int32_t>& col);
178 template NEVER_INLINE HOST double get_column_mean(const Column<int64_t>& col);
179 template NEVER_INLINE HOST double get_column_mean(const Column<float>& col);
180 template NEVER_INLINE HOST double get_column_mean(const Column<double>& col);
181 
182 template <typename T>
183 NEVER_INLINE HOST double get_column_std_dev(const Column<T>& col, const double mean) {
184  return get_column_std_dev(col.getPtr(), col.size(), mean);
185 }
186 
187 template NEVER_INLINE HOST double get_column_std_dev(const Column<int32_t>& col,
188  const double mean);
189 template NEVER_INLINE HOST double get_column_std_dev(const Column<int64_t>& col,
190  const double mean);
191 template NEVER_INLINE HOST double get_column_std_dev(const Column<float>& col,
192  const double mean);
193 template NEVER_INLINE HOST double get_column_std_dev(const Column<double>& col,
194  const double mean);
195 
196 template <typename T>
198  const int64_t num_rows,
199  const double mean) {
200  // const int64_t num_rows = col.size();
201  const size_t max_thread_count = std::thread::hardware_concurrency();
202  const size_t max_inputs_per_thread = 200000;
203  const size_t num_threads = std::min(
204  max_thread_count, ((num_rows + max_inputs_per_thread - 1) / max_inputs_per_thread));
205 
206  std::vector<double> local_col_squared_residuals(num_threads, 0.);
207  std::vector<int64_t> local_col_non_null_counts(num_threads, 0L);
208  tbb::task_arena limited_arena(num_threads);
209 
210  limited_arena.execute([&] {
211  tbb::parallel_for(tbb::blocked_range<int64_t>(0, num_rows),
212  [&](const tbb::blocked_range<int64_t>& r) {
213  const int64_t start_idx = r.begin();
214  const int64_t end_idx = r.end();
215  double local_col_squared_residual = 0.;
216  int64_t local_col_non_null_count = 0;
217  for (int64_t r = start_idx; r < end_idx; ++r) {
218  const T val = data[r];
219  if (val == inline_null_value<T>()) {
220  continue;
221  }
222  const double residual = val - mean;
223  local_col_squared_residual += (residual * residual);
224  local_col_non_null_count++;
225  }
226  size_t thread_idx = tbb::this_task_arena::current_thread_index();
227  local_col_squared_residuals[thread_idx] +=
228  local_col_squared_residual;
229  local_col_non_null_counts[thread_idx] += local_col_non_null_count;
230  });
231  });
232 
233  double col_sum_squared_residual = 0.0;
234  int64_t col_non_null_count = 0;
235 
236  for (size_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
237  col_sum_squared_residual += local_col_squared_residuals[thread_idx];
238  col_non_null_count += local_col_non_null_counts[thread_idx];
239  }
240 
241  return col_non_null_count == 0 ? 0
242  : sqrt(col_sum_squared_residual / col_non_null_count);
243 }
244 
245 template NEVER_INLINE HOST double get_column_std_dev(const int32_t* data,
246  const int64_t num_rows,
247  const double mean);
248 template NEVER_INLINE HOST double get_column_std_dev(const int64_t* data,
249  const int64_t num_rows,
250  const double mean);
251 template NEVER_INLINE HOST double get_column_std_dev(const float* data,
252  const int64_t num_rows,
253  const double mean);
254 template NEVER_INLINE HOST double get_column_std_dev(const double* data,
255  const int64_t num_rows,
256  const double mean);
257 
258 template <typename T>
259 NEVER_INLINE HOST std::tuple<T, T, bool> get_column_metadata(const Column<T>& col) {
260  T col_min = std::numeric_limits<T>::max();
261  T col_max = std::numeric_limits<T>::lowest();
262  bool has_nulls = false;
263  const int64_t num_rows = col.size();
264  const size_t max_thread_count = std::thread::hardware_concurrency();
265  const size_t max_inputs_per_thread = 200000;
266  const size_t num_threads = std::min(
267  max_thread_count, ((num_rows + max_inputs_per_thread - 1) / max_inputs_per_thread));
268 
269  std::vector<T> local_col_mins(num_threads, std::numeric_limits<T>::max());
270  std::vector<T> local_col_maxes(num_threads, std::numeric_limits<T>::lowest());
271  std::vector<bool> local_col_has_nulls(num_threads, false);
272  tbb::task_arena limited_arena(num_threads);
273 
274  limited_arena.execute([&] {
275  tbb::parallel_for(tbb::blocked_range<int64_t>(0, num_rows),
276  [&](const tbb::blocked_range<int64_t>& r) {
277  const int64_t start_idx = r.begin();
278  const int64_t end_idx = r.end();
279  T local_col_min = std::numeric_limits<T>::max();
280  T local_col_max = std::numeric_limits<T>::lowest();
281  bool local_has_nulls = false;
282  for (int64_t r = start_idx; r < end_idx; ++r) {
283  if (col.isNull(r)) {
284  local_has_nulls = true;
285  continue;
286  }
287  if (col[r] < local_col_min) {
288  local_col_min = col[r];
289  }
290  if (col[r] > local_col_max) {
291  local_col_max = col[r];
292  }
293  }
294  const size_t thread_idx =
295  tbb::this_task_arena::current_thread_index();
296  if (local_has_nulls) {
297  local_col_has_nulls[thread_idx] = true;
298  }
299  if (local_col_min < local_col_mins[thread_idx]) {
300  local_col_mins[thread_idx] = local_col_min;
301  }
302  if (local_col_max > local_col_maxes[thread_idx]) {
303  local_col_maxes[thread_idx] = local_col_max;
304  }
305  });
306  });
307 
308  for (size_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
309  if (local_col_has_nulls[thread_idx]) {
310  has_nulls = true;
311  }
312  if (local_col_mins[thread_idx] < col_min) {
313  col_min = local_col_mins[thread_idx];
314  }
315  if (local_col_maxes[thread_idx] > col_max) {
316  col_max = local_col_maxes[thread_idx];
317  }
318  }
319  return {col_min, col_max, has_nulls};
320 }
321 
322 template NEVER_INLINE HOST std::tuple<int8_t, int8_t, bool> get_column_metadata(
323  const Column<int8_t>& col);
324 template NEVER_INLINE HOST std::tuple<int16_t, int16_t, bool> get_column_metadata(
325  const Column<int16_t>& col);
326 template NEVER_INLINE HOST std::tuple<int32_t, int32_t, bool> get_column_metadata(
327  const Column<int32_t>& col);
328 template NEVER_INLINE HOST std::tuple<int64_t, int64_t, bool> get_column_metadata(
329  const Column<int64_t>& col);
330 template NEVER_INLINE HOST std::tuple<float, float, bool> get_column_metadata(
331  const Column<float>& col);
332 template NEVER_INLINE HOST std::tuple<double, double, bool> get_column_metadata(
333  const Column<double>& col);
334 
335 std::tuple<int32_t, int32_t, bool> get_column_metadata(
336  const Column<TextEncodingDict>& col) {
337  Column<int32_t> int_alias_col(reinterpret_cast<int32_t*>(col.getPtr()), col.size());
338  return get_column_metadata(int_alias_col);
339 }
340 
341 template <typename T>
342 void z_std_normalize_col(const T* input_data,
343  T* output_data,
344  const int64_t num_rows,
345  const double mean,
346  const double std_dev) {
347  if (std_dev <= 0.0) {
348  throw std::runtime_error("Standard deviation cannot be <= 0");
349  }
350  const double inv_std_dev = 1.0 / std_dev;
351 
352  tbb::parallel_for(tbb::blocked_range<int64_t>(0, num_rows),
353  [&](const tbb::blocked_range<int64_t>& r) {
354  const int64_t start_idx = r.begin();
355  const int64_t end_idx = r.end();
356  for (int64_t row_idx = start_idx; row_idx < end_idx; ++row_idx) {
357  output_data[row_idx] = (input_data[row_idx] - mean) * inv_std_dev;
358  }
359  });
360 }
361 
362 template void z_std_normalize_col(const float* input_data,
363  float* output_data,
364  const int64_t num_rows,
365  const double mean,
366  const double std_dev);
367 template void z_std_normalize_col(const double* input_data,
368  double* output_data,
369  const int64_t num_rows,
370  const double mean,
371  const double std_dev);
372 
373 template <typename T>
374 std::vector<std::vector<T>> z_std_normalize_data(const std::vector<T*>& input_data,
375  const int64_t num_rows) {
376  const int64_t num_features = input_data.size();
377  std::vector<std::vector<T>> normalized_data(num_features);
378  for (int64_t feature_idx = 0; feature_idx < num_features; ++feature_idx) {
379  const auto mean = get_column_mean(input_data[feature_idx], num_rows);
380  const auto std_dev = get_column_std_dev(input_data[feature_idx], num_rows, mean);
381  normalized_data[feature_idx].resize(num_rows);
382  z_std_normalize_col(input_data[feature_idx],
383  normalized_data[feature_idx].data(),
384  num_rows,
385  mean,
386  std_dev);
387  }
388  return normalized_data;
389 }
390 
391 template std::vector<std::vector<float>> z_std_normalize_data(
392  const std::vector<float*>& input_data,
393  const int64_t num_rows);
394 template std::vector<std::vector<double>> z_std_normalize_data(
395  const std::vector<double*>& input_data,
396  const int64_t num_rows);
397 
398 template <typename T1, typename T2>
400 distance_in_meters(const T1 fromlon, const T1 fromlat, const T2 tolon, const T2 tolat) {
401  T1 latitudeArc = (fromlat - tolat) * 0.017453292519943295769236907684886;
402  T1 longitudeArc = (fromlon - tolon) * 0.017453292519943295769236907684886;
403  T1 latitudeH = sin(latitudeArc * 0.5);
404  latitudeH *= latitudeH;
405  T1 lontitudeH = sin(longitudeArc * 0.5);
406  lontitudeH *= lontitudeH;
407  T1 tmp = cos(fromlat * 0.017453292519943295769236907684886) *
408  cos(tolat * 0.017453292519943295769236907684886);
409  return 6372797.560856 * (2.0 * asin(sqrt(latitudeH + tmp * lontitudeH)));
410 }
411 
412 template NEVER_INLINE HOST float distance_in_meters(const float fromlon,
413  const float fromlat,
414  const float tolon,
415  const float tolat);
416 
417 template NEVER_INLINE HOST float distance_in_meters(const float fromlon,
418  const float fromlat,
419  const double tolon,
420  const double tolat);
421 
422 template NEVER_INLINE HOST double distance_in_meters(const double fromlon,
423  const double fromlat,
424  const float tolon,
425  const float tolat);
426 
427 template NEVER_INLINE HOST double distance_in_meters(const double fromlon,
428  const double fromlat,
429  const double tolon,
430  const double tolat);
431 
432 namespace FileUtilities {
433 
434 // Following implementation taken from https://stackoverflow.com/a/65851545
435 
436 std::regex glob_to_regex(const std::string& glob, bool case_sensitive = false) {
437  // Note It is possible to automate checking if filesystem is case sensitive or not (e.g.
438  // by performing a test first time this function is ran)
439  std::string regex_string{glob};
440  // Escape all regex special chars:
441  regex_string = std::regex_replace(regex_string, std::regex("\\\\"), "\\\\");
442  regex_string = std::regex_replace(regex_string, std::regex("\\^"), "\\^");
443  regex_string = std::regex_replace(regex_string, std::regex("\\."), "\\.");
444  regex_string = std::regex_replace(regex_string, std::regex("\\$"), "\\$");
445  regex_string = std::regex_replace(regex_string, std::regex("\\|"), "\\|");
446  regex_string = std::regex_replace(regex_string, std::regex("\\("), "\\(");
447  regex_string = std::regex_replace(regex_string, std::regex("\\)"), "\\)");
448  regex_string = std::regex_replace(regex_string, std::regex("\\{"), "\\{");
449  regex_string = std::regex_replace(regex_string, std::regex("\\{"), "\\}");
450  regex_string = std::regex_replace(regex_string, std::regex("\\["), "\\[");
451  regex_string = std::regex_replace(regex_string, std::regex("\\]"), "\\]");
452  regex_string = std::regex_replace(regex_string, std::regex("\\+"), "\\+");
453  regex_string = std::regex_replace(regex_string, std::regex("\\/"), "\\/");
454  // Convert wildcard specific chars '*?' to their regex equivalents:
455  regex_string = std::regex_replace(regex_string, std::regex("\\?"), ".");
456  regex_string = std::regex_replace(regex_string, std::regex("\\*"), ".*");
457 
458  return std::regex(
459  regex_string,
460  case_sensitive ? std::regex_constants::ECMAScript : std::regex_constants::icase);
461 }
462 
463 std::vector<std::filesystem::path> get_fs_paths(const std::string& file_or_directory) {
464  const std::filesystem::path file_or_directory_path(file_or_directory);
465  const auto file_status = std::filesystem::status(file_or_directory_path);
466 
467  std::vector<std::filesystem::path> fs_paths;
468  if (std::filesystem::is_regular_file(file_status)) {
469  fs_paths.emplace_back(file_or_directory_path);
470  return fs_paths;
471  } else if (std::filesystem::is_directory(file_status)) {
472  for (std::filesystem::directory_entry const& entry :
473  std::filesystem::directory_iterator(file_or_directory_path)) {
474  if (std::filesystem::is_regular_file(std::filesystem::status(entry))) {
475  fs_paths.emplace_back(entry.path());
476  }
477  }
478  return fs_paths;
479  } else {
480  const auto parent_path = file_or_directory_path.parent_path();
481  const auto parent_status = std::filesystem::status(parent_path);
482  if (std::filesystem::is_directory(parent_status)) {
483  const auto file_glob = file_or_directory_path.filename();
484  const std::regex glob_regex{glob_to_regex(file_glob.string(), false)};
485 
486  for (std::filesystem::directory_entry const& entry :
487  std::filesystem::directory_iterator(parent_path)) {
488  if (std::filesystem::is_regular_file(std::filesystem::status(entry))) {
489  const auto entry_filename = entry.path().filename().string();
490  if (std::regex_match(entry_filename, glob_regex)) {
491  fs_paths.emplace_back(entry.path());
492  }
493  }
494  }
495  return fs_paths;
496  }
497  }
498  return fs_paths;
499 }
500 
501 } // namespace FileUtilities
502 
503 template <typename T>
505  const T bounds_val,
506  const BoundsType bounds_type,
507  const IntervalType interval_type) {
508  switch (bounds_type) {
509  case BoundsType::Min:
510  switch (interval_type) {
512  return input >= bounds_val;
514  return input > bounds_val;
515  default:
516  UNREACHABLE();
517  }
518  case BoundsType::Max:
519  switch (interval_type) {
521  return input <= bounds_val;
523  return input < bounds_val;
524  default:
525  UNREACHABLE();
526  }
527  break;
528  default:
529  UNREACHABLE();
530  }
531  UNREACHABLE();
532  return false; // To address compiler warning
533 }
534 
535 template NEVER_INLINE HOST bool is_valid_tf_input(const int32_t input,
536  const int32_t bounds_val,
537  const BoundsType bounds_type,
538  const IntervalType interval_type);
539 
540 template NEVER_INLINE HOST bool is_valid_tf_input(const int64_t input,
541  const int64_t bounds_val,
542  const BoundsType bounds_type,
543  const IntervalType interval_type);
544 
545 template NEVER_INLINE HOST bool is_valid_tf_input(const float input,
546  const float bounds_val,
547  const BoundsType bounds_type,
548  const IntervalType interval_type);
549 
550 template NEVER_INLINE HOST bool is_valid_tf_input(const double input,
551  const double bounds_val,
552  const BoundsType bounds_type,
553  const IntervalType interval_type);
554 
555 #endif // #ifndef __CUDACC__
std::regex glob_to_regex(const std::string &glob, bool case_sensitive=false)
NEVER_INLINE HOST std::pair< T, T > get_column_min_max(const Column< T > &col)
DEVICE int64_t size() const
Definition: heavydbTypes.h:751
#define UNREACHABLE()
Definition: Logger.h:337
DEVICE T * getPtr() const
Definition: heavydbTypes.h:750
void z_std_normalize_col(const T *input_data, T *output_data, const int64_t num_rows, const double mean, const double std_dev)
std::vector< std::filesystem::path > get_fs_paths(const std::string &file_or_directory)
const size_t max_inputs_per_thread
#define HOST
DEVICE TextEncodingDict * getPtr() const
Definition: heavydbTypes.h:949
DEVICE bool isNull(int64_t index) const
Definition: heavydbTypes.h:754
void parallel_for(const blocked_range< Int > &range, const Body &body, const Partitioner &p=Partitioner())
EXTENSION_NOINLINE double distance_in_meters(const double fromlon, const double fromlat, const double tolon, const double tolat)
Computes the distance, in meters, between two WGS-84 positions.
#define NEVER_INLINE
NEVER_INLINE HOST std::tuple< T, T, bool > get_column_metadata(const Column< T > &col)
std::vector< std::vector< T > > z_std_normalize_data(const std::vector< T * > &input_data, const int64_t num_rows)
NEVER_INLINE HOST double get_column_std_dev(const Column< T > &col, const double mean)
DEVICE int64_t size() const
Definition: heavydbTypes.h:950
std::vector< std::string > glob(const std::string &pattern)
NEVER_INLINE HOST bool is_valid_tf_input(const T input, const T bounds_val, const BoundsType bounds_type, const IntervalType interval_type)
NEVER_INLINE HOST double get_column_mean(const T *data, const int64_t num_rows)