This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push:
new 70cfd9907d [REFACTOR][S-TIR] Minimize src/support/ by relocating
s_tir-private headers (#19460)
70cfd9907d is described below
commit 70cfd9907d12dbffe540e56dec9fa3d715abdb97
Author: Tianqi Chen <[email protected]>
AuthorDate: Mon Apr 27 17:37:42 2026 -0400
[REFACTOR][S-TIR] Minimize src/support/ by relocating s_tir-private headers
(#19460)
---
include/tvm/support/parallel_for.h | 93 ----------
src/ir/expr.cc | 4 +-
src/relax/analysis/layout_transformation.cc | 19 +-
src/relax/transform/utils.h | 6 +-
src/runtime/minrpc/minrpc_server.h | 2 +-
.../schedule_rule/multi_level_tiling.h | 2 +-
src/s_tir/meta_schedule/utils.h | 8 +-
src/s_tir/schedule/utils.h | 4 +-
.../array.h => s_tir/support/array_utils.h} | 6 +-
src/{ => s_tir}/support/nd_int_set.h | 6 +-
.../support/parallel_for.h} | 72 +++++++-
src/{ => s_tir}/support/table_printer.h | 6 +-
src/s_tir/transform/compact_buffer_region.cc | 2 +-
src/support/arena.h | 151 +++++++++++++++-
src/support/generic_arena.h | 183 --------------------
src/support/hexdump.h | 82 ---------
src/support/{scalars.h => limits.h} | 37 +---
src/support/scalars.cc | 192 ---------------------
src/te/operation/create_primfunc.cc | 1 -
tests/cpp/parallel_for_test.cc | 159 -----------------
tests/cpp/support_test.cc | 19 --
21 files changed, 256 insertions(+), 798 deletions(-)
diff --git a/include/tvm/support/parallel_for.h
b/include/tvm/support/parallel_for.h
deleted file mode 100644
index aa9da30d8f..0000000000
--- a/include/tvm/support/parallel_for.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * \file parallel_for.h
- * \brief An implementation to run loop in parallel.
- */
-#ifndef TVM_SUPPORT_PARALLEL_FOR_H_
-#define TVM_SUPPORT_PARALLEL_FOR_H_
-
-#include <tvm/runtime/base.h>
-
-#include <functional>
-#include <vector>
-
-namespace tvm {
-namespace support {
-
-using PartitionerFuncType = std::function<std::vector<std::vector<int>>(int,
int, int, int)>;
-
-/*!
- * \brief A partitioner to split the task to each thread in Round-robin manner.
- * \param begin The start index of this parallel loop(inclusive).
- * \param end The end index of this parallel loop(exclusive).
- * \param step The traversal step to the index.
- * \param num_threads The number of threads(the number of tasks to be
partitioned to).
- * \return A list with `num_threads` elements, and each is a list of integers
indicating the loop
- * indexes for the corresponding thread to process.
- */
-TVM_DLL std::vector<std::vector<int>> rr_partitioner(int begin, int end, int
step, int num_threads);
-
-/*!
- * \brief A runtime api provided to run the task function in parallel.
- * e.g. A for loop:
- * for (int i = 0; i < 10; i++) {
- * a[i] = i;
- * }
- * should work the same as:
- * parallel_for(0, 10, [&a](int index) {
- * a[i] = i;
- * });
- * \param begin The start index of this parallel loop(inclusive).
- * \param end The end index of this parallel loop(exclusive).
- * \param f The task function to be executed. Assert to take an int index as
input with no output.
- * \param step The traversal step to the index.
- * \param partitioner A partition function to split tasks to different
threads. Use Round-robin
- * partitioner by default.
- * \note 1. Currently do not support nested parallel_for; 2. The order of
execution in each thread
- * is not guaranteed, the for loop task should be thread independent and
thread safe.
- */
-TVM_DLL void parallel_for(int begin, int end, const std::function<void(int)>&
f, int step = 1,
- const PartitionerFuncType partitioner =
rr_partitioner);
-
-/*!
- * \brief An API to launch fix amount of threads to run the specific functor
in parallel.
- * Different from `parallel_for`, the partition is determined dynamically on
the fly,
- * i.e. any time when a thread is idle, it fetches the next task to run.
- * The behavior is similar to dynamic scheduling in OpenMP:
- *
- * \#pragma omp parallel for schedule(dynamic) num_threads(num_threads)
- * for (int i = 0; i < 10; i++) {
- * a[i] = i;
- * }
- *
- * \param begin The start index of this parallel loop (inclusive).
- * \param end The end index of this parallel loop (exclusive).
- * \param num_threads The number of threads to be used.
- * \param f The task function to be executed. Takes the thread index and the
task index as
- * input with no output.
- * \note `step` support is left for future work.
- */
-TVM_DLL void parallel_for_dynamic(int begin, int end, int num_threads,
- const std::function<void(int thread_id, int
task_id)>& f);
-} // namespace support
-} // namespace tvm
-
-#endif // TVM_SUPPORT_PARALLEL_FOR_H_
diff --git a/src/ir/expr.cc b/src/ir/expr.cc
index b5cc09e11d..3dac9204c0 100644
--- a/src/ir/expr.cc
+++ b/src/ir/expr.cc
@@ -29,7 +29,9 @@
#include <tvm/te/tensor.h>
#include <tvm/tirx/expr.h>
-#include "../support/scalars.h"
+#include <cmath>
+
+#include "../support/limits.h"
namespace tvm {
diff --git a/src/relax/analysis/layout_transformation.cc
b/src/relax/analysis/layout_transformation.cc
index 307ce09d0f..cbc1a15331 100644
--- a/src/relax/analysis/layout_transformation.cc
+++ b/src/relax/analysis/layout_transformation.cc
@@ -30,8 +30,6 @@
#include <tvm/tirx/index_map.h>
#include <tvm/tirx/stmt_functor.h>
-#include "../../support/array.h"
-
namespace tvm {
namespace relax {
@@ -217,8 +215,10 @@ static ffi::Optional<IndexMap>
InferLayoutTransformation(const SpatialLayout& sr
const IndexMap&
src_transformation,
const SpatialLayout&
tgt_spatial_layout) {
// Copy over the src transformation intial and final indices
- auto initial_indices = support::AsList(src_transformation->initial_indices);
- auto final_indices = support::AsList(src_transformation->final_indices);
+ std::vector<tirx::Var>
initial_indices(src_transformation->initial_indices.begin(),
+
src_transformation->initial_indices.end());
+ std::vector<PrimExpr>
final_indices(src_transformation->final_indices.begin(),
+ src_transformation->final_indices.end());
// Get the iterator var set used in target spatial layout.
VarSet tgt_var_set;
@@ -297,11 +297,16 @@ static ffi::Optional<IndexMap>
InferLayoutTransformation(const SpatialLayout& sr
}
auto new_dim = tirx::Var("d");
- initial_indices.insert(initial_indices_it, new_dim);
- final_indices.insert(final_indices_it, new_dim);
+ initial_indices_it = initial_indices.insert(initial_indices_it, new_dim);
+ final_indices_it = final_indices.insert(final_indices_it, new_dim);
+ // Advance past the newly inserted element so subsequent iterations start
correctly.
+ initial_indices_it++;
+ final_indices_it++;
}
- return IndexMap(support::AsArray(initial_indices),
support::AsArray(final_indices));
+ ffi::Array<tirx::Var> initial_array(initial_indices.begin(),
initial_indices.end());
+ ffi::Array<PrimExpr> final_array(final_indices.begin(), final_indices.end());
+ return IndexMap(initial_array, final_array);
}
/*!
diff --git a/src/relax/transform/utils.h b/src/relax/transform/utils.h
index 2eef6c92cd..4e1084dd4c 100644
--- a/src/relax/transform/utils.h
+++ b/src/relax/transform/utils.h
@@ -36,7 +36,6 @@
#include <utility>
#include <vector>
-#include "../../support/array.h"
#include "../analysis/graph_partitioner.h"
#include "../op/nn/convolution.h"
#include "../op/nn/nn.h"
@@ -375,7 +374,10 @@ inline ffi::Array<Integer> GetOrderedPositiveAxes(const
ffi::Array<Integer>& axe
ret.push_back(axis_val);
}
std::sort(ret.begin(), ret.end());
- return support::AsArray<int64_t, Integer>(ret);
+ ffi::Array<Integer> result;
+ result.reserve(ret.size());
+ for (int64_t x : ret) result.push_back(Integer(x));
+ return result;
}
inline ffi::String GetCodegenName(const std::string& composite_name) {
diff --git a/src/runtime/minrpc/minrpc_server.h
b/src/runtime/minrpc/minrpc_server.h
index ccfd3d0792..434c88b693 100644
--- a/src/runtime/minrpc/minrpc_server.h
+++ b/src/runtime/minrpc/minrpc_server.h
@@ -37,7 +37,7 @@
#include <memory>
#include <utility>
-#include "../../support/generic_arena.h"
+#include "../../support/arena.h"
#include "rpc_reference.h"
namespace tvm {
diff --git a/src/s_tir/meta_schedule/schedule_rule/multi_level_tiling.h
b/src/s_tir/meta_schedule/schedule_rule/multi_level_tiling.h
index 0b52cf2dfb..8c2b2f04ea 100644
--- a/src/s_tir/meta_schedule/schedule_rule/multi_level_tiling.h
+++ b/src/s_tir/meta_schedule/schedule_rule/multi_level_tiling.h
@@ -27,7 +27,7 @@
#include <utility>
#include <vector>
-#include "../../../support/array.h"
+#include "../../support/array_utils.h"
namespace tvm {
namespace s_tir {
diff --git a/src/s_tir/meta_schedule/utils.h b/src/s_tir/meta_schedule/utils.h
index a7804361eb..ec2ece6713 100644
--- a/src/s_tir/meta_schedule/utils.h
+++ b/src/s_tir/meta_schedule/utils.h
@@ -41,7 +41,6 @@
#include <tvm/s_tir/meta_schedule/tune_context.h>
#include <tvm/s_tir/schedule/schedule.h>
#include <tvm/support/io.h>
-#include <tvm/support/parallel_for.h>
#include <tvm/support/serializer.h>
#include <tvm/tirx/transform.h>
@@ -52,14 +51,15 @@
#include <utility>
#include <vector>
-#include "../../support/array.h"
#include "../../support/base64.h"
#include "../../support/bytes_io.h"
-#include "../../support/nd_int_set.h"
-#include "../../support/table_printer.h"
#include "../../support/utils.h"
#include "../schedule/primitive.h"
#include "../schedule/utils.h"
+#include "../support/array_utils.h"
+#include "../support/nd_int_set.h"
+#include "../support/parallel_for.h"
+#include "../support/table_printer.h"
#define TVM_PY_LOG(logging_level, logger)
\
::tvm::s_tir::meta_schedule::PyLogMessage(__FILE__, __LINE__, logger,
\
diff --git a/src/s_tir/schedule/utils.h b/src/s_tir/schedule/utils.h
index 4026694df1..023c539989 100644
--- a/src/s_tir/schedule/utils.h
+++ b/src/s_tir/schedule/utils.h
@@ -42,8 +42,8 @@
#include "../../arith/pattern_match.h"
#include "../../ir/attr_registry.h"
#include "../../runtime/thread_storage_scope.h"
-#include "../../support/array.h"
-#include "../../support/nd_int_set.h"
+#include "../support/array_utils.h"
+#include "../support/nd_int_set.h"
#include "./analysis.h"
#include "./error.h"
#include "./instruction_traits.h"
diff --git a/src/support/array.h b/src/s_tir/support/array_utils.h
similarity index 98%
rename from src/support/array.h
rename to src/s_tir/support/array_utils.h
index 6e2aeca3e1..cd9fdb410c 100644
--- a/src/support/array.h
+++ b/src/s_tir/support/array_utils.h
@@ -16,8 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-#ifndef TVM_SUPPORT_ARRAY_H_
-#define TVM_SUPPORT_ARRAY_H_
+#ifndef TVM_S_TIR_SUPPORT_ARRAY_UTILS_H_
+#define TVM_S_TIR_SUPPORT_ARRAY_UTILS_H_
#include <tvm/ffi/container/array.h>
#include <tvm/ir/expr.h>
@@ -278,4 +278,4 @@ inline ffi::Array<TDst> AsArray(const std::vector<TSrc>&
vec) {
} // namespace support
} // namespace tvm
-#endif // TVM_SUPPORT_ARRAY_H_
+#endif // TVM_S_TIR_SUPPORT_ARRAY_UTILS_H_
diff --git a/src/support/nd_int_set.h b/src/s_tir/support/nd_int_set.h
similarity index 97%
rename from src/support/nd_int_set.h
rename to src/s_tir/support/nd_int_set.h
index 012aefd18b..03f3672b45 100644
--- a/src/support/nd_int_set.h
+++ b/src/s_tir/support/nd_int_set.h
@@ -16,8 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-#ifndef TVM_SUPPORT_ND_INT_SET_H_
-#define TVM_SUPPORT_ND_INT_SET_H_
+#ifndef TVM_S_TIR_SUPPORT_ND_INT_SET_H_
+#define TVM_S_TIR_SUPPORT_ND_INT_SET_H_
#include <tvm/arith/int_set.h>
#include <tvm/ir/expr.h>
@@ -147,4 +147,4 @@ inline NDIntSet NDIntSetEval(
} // namespace support
} // namespace tvm
-#endif // TVM_SUPPORT_ND_INT_SET_H_
+#endif // TVM_S_TIR_SUPPORT_ND_INT_SET_H_
diff --git a/src/support/parallel_for.cc b/src/s_tir/support/parallel_for.h
similarity index 59%
rename from src/support/parallel_for.cc
rename to src/s_tir/support/parallel_for.h
index 46aa46b409..9374027c42 100644
--- a/src/support/parallel_for.cc
+++ b/src/s_tir/support/parallel_for.h
@@ -18,13 +18,19 @@
*/
/*!
- * \file parallel_for.cc
+ * \file parallel_for.h
* \brief An implementation to run loop in parallel.
*/
+#ifndef TVM_S_TIR_SUPPORT_PARALLEL_FOR_H_
+#define TVM_S_TIR_SUPPORT_PARALLEL_FOR_H_
+
+#include <tvm/runtime/base.h>
#include <tvm/runtime/logging.h>
-#include <tvm/support/parallel_for.h>
+#include <atomic>
+#include <functional>
#include <future>
+#include <mutex>
#include <thread>
#include <utility>
#include <vector>
@@ -32,7 +38,19 @@
namespace tvm {
namespace support {
-std::vector<std::vector<int>> rr_partitioner(int begin, int end, int step, int
num_threads) {
+using PartitionerFuncType = std::function<std::vector<std::vector<int>>(int,
int, int, int)>;
+
+/*!
+ * \brief A partitioner to split the task to each thread in Round-robin manner.
+ * \param begin The start index of this parallel loop(inclusive).
+ * \param end The end index of this parallel loop(exclusive).
+ * \param step The traversal step to the index.
+ * \param num_threads The number of threads(the number of tasks to be
partitioned to).
+ * \return A list with `num_threads` elements, and each is a list of integers
indicating the loop
+ * indexes for the corresponding thread to process.
+ */
+TVM_DLL inline std::vector<std::vector<int>> rr_partitioner(int begin, int
end, int step,
+ int num_threads) {
int total_task_count = (end - begin) / step;
TVM_FFI_ICHECK_GE(total_task_count, 0)
<< "Infinite loop condition with begin: " << begin << " end: " << end <<
" step: " << step;
@@ -47,8 +65,28 @@ std::vector<std::vector<int>> rr_partitioner(int begin, int
end, int step, int n
return ret;
}
-void parallel_for(int begin, int end, const std::function<void(int)>& f, int
step,
- const PartitionerFuncType partitioner) {
+/*!
+ * \brief A runtime api provided to run the task function in parallel.
+ * e.g. A for loop:
+ * for (int i = 0; i < 10; i++) {
+ * a[i] = i;
+ * }
+ * should work the same as:
+ * parallel_for(0, 10, [&a](int index) {
+ * a[i] = i;
+ * });
+ * \param begin The start index of this parallel loop(inclusive).
+ * \param end The end index of this parallel loop(exclusive).
+ * \param f The task function to be executed. Assert to take an int index as
input with no output.
+ * \param step The traversal step to the index.
+ * \param partitioner A partition function to split tasks to different
threads. Use Round-robin
+ * partitioner by default.
+ * \note 1. Currently do not support nested parallel_for; 2. The order of
execution in each thread
+ * is not guaranteed, the for loop task should be thread independent and
thread safe.
+ */
+TVM_DLL inline void parallel_for(int begin, int end, const
std::function<void(int)>& f,
+ int step = 1,
+ const PartitionerFuncType partitioner =
rr_partitioner) {
static bool GLOBAL_PARALLEL_FOR_FLAG{false};
static std::mutex M_GLOBAL_PARALLEL_FOR_FLAG;
{
@@ -94,8 +132,26 @@ void parallel_for(int begin, int end, const
std::function<void(int)>& f, int ste
}
}
-void parallel_for_dynamic(int begin, int end, int num_threads,
- const std::function<void(int thread_id, int
task_id)>& f) {
+/*!
+ * \brief An API to launch fix amount of threads to run the specific functor
in parallel.
+ * Different from `parallel_for`, the partition is determined dynamically on
the fly,
+ * i.e. any time when a thread is idle, it fetches the next task to run.
+ * The behavior is similar to dynamic scheduling in OpenMP:
+ *
+ * \#pragma omp parallel for schedule(dynamic) num_threads(num_threads)
+ * for (int i = 0; i < 10; i++) {
+ * a[i] = i;
+ * }
+ *
+ * \param begin The start index of this parallel loop (inclusive).
+ * \param end The end index of this parallel loop (exclusive).
+ * \param num_threads The number of threads to be used.
+ * \param f The task function to be executed. Takes the thread index and the
task index as
+ * input with no output.
+ * \note `step` support is left for future work.
+ */
+TVM_DLL inline void parallel_for_dynamic(int begin, int end, int num_threads,
+ const std::function<void(int
thread_id, int task_id)>& f) {
// Step 1. Sanity checks
if (begin == end) {
return;
@@ -143,3 +199,5 @@ void parallel_for_dynamic(int begin, int end, int
num_threads,
} // namespace support
} // namespace tvm
+
+#endif // TVM_S_TIR_SUPPORT_PARALLEL_FOR_H_
diff --git a/src/support/table_printer.h b/src/s_tir/support/table_printer.h
similarity index 97%
rename from src/support/table_printer.h
rename to src/s_tir/support/table_printer.h
index 078055aa95..6ccaa23eca 100644
--- a/src/support/table_printer.h
+++ b/src/s_tir/support/table_printer.h
@@ -16,8 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-#ifndef TVM_SUPPORT_TABLE_PRINTER_H_
-#define TVM_SUPPORT_TABLE_PRINTER_H_
+#ifndef TVM_S_TIR_SUPPORT_TABLE_PRINTER_H_
+#define TVM_S_TIR_SUPPORT_TABLE_PRINTER_H_
#include <tvm/runtime/logging.h>
@@ -157,4 +157,4 @@ inline std::string TablePrinter::AsStr() const {
} // namespace support
} // namespace tvm
-#endif // TVM_SUPPORT_TABLE_PRINTER_H_
+#endif // TVM_S_TIR_SUPPORT_TABLE_PRINTER_H_
diff --git a/src/s_tir/transform/compact_buffer_region.cc
b/src/s_tir/transform/compact_buffer_region.cc
index 3d73fa1912..b08edb81dc 100644
--- a/src/s_tir/transform/compact_buffer_region.cc
+++ b/src/s_tir/transform/compact_buffer_region.cc
@@ -34,10 +34,10 @@
#include <stack>
#include "../../support/arena.h"
-#include "../../support/nd_int_set.h"
#include "../../support/utils.h"
#include "../../tirx/transform/ir_utils.h"
#include "../schedule/utils.h"
+#include "../support/nd_int_set.h"
namespace tvm {
namespace s_tir {
diff --git a/src/support/arena.h b/src/support/arena.h
index 832f828778..79036326f6 100644
--- a/src/support/arena.h
+++ b/src/support/arena.h
@@ -22,19 +22,166 @@
* \file arena.h
* \brief Arena allocator that allocates
* memory chunks and frees them all during destruction time.
+ *
+ * NOTE: The GenericArena/ArenaPageHeader portion of this file is portable to
bare-metal embedded
+ * devices. Don't use operator new (without placement parameters) or malloc in
that section.
+ * The SimplePageAllocator below uses operator new / delete and is NOT
bare-metal portable.
*/
#ifndef TVM_SUPPORT_ARENA_H_
#define TVM_SUPPORT_ARENA_H_
+#ifndef TVM_ARENA_HAS_DESTRUCTOR
+#define TVM_ARENA_HAS_DESTRUCTOR 1
+#endif
+
+#include <stddef.h>
+
#include <cstddef>
#include <type_traits>
#include <utility>
-#include "generic_arena.h"
-
namespace tvm {
namespace support {
+namespace {
+template <typename T> // For lvalues (T is T&),
+T&& forward(T&& param) { // take/return lvalue refs.
+ return static_cast<T&&>(param); // For rvalues (T is T),
+} // take/return rvalue refs.
+} // namespace
+
+/*!
+ * \brief An arena page header.
+ */
+struct ArenaPageHeader {
+ /*! \brief points to the next page. */
+ ArenaPageHeader* next;
+ /*!
+ * \brief Total size of the page.
+ */
+ size_t size;
+ /*! \brief memory allocator offset inside page. */
+ size_t offset;
+};
+
+/*!
+ * \brief Arena allocator that allocates memory from continuous
+ * chunk and frees them all only during destruction.
+ */
+template <typename PageAllocator>
+class GenericArena {
+ public:
+ explicit GenericArena(PageAllocator alloc = PageAllocator()) : alloc_(alloc)
{
+ // eagerly allocate the first page.
+ head_ = tail_ = alloc_.allocate(1);
+ head_->next = nullptr;
+ }
+
+#if TVM_ARENA_HAS_DESTRUCTOR
+ ~GenericArena() { this->FreeAll(); }
+#endif
+
+ /*! \brief Free all pages. */
+ void FreeAll() {
+ FreePageList(&head_);
+ FreePageList(&free_list_);
+ }
+ /*! \brief Recycle all the pages in the arena */
+ void RecycleAll() {
+ // put all the current list to the free list.
+ tail_->next = free_list_;
+ // allocate the first in the free list to head
+ free_list_ = head_->next;
+ head_->next = nullptr;
+ // Reset the head.
+ head_->offset = sizeof(ArenaPageHeader);
+ tail_ = head_;
+ }
+ /*!
+ * \brief Allocate a space from Arena for type T
+ * \param T the data type to be allocated
+ * \param count Numberof elements
+ * \note The space of T is not initialized.
+ */
+ template <typename T>
+ T* allocate_(int count = 1) {
+ static_assert(PageAllocator::kPageAlign % alignof(T) == 0, "Too large
alignment");
+ return static_cast<T*>(Alloc(sizeof(T) * count, alignof(T)));
+ }
+ /*!
+ * \brief Create a new instance of type T.
+ * \param args The constructor argument.
+ * \tparam T the type to be created.
+ * \tparam Args Arguments to the constructor.
+ *
+ * \return The allocated object.
+ * \note The type T must be simple type, or only contain
+ * memory allocated from the same arena.
+ * Otherwise the destructor needs to be called explicitly.
+ */
+ template <typename T, typename... Args>
+ T* make(Args&&... args) {
+ T* ptr = allocate_<T>();
+ new (ptr) T(forward<Args>(args)...);
+ return ptr;
+ }
+
+ private:
+ /*! \brief internal page allocator. */
+ PageAllocator alloc_;
+ /* \brief The head of the allocated list. */
+ ArenaPageHeader* head_{nullptr};
+ /*! \brief The tail of the allocated list. */
+ ArenaPageHeader* tail_{nullptr};
+ /* \brief List of free pages. */
+ ArenaPageHeader* free_list_{nullptr};
+ /*!
+ * \brief Align ptr by upper bound.
+ * \param offset The offset value.
+ * \param align The alignment requirement.
+ */
+ size_t UpperAlign(size_t offset, size_t align) {
+ return offset + (align - (offset % align)) % align;
+ }
+ /*!
+ * \brief Internal aligned alloc function.
+ * \param size The size of the memory.
+ * \param align The alignment requirement.
+ */
+ void* Alloc(size_t size, size_t align) {
+ size_t offset = UpperAlign(head_->offset, align);
+ if (offset + size <= head_->size) {
+ head_->offset = offset + size;
+ return reinterpret_cast<char*>(head_) + offset;
+ } else {
+ ArenaPageHeader* new_head;
+ offset = UpperAlign(sizeof(ArenaPageHeader), align);
+ if (free_list_ != nullptr && offset + size <= free_list_->size) {
+ new_head = free_list_;
+ free_list_ = free_list_->next;
+ } else {
+ new_head = alloc_.allocate(offset + size);
+ }
+ new_head->next = head_;
+ new_head->offset = offset + size;
+ head_ = new_head;
+ return reinterpret_cast<char*>(head_) + offset;
+ }
+ }
+ /*!
+ * \brief Free all the pages in the list.
+ * \param ptr The head ptr.
+ */
+ void FreePageList(ArenaPageHeader** ptr) {
+ // delete all the allocated pages.
+ while (ptr[0] != nullptr) {
+ ArenaPageHeader* temp = ptr[0];
+ ptr[0] = ptr[0]->next;
+ alloc_.deallocate(temp);
+ }
+ }
+};
+
/*!
* \brief Simple page allocator that uses new and delete.
*/
diff --git a/src/support/generic_arena.h b/src/support/generic_arena.h
deleted file mode 100644
index ca4d14de72..0000000000
--- a/src/support/generic_arena.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- *
- * \file arena.h
- * \brief Arena allocator that allocates memory chunks and frees them all
during destruction time.
- *
- * NOTE: This file is portable to bare-metal embedded devices. Don't use
operator new (without
- * placement parameters) or malloc.
- */
-#ifndef TVM_SUPPORT_GENERIC_ARENA_H_
-#define TVM_SUPPORT_GENERIC_ARENA_H_
-
-#ifndef TVM_ARENA_HAS_DESTRUCTOR
-#define TVM_ARENA_HAS_DESTRUCTOR 1
-#endif
-
-#include <stddef.h>
-
-#include <utility>
-
-namespace tvm {
-namespace support {
-
-namespace {
-template <typename T> // For lvalues (T is T&),
-T&& forward(T&& param) { // take/return lvalue refs.
- return static_cast<T&&>(param); // For rvalues (T is T),
-} // take/return rvalue refs.
-} // namespace
-
-/*!
- * \brief An arena page header.
- */
-struct ArenaPageHeader {
- /*! \brief points to the next page. */
- ArenaPageHeader* next;
- /*!
- * \brief Total size of the page.
- */
- size_t size;
- /*! \brief memory allocator offset inside page. */
- size_t offset;
-};
-
-/*!
- * \brief Arena allocator that allocates memory from continuous
- * chunk and frees them all only during destruction.
- */
-template <typename PageAllocator>
-class GenericArena {
- public:
- explicit GenericArena(PageAllocator alloc = PageAllocator()) : alloc_(alloc)
{
- // eagerly allocate the first page.
- head_ = tail_ = alloc_.allocate(1);
- head_->next = nullptr;
- }
-
-#if TVM_ARENA_HAS_DESTRUCTOR
- ~GenericArena() { this->FreeAll(); }
-#endif
-
- /*! \brief Free all pages. */
- void FreeAll() {
- FreePageList(&head_);
- FreePageList(&free_list_);
- }
- /*! \brief Recycle all the pages in the arena */
- void RecycleAll() {
- // put all the current list to the free list.
- tail_->next = free_list_;
- // allocate the first in the free list to head
- free_list_ = head_->next;
- head_->next = nullptr;
- // Reset the head.
- head_->offset = sizeof(ArenaPageHeader);
- tail_ = head_;
- }
- /*!
- * \brief Allocate a space from Arena for type T
- * \param T the data type to be allocated
- * \param count Numberof elements
- * \note The space of T is not initialized.
- */
- template <typename T>
- T* allocate_(int count = 1) {
- static_assert(PageAllocator::kPageAlign % alignof(T) == 0, "To large
alignment");
- return static_cast<T*>(Alloc(sizeof(T) * count, alignof(T)));
- }
- /*!
- * \brief Create a new instance of type T.
- * \param args The constructor argument.
- * \tparam T the type to be created.
- * \tparam Args Arguments to the constructor.
- *
- * \return The allocated object.
- * \note The type T must be simple type, or only contain
- * memory allocated from the same arena.
- * Otherwise the destructor needs to be called explicitly.
- */
- template <typename T, typename... Args>
- T* make(Args&&... args) {
- T* ptr = allocate_<T>();
- new (ptr) T(forward<Args>(args)...);
- return ptr;
- }
-
- private:
- /*! \brief internal page allocator. */
- PageAllocator alloc_;
- /* \brief The head of the allocated list. */
- ArenaPageHeader* head_{nullptr};
- /*! \brief The tail of the allocated list. */
- ArenaPageHeader* tail_{nullptr};
- /* \brief List of free pages. */
- ArenaPageHeader* free_list_{nullptr};
- /*!
- * \brief Align ptr by upper bound.
- * \param offset The offset value.
- * \param align The alignment requirement.
- */
- size_t UpperAlign(size_t offset, size_t align) {
- return offset + (align - (offset % align)) % align;
- }
- /*!
- * \brief Internal aligned alloc function.
- * \param size The size of the memory.
- * \param align The alignment requirement.
- */
- void* Alloc(size_t size, size_t align) {
- size_t offset = UpperAlign(head_->offset, align);
- if (offset + size <= head_->size) {
- head_->offset = offset + size;
- return reinterpret_cast<char*>(head_) + offset;
- } else {
- ArenaPageHeader* new_head;
- offset = UpperAlign(sizeof(ArenaPageHeader), align);
- if (free_list_ != nullptr && offset + size <= free_list_->size) {
- new_head = free_list_;
- free_list_ = free_list_->next;
- } else {
- new_head = alloc_.allocate(offset + size);
- }
- new_head->next = head_;
- new_head->offset = offset + size;
- head_ = new_head;
- return reinterpret_cast<char*>(head_) + offset;
- }
- }
- /*!
- * \brief Free all the pages in the list.
- * \param ptr The head ptr.
- */
- void FreePageList(ArenaPageHeader** ptr) {
- // delete all the allocated pages.
- while (ptr[0] != nullptr) {
- ArenaPageHeader* temp = ptr[0];
- ptr[0] = ptr[0]->next;
- alloc_.deallocate(temp);
- }
- }
-};
-
-} // namespace support
-} // namespace tvm
-#endif // TVM_SUPPORT_GENERIC_ARENA_H_
diff --git a/src/support/hexdump.h b/src/support/hexdump.h
deleted file mode 100644
index 29fee1cd29..0000000000
--- a/src/support/hexdump.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- *
- * \file support/hexdump.h
- * \brief Print hex representation of BLOBs.
- */
-#ifndef TVM_SUPPORT_HEXDUMP_H_
-#define TVM_SUPPORT_HEXDUMP_H_
-
-#include <cctype>
-#include <iomanip>
-#include <ostream>
-#include <sstream>
-#include <string>
-
-namespace tvm {
-namespace support {
-
-/*! \brief generate a hexdump of some binary data.
- * \param s Binary data to print.
- * \param os stream that receives the hexdump.
- */
-inline void HexDump(const std::string& s, std::ostream& os) {
- os << std::hex << std::setfill('0') << std::right;
-
- int addr_width = 4;
- for (size_t addr_bytes = s.size() >> 16; addr_bytes != 0; addr_bytes >>= 4) {
- addr_width++;
- }
-
- for (size_t cursor = 0; cursor < s.size(); cursor += 0x10) {
- os << std::setw(addr_width) << cursor;
- size_t row_end = cursor + 0x10;
- if (row_end > s.size()) {
- row_end = s.size();
- }
-
- os << " ";
- for (size_t j = cursor; j < row_end; j++) {
- os << " " << std::setw(2) << (unsigned int)(s[j] & 0xff);
- }
-
- for (size_t j = row_end; j < cursor + 0x10; j++) {
- os << " ";
- }
-
- os << std::setw(1) << " ";
- for (size_t j = cursor; j < row_end; j++) {
- os << (isprint(s[j]) ? s[j] : '.');
- }
- os << std::endl;
- }
-}
-
-/*! \brief return a string containing a hexdump of the data in s */
-inline std::string HexDump(const std::string& s) {
- std::stringstream ss;
- HexDump(s, ss);
- return ss.str();
-}
-
-} // namespace support
-} // namespace tvm
-#endif // TVM_SUPPORT_HEXDUMP_H_
diff --git a/src/support/scalars.h b/src/support/limits.h
similarity index 62%
rename from src/support/scalars.h
rename to src/support/limits.h
index 069ed62445..eb88643288 100644
--- a/src/support/scalars.h
+++ b/src/support/limits.h
@@ -18,42 +18,15 @@
*/
/*!
- * \file src/support/scalars.h
- * \brief Helpers for converting between scalars in native, text, TIR
immediate and Tensor forms.
+ * \file src/support/limits.h
+ * \brief Numeric range limits for TVM low-precision floating-point dtypes.
*/
-
-#ifndef TVM_SUPPORT_SCALARS_H_
-#define TVM_SUPPORT_SCALARS_H_
-
-#include <cmath>
-#include <string>
-
-#include "tvm/ir/expr.h"
-#include "tvm/runtime/tensor.h"
+#ifndef TVM_SUPPORT_LIMITS_H_
+#define TVM_SUPPORT_LIMITS_H_
namespace tvm {
namespace support {
-/*! \brief Returns Tensor 'scalar' for given TIR immediate. */
-runtime::Tensor IntImmToTensor(const IntImm& int_imm);
-runtime::Tensor FloatImmToTensor(const FloatImm& float_imm);
-runtime::Tensor BoolToTensor(bool value);
-
-/*! \brief Returns literal text for Tensor 'scalar'. */
-std::string TensorScalarToString(const runtime::Tensor& data);
-
-/*! \brief Returns literal text for given TIR immediate. */
-std::string IntImmToString(const IntImm& int_imm);
-std::string FloatImmToString(const FloatImm& float_imm);
-
-/*!
- * \brief Returns TIR immediate for given value and width. Result will be null
if value is
- * out of range in width. Note however for floating point we don't check if
the value is
- * representable without loss of precision.
- */
-IntImm ValueToIntImm(int64_t value, int width);
-FloatImm ValueToFloatImm(double value, int width);
-
// 2^15 * (1 + 1023/1024)
// See https://en.wikipedia.org/wiki/Half-precision_floating-point_format
constexpr double kMaxFloat16 = 65504.0;
@@ -100,4 +73,4 @@ constexpr double kMaxE2M1FN = 6.0;
} // namespace support
} // namespace tvm
-#endif // TVM_SUPPORT_SCALARS_H_
+#endif // TVM_SUPPORT_LIMITS_H_
diff --git a/src/support/scalars.cc b/src/support/scalars.cc
deleted file mode 100644
index a3836a849d..0000000000
--- a/src/support/scalars.cc
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * \file src/support/scalars.cc
- * \brief Helpers for converting between scalars in native, text, TIR
immediate and Tensor forms.
- */
-
-#include "./scalars.h"
-
-#include "tvm/runtime/builtin_fp16.h"
-
-namespace tvm {
-namespace support {
-
-/*! \brief The standard scalar dtypes. */
-static const DataType kInt16 = DataType::Int(16);
-static const DataType kInt32 = DataType::Int(32);
-static const DataType kInt64 = DataType::Int(64);
-static const DataType kFloat16 = DataType::Float(16);
-static const DataType kFloat32 = DataType::Float(32);
-static const DataType kFloat64 = DataType::Float(64);
-static const DataType kBool = DataType::Bool();
-
-runtime::Tensor IntImmToTensor(const IntImm& int_imm) {
- DLDevice dev = {DLDeviceType::kDLCPU, 0};
- auto data = runtime::Tensor::Empty({}, int_imm->dtype, dev);
- if (int_imm.dtype() == kInt16) {
- auto* array = reinterpret_cast<int16_t*>(data->data);
- array[0] = static_cast<int16_t>(int_imm->value);
- } else if (int_imm.dtype() == kInt32) {
- auto* array = reinterpret_cast<int32_t*>(data->data);
- array[0] = static_cast<int32_t>(int_imm->value);
- } else if (int_imm.dtype() == kInt64) {
- auto* array = reinterpret_cast<int64_t*>(data->data);
- array[0] = int_imm->value;
- } else {
- TVM_FFI_THROW(InternalError) << "Unrecognized numeric literal dtype: "
- << DLDataTypeToString(int_imm.dtype());
- }
- return data;
-}
-
-runtime::Tensor FloatImmToTensor(const FloatImm& float_imm) {
- DLDevice dev = {DLDeviceType::kDLCPU, 0};
- auto data = runtime::Tensor::Empty({}, float_imm->dtype, dev);
- if (float_imm.dtype() == kFloat16) {
- auto* array = reinterpret_cast<uint16_t*>(data->data);
- array[0] = __gnu_f2h_ieee(static_cast<float>(float_imm->value));
- } else if (float_imm.dtype() == kFloat32) {
- auto* array = reinterpret_cast<float*>(data->data);
- array[0] = static_cast<float>(float_imm->value);
- } else if (float_imm.dtype() == kFloat64) {
- auto* array = reinterpret_cast<double*>(data->data);
- array[0] = float_imm->value;
- } else {
- TVM_FFI_THROW(InternalError) << "Unrecognized numeric literal dtype: "
- << DLDataTypeToString(float_imm.dtype());
- }
- return data;
-}
-
-runtime::Tensor BoolToTensor(bool value) {
- DLDevice dev = {DLDeviceType::kDLCPU, 0};
- auto data = runtime::Tensor::Empty({}, kBool, dev);
- auto array = reinterpret_cast<bool*>(data->data);
- array[0] = value;
- return data;
-}
-
-std::string TensorScalarToString(const runtime::Tensor& data) {
- std::ostringstream os;
- DataType dtype(data->dtype);
- TVM_FFI_ICHECK_EQ(data->device.device_type, kDLCPU)
- << "Scalars must reside on the CPU to be printed";
- if (dtype == kInt16) {
- auto value = static_cast<const int16_t*>(data->data)[0];
- os << value << "i16";
- } else if (dtype == kInt32) {
- auto value = static_cast<const int32_t*>(data->data)[0];
- os << value;
- } else if (dtype == kInt64) {
- auto value = static_cast<const int64_t*>(data->data)[0];
- os << value << "i64";
- } else if (dtype == kFloat16) {
- auto value = __gnu_h2f_ieee(static_cast<const uint16_t*>(data->data)[0]);
- os << value << "f16";
- } else if (dtype == kFloat32) {
- auto value = static_cast<const float*>(data->data)[0];
- os << value << "f";
- } else if (dtype == kFloat64) {
- auto value = static_cast<const double*>(data->data)[0];
- os << value << "f64";
- } else if (dtype == kBool) {
- auto value = static_cast<const uint8_t*>(data->data)[0];
- os << (value ? "True" : "False");
- } else {
- TVM_FFI_THROW(InternalError) << "Unrecognized Tensor scalar dtype: "
- << DLDataTypeToString(dtype);
- }
- return os.str();
-}
-
-std::string IntImmToString(const IntImm& int_imm) {
- std::ostringstream os;
- if (int_imm->dtype == kInt16) {
- os << int_imm->value << "i16";
- } else if (int_imm->dtype == kInt32) {
- os << int_imm->value;
- } else if (int_imm->dtype == kInt64) {
- os << int_imm->value << "i64";
- } else if (int_imm->dtype == kBool) {
- os << (int_imm->value ? "True" : "False");
- } else {
- TVM_FFI_THROW(InternalError) << "Unrecognised IntImm dtype: "
- << DLDataTypeToString(int_imm->dtype);
- }
- return os.str();
-}
-
-std::string FloatImmToString(const FloatImm& float_imm) {
- std::ostringstream os;
- if (float_imm->dtype == kFloat16) {
- os << float_imm->value << "f16";
- } else if (float_imm->dtype == kFloat32) {
- os << float_imm->value << "f";
- } else if (float_imm->dtype == kFloat64) {
- os << float_imm->value << "f64";
- } else {
- TVM_FFI_THROW(InternalError) << "Unrecognised FloatImm dtype: "
- << DLDataTypeToString(float_imm->dtype);
- }
- return os.str();
-}
-
-IntImm ValueToIntImm(int64_t value, int width) {
- if (width == 16) {
- if (value < std::numeric_limits<int16_t>::min() ||
- value > std::numeric_limits<int16_t>::max()) {
- return {};
- }
- return IntImm(kInt16, value);
- } else if (width == 32) {
- if (value < std::numeric_limits<int32_t>::min() ||
- value > std::numeric_limits<int32_t>::max()) {
- return {};
- }
- return IntImm(kInt32, value);
- } else if (width == 64) {
- return IntImm(kInt64, value);
- } else {
- TVM_FFI_THROW(InternalError) << "Unrecognized int scalar width: " << width;
- }
-}
-
-FloatImm ValueToFloatImm(double value, int width) {
- if (width == 16) {
- if (!std::isinf(value) && (value < -kMaxFloat16 || value > kMaxFloat16)) {
- return {};
- }
- return FloatImm(kFloat16, value);
- } else if (width == 32) {
- if (!std::isinf(value) &&
- (value < -std::numeric_limits<float>::max() || value >
std::numeric_limits<float>::max())) {
- return {};
- }
- return FloatImm(kFloat32, value);
- } else if (width == 64) {
- return FloatImm(kFloat64, value);
- } else {
- TVM_FFI_THROW(InternalError) << "Unrecognized float scalar width: " <<
width;
- }
-}
-
-} // namespace support
-} // namespace tvm
diff --git a/src/te/operation/create_primfunc.cc
b/src/te/operation/create_primfunc.cc
index d34222117f..7c8bcc5ac0 100644
--- a/src/te/operation/create_primfunc.cc
+++ b/src/te/operation/create_primfunc.cc
@@ -36,7 +36,6 @@
#include <utility>
#include <vector>
-#include "../../support/array.h"
#include "../../tirx/ir/data_type_rewriter.h"
#include "../../tirx/ir/functor_common.h"
#include "graph.h"
diff --git a/tests/cpp/parallel_for_test.cc b/tests/cpp/parallel_for_test.cc
deleted file mode 100644
index b6b352f0ba..0000000000
--- a/tests/cpp/parallel_for_test.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <gtest/gtest.h>
-#include <tvm/runtime/logging.h>
-#include <tvm/support/parallel_for.h>
-
-#include <thread>
-#include <vector>
-
-TEST(ParallelFor, Basic) {
- using tvm::support::parallel_for;
-
- int a[1000], b[1000];
-
- // Check for a small size of parallel
- for (int i = 0; i < 10; i++) {
- a[i] = i;
- }
- parallel_for(0, 10, [&b](int i) { b[i] = i; });
- for (int i = 0; i < 10; i++) {
- TVM_FFI_ICHECK_EQ(a[i], b[i]);
- }
-
- // Check for a large size of parallel
- for (int i = 0; i < 1000; i++) {
- a[i] = i;
- }
- parallel_for(0, 1000, [&b](int i) { b[i] = i; });
- for (int i = 0; i < 1000; i++) {
- TVM_FFI_ICHECK_EQ(a[i], b[i]);
- }
-
- // Check for step != 1
- for (int i = 0; i < 1000; i += 2) {
- a[i] *= 2;
- }
- parallel_for(0, 1000, [&b](int i) { b[i] *= 2; }, 2);
- for (int i = 0; i < 1000; i++) {
- TVM_FFI_ICHECK_EQ(a[i], b[i]);
- }
-}
-
-TEST(ParallelFor, NestedWithNormalForLoop) {
- using tvm::support::parallel_for;
-
- int a[500][500], b[500][500], c[500][500];
-
- for (int i = 0; i < 500; i++) {
- for (int j = 0; j < 500; j++) {
- a[i][j] = i * j;
- }
- }
-
- parallel_for(0, 500, [&b](int i) {
- for (int j = 0; j < 500; j++) {
- b[i][j] = i * j;
- }
- });
- for (int i = 0; i < 500; i++) {
- for (int j = 0; j < 500; j++) {
- TVM_FFI_ICHECK_EQ(a[i][j], b[i][j]);
- }
- }
-
- for (int i = 0; i < 500; i++) {
- parallel_for(0, 500, [&c, &i](int j) { c[i][j] = i * j; });
- }
- for (int i = 0; i < 500; i++) {
- for (int j = 0; j < 500; j++) {
- TVM_FFI_ICHECK_EQ(a[i][j], c[i][j]);
- }
- }
-}
-
-TEST(ParallelFor, NestedWithParallelFor) {
- // Currently do not support using nested parallel_for
- using tvm::support::parallel_for;
-
- bool exception = false;
- try {
- parallel_for(0, 100, [](int i) {
- parallel_for(0, 100, [](int j) {
- // Blank loop
- });
- });
- } catch (const std::exception& e) {
- exception = true;
- }
- TVM_FFI_ICHECK(exception);
-}
-
-TEST(ParallelFor, Exception) {
- using tvm::support::parallel_for;
-
- bool exception = false;
- try {
- parallel_for(0, 100, [](int i) { TVM_FFI_THROW(InternalError) << "error";
});
- } catch (const std::exception& e) {
- exception = true;
- }
- TVM_FFI_ICHECK(exception);
-}
-
-TEST(ParallelForDynamic, Basic) {
- using tvm::support::parallel_for_dynamic;
- int a[1000];
- int num_threads = std::thread::hardware_concurrency();
- parallel_for_dynamic(0, 1000, num_threads, [&a](int thread_id, int i) { a[i]
= i; });
- for (int i = 0; i < 1000; i++) {
- TVM_FFI_ICHECK_EQ(a[i], i);
- }
-}
-
-TEST(ParallelForDynamic, ExceptionOnMain) {
- using tvm::support::parallel_for_dynamic;
- int num_threads = 1;
- bool exception = false;
- try {
- parallel_for_dynamic(0, 10, num_threads, [](int thread_id, int task_id) {
- if (thread_id == 0) {
- TVM_FFI_THROW(InternalError) << "Error";
- }
- });
- } catch (const std::exception& e) {
- exception = true;
- }
- TVM_FFI_ICHECK(exception);
-}
-
-TEST(ParallelForDynamic, ExceptionOnArbitrary) {
- using tvm::support::parallel_for_dynamic;
- int num_threads = 3;
- bool exception = false;
- try {
- parallel_for_dynamic(0, 100, num_threads, [](int thread_id, int task_id) {
- TVM_FFI_THROW(InternalError) << "Error";
- });
- } catch (const std::exception& e) {
- exception = true;
- }
- TVM_FFI_ICHECK(exception);
-}
diff --git a/tests/cpp/support_test.cc b/tests/cpp/support_test.cc
index 20272d67c4..87f14dce02 100644
--- a/tests/cpp/support_test.cc
+++ b/tests/cpp/support_test.cc
@@ -20,30 +20,11 @@
#include <gtest/gtest.h>
#include <tvm/runtime/logging.h>
-#include "../../src/support/hexdump.h"
#include "../../src/support/utils.h"
namespace tvm {
namespace test {
-TEST(HexDumpTests, Empty) { EXPECT_EQ("", ::tvm::support::HexDump("")); }
-
-TEST(HexDumpTests, Aligned) {
- EXPECT_EQ(
- "0000 01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef
.#Eg.....#Eg....\n"
- "0010 01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef
.#Eg.....#Eg....\n",
-
::tvm::support::HexDump("\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
-
"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"));
-}
-
-TEST(HexDumpTests, Unaligned) {
- EXPECT_EQ(
- "0000 01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef
.#Eg.....#Eg....\n"
- "0010 01 23 45 67 89 ab cd ef 01 .#Eg.....\n",
-
::tvm::support::HexDump("\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
- "\x01\x23\x45\x67\x89\xab\xcd\xef\x01"));
-}
-
TEST(HashTests, HashStability) {
size_t a = 345292;
int b = 795620;