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 29f1183600 [REFACTOR][RELAX] Own global device metadata in Relax
(#20363)
29f1183600 is described below
commit 29f118360074833477eea072cf41b3cb57e6a1bc
Author: Tianqi Chen <[email protected]>
AuthorDate: Wed Sep 16 11:43:56 2026 -0400
[REFACTOR][RELAX] Own global device metadata in Relax (#20363)
Relax owns the concrete global metadata used by its device annotations.
Move `VDevice`, `MemoryScope`, and `DummyGlobalInfo` into the Relax C++
and Python namespaces, with their registrations and consumers, while
keeping the generic `GlobalInfo` base and IRModule storage in IR.
Existing TVMScript global-info syntax is preserved.
Remove the unused legacy `target.VirtualDevice` API and its dedicated
wrappers and tests.
---
include/tvm/ir/expr.h | 3 -
include/tvm/ir/global_info.h | 68 +---
include/tvm/relax/attrs/op.h | 2 +-
include/tvm/{ir => relax}/global_info.h | 39 +--
include/tvm/relax/type.h | 2 +-
include/tvm/target/virtual_device.h | 382 ---------------------
include/tvm/tirx/layout.h | 1 +
python/tvm/ir/__init__.py | 2 +-
python/tvm/ir/global_info.py | 32 +-
python/tvm/relax/__init__.py | 3 +
.../virtual_device.py => relax/global_info.py} | 39 ++-
python/tvm/relax/script/builder/ir.py | 3 +-
python/tvm/relax/transform/transform.py | 5 +-
python/tvm/relax/type.py | 3 +-
python/tvm/relax/utils.py | 3 +-
python/tvm/script/ir_builder/ir/ir.py | 14 +-
python/tvm/target/__init__.py | 1 -
src/{ => relax}/ir/global_info.cc | 10 +-
src/relax/script/printer/call.cc | 2 +-
src/relax/script/printer/utils.h | 4 +-
src/script/ir_builder/ir/ir.cc | 9 +-
src/script/printer/ir/ir.cc | 7 +-
src/target/virtual_device.cc | 201 -----------
tests/cpp/target/virtual_device_test.cc | 129 -------
tests/python/relax/test_analysis_type_analysis.py | 16 +-
.../relax/test_backend_dispatch_sort_scan.py | 2 +-
tests/python/relax/test_op_binary.py | 3 +-
tests/python/relax/test_op_create.py | 3 +-
tests/python/relax/test_op_image.py | 3 +-
tests/python/relax/test_op_index.py | 3 +-
tests/python/relax/test_op_linear_algebra.py | 3 +-
tests/python/relax/test_op_manipulate.py | 3 +-
tests/python/relax/test_op_nn.py | 3 +-
tests/python/relax/test_op_nn_convolution.py | 3 +-
tests/python/relax/test_op_nn_pooling.py | 3 +-
tests/python/relax/test_op_search.py | 3 +-
tests/python/relax/test_op_set.py | 3 +-
tests/python/relax/test_op_sort.py | 3 +-
tests/python/relax/test_op_statistical.py | 3 +-
tests/python/relax/test_op_ternary.py | 3 +-
tests/python/relax/test_op_unary.py | 3 +-
tests/python/relax/test_relax_operators.py | 2 +-
.../python/relax/test_transform_realize_vdevice.py | 2 +-
.../python/relax/test_transform_update_vdevice.py | 2 +-
tests/python/relax/test_tvmscript_parser.py | 2 +-
tests/python/relax/test_vm_build.py | 4 +-
tests/python/target/test_virtual_device.py | 51 ---
47 files changed, 128 insertions(+), 962 deletions(-)
diff --git a/include/tvm/ir/expr.h b/include/tvm/ir/expr.h
index b245795469..c02b804bab 100644
--- a/include/tvm/ir/expr.h
+++ b/include/tvm/ir/expr.h
@@ -43,9 +43,6 @@
namespace tvm {
-// Forward-declare VirtualDevice to avoid circular imports.
-class VirtualDevice;
-
/*! \brief Tuple container */
class TupleNode : public ExprNode {
public:
diff --git a/include/tvm/ir/global_info.h b/include/tvm/ir/global_info.h
index 3533b78687..46d7cce46c 100644
--- a/include/tvm/ir/global_info.h
+++ b/include/tvm/ir/global_info.h
@@ -19,23 +19,15 @@
/*!
* \file tvm/ir/global_info.h
- * \brief GlobalInfo are globally static object that are referred by the IR
itself.
+ * \brief Base for globally static objects referred to by the IR.
*/
-
#ifndef TVM_IR_GLOBAL_INFO_H_
#define TVM_IR_GLOBAL_INFO_H_
-#include <tvm/ffi/reflection/registry.h>
-#include <tvm/ir/expr.h>
-#include <tvm/target/target.h>
+#include <tvm/ffi/object.h>
namespace tvm {
-/*!
- * \brief Abstract label for an area of memory.
- */
-using MemoryScope = ffi::String;
-
/*!
* \brief GlobalInfo are globally static object that are referred by the IR
itself.
* Base node for all global info that can appear in the IR
@@ -56,62 +48,6 @@ class GlobalInfo : public ffi::ObjectRef {
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(GlobalInfo, ffi::ObjectRef,
GlobalInfoNode);
};
-/*!
- * \brief A global info subclass for virtual devices.
- */
-class VDeviceNode : public GlobalInfoNode {
- public:
- /*! \brief The \p Target describing how to compile for the virtual device. */
- Target target;
- /*! \brief The device identifier for the virtual device. This enables us to
- * differentiate between distinct devices with same Target, such as multiple
GPUs.
- */
- int vdevice_id;
- MemoryScope memory_scope;
-
- static void RegisterReflection() {
- namespace refl = tvm::ffi::reflection;
- refl::ObjectDef<VDeviceNode>()
- .def_ro("target", &VDeviceNode::target)
- .def_ro("vdevice_id", &VDeviceNode::vdevice_id)
- .def_ro("memory_scope", &VDeviceNode::memory_scope);
- }
-
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.VDevice", VDeviceNode, GlobalInfoNode);
-};
-
-/*!
- * \brief Managed reference to VDeviceNode.
- * \sa VDeviceNode
- */
-class VDevice : public GlobalInfo {
- public:
- TVM_DLL explicit VDevice(Target tgt, int dev_id, MemoryScope mem_scope);
- TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(VDevice, GlobalInfo, VDeviceNode);
-};
-
-/*!
- * \brief A dummy global info sub-class for testing purpose.
- */
-class DummyGlobalInfoNode : public GlobalInfoNode {
- public:
- static void RegisterReflection() {
- namespace refl = tvm::ffi::reflection;
- refl::ObjectDef<DummyGlobalInfoNode>();
- }
-
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.DummyGlobalInfo", DummyGlobalInfoNode,
GlobalInfoNode);
-};
-
-/*!
- * \brief Managed reference to DummyGlobalInfoNode.
- * \sa DummyGlobalInfoNode
- */
-class DummyGlobalInfo : public GlobalInfo {
- public:
- TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(DummyGlobalInfo, GlobalInfo,
DummyGlobalInfoNode);
-};
-
} // namespace tvm
#endif // TVM_IR_GLOBAL_INFO_H_
diff --git a/include/tvm/relax/attrs/op.h b/include/tvm/relax/attrs/op.h
index 4c1451c3dc..54d6bba916 100644
--- a/include/tvm/relax/attrs/op.h
+++ b/include/tvm/relax/attrs/op.h
@@ -24,8 +24,8 @@
#ifndef TVM_RELAX_ATTRS_OP_H_
#define TVM_RELAX_ATTRS_OP_H_
-#include <tvm/ir/global_info.h>
#include <tvm/relax/expr.h>
+#include <tvm/relax/global_info.h>
namespace tvm {
namespace relax {
diff --git a/include/tvm/ir/global_info.h b/include/tvm/relax/global_info.h
similarity index 71%
copy from include/tvm/ir/global_info.h
copy to include/tvm/relax/global_info.h
index 3533b78687..4cb49064b8 100644
--- a/include/tvm/ir/global_info.h
+++ b/include/tvm/relax/global_info.h
@@ -18,44 +18,24 @@
*/
/*!
- * \file tvm/ir/global_info.h
- * \brief GlobalInfo are globally static object that are referred by the IR
itself.
+ * \file tvm/relax/global_info.h
+ * \brief Global information used by Relax.
*/
-
-#ifndef TVM_IR_GLOBAL_INFO_H_
-#define TVM_IR_GLOBAL_INFO_H_
+#ifndef TVM_RELAX_GLOBAL_INFO_H_
+#define TVM_RELAX_GLOBAL_INFO_H_
#include <tvm/ffi/reflection/registry.h>
-#include <tvm/ir/expr.h>
+#include <tvm/ir/global_info.h>
#include <tvm/target/target.h>
namespace tvm {
+namespace relax {
/*!
* \brief Abstract label for an area of memory.
*/
using MemoryScope = ffi::String;
-/*!
- * \brief GlobalInfo are globally static object that are referred by the IR
itself.
- * Base node for all global info that can appear in the IR
- */
-class GlobalInfoNode : public ffi::Object {
- public:
- static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind =
kTVMFFISEqHashKindTreeNode;
-
- TVM_FFI_DECLARE_OBJECT_INFO("ir.GlobalInfo", GlobalInfoNode, ffi::Object);
-};
-
-/*!
- * \brief Managed reference to GlobalInfoNode.
- * \sa GlobalInfoNode
- */
-class GlobalInfo : public ffi::ObjectRef {
- public:
- TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(GlobalInfo, ffi::ObjectRef,
GlobalInfoNode);
-};
-
/*!
* \brief A global info subclass for virtual devices.
*/
@@ -77,7 +57,7 @@ class VDeviceNode : public GlobalInfoNode {
.def_ro("memory_scope", &VDeviceNode::memory_scope);
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.VDevice", VDeviceNode, GlobalInfoNode);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.VDevice", VDeviceNode,
GlobalInfoNode);
};
/*!
@@ -100,7 +80,7 @@ class DummyGlobalInfoNode : public GlobalInfoNode {
refl::ObjectDef<DummyGlobalInfoNode>();
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.DummyGlobalInfo", DummyGlobalInfoNode,
GlobalInfoNode);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.DummyGlobalInfo",
DummyGlobalInfoNode, GlobalInfoNode);
};
/*!
@@ -112,6 +92,7 @@ class DummyGlobalInfo : public GlobalInfo {
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(DummyGlobalInfo, GlobalInfo,
DummyGlobalInfoNode);
};
+} // namespace relax
} // namespace tvm
-#endif // TVM_IR_GLOBAL_INFO_H_
+#endif // TVM_RELAX_GLOBAL_INFO_H_
diff --git a/include/tvm/relax/type.h b/include/tvm/relax/type.h
index 9fd8ee3b59..cb3c0e8196 100644
--- a/include/tvm/relax/type.h
+++ b/include/tvm/relax/type.h
@@ -28,9 +28,9 @@
#include <tvm/ffi/reflection/registry.h>
#include <tvm/ir/attrs.h>
#include <tvm/ir/env_func.h>
-#include <tvm/ir/global_info.h>
#include <tvm/ir/prim/expr.h>
#include <tvm/ir/type.h>
+#include <tvm/relax/global_info.h>
#include <string>
#include <utility>
diff --git a/include/tvm/target/virtual_device.h
b/include/tvm/target/virtual_device.h
deleted file mode 100644
index 83c7f5655a..0000000000
--- a/include/tvm/target/virtual_device.h
+++ /dev/null
@@ -1,382 +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 tvm/target/virtual_device.h
- * \brief A compile time representation for where data is to be stored at
runtime, and how to
- * compile code to compute it.
- */
-
-#ifndef TVM_TARGET_VIRTUAL_DEVICE_H_
-#define TVM_TARGET_VIRTUAL_DEVICE_H_
-
-#include <tvm/ir/transform.h>
-#include <tvm/target/target.h>
-
-#include <string>
-#include <unordered_set>
-#include <utility>
-
-namespace tvm {
-
-/*!
- * \brief Abstract label for an area of memory.
- *
- * Currently uninterpreted and arbitrary. Likely to be replaced by a
structured representation
- * of a memory pool in the future. Please try to use this alias instead of
ffi::String to aid future
- * code migration.
- */
-using MemoryScope = ffi::String;
-
-// NOTE: cannot use enum as they are out of bound of the original enum
-// and results in an undefined behavior
-// A 'null' device type, does not correspond to any DLDeviceType enum.
-// TODO(mbs): This is to help us as we transition away from representing the
'homogenous' case
-// as a singleton target map indexed by the invalid DLDeviceType '0'.
-constexpr int kNullDeviceType = 0;
-
-// An 'invalid' device type, does not correspond to any DLDeviceType enum.
-constexpr int kInvalidDeviceType = -1;
-
-/*!
- * \brief Describes at compile time the constraints on where data is to be
stored at runtime
- * down to the (virtual) device and memory scope level, and how to compile
code to compute that
- * data. Used by the \p PlanDevices pass to collect and solve (virtual) device
constraints for
- * the whole Relax program.
- *
- * Is a quadruple of:
- * - A \p device_type (\p DLDeviceType). May be \p kInvalidDeviceType if
unconstrained.
- * - A \p virtual_device_id (\p int). This allows us to distinguish distinct
devices
- * with the same \p Target, for example in a multi-GPU system. May be -1 if
unconstrained.
- * See "Virtual Devices" below.
- * - A \p target (\p Target) describing how to compile code for the intended
device. May be null
- * if unconstrained.
- * - A \p memory_scope (\p MemoryScope, which is currently just \p String)
describing which memory
- * area is to be used to hold data. May be "" if unconstrained. See "Memory
Scopes and Devices"
- * below.
- *
- * Some or all of these fields may be unconstrained, signaling that device
planning is free to
- * choose a value consistent with the whole program. However if a \p target is
given then the \p
- * device_type must equal \p target->GetTargetDeviceType().
- *
- * Note that currently we assume if a function returns its result on a
particular (virtual) device
- * then the function body is also executed on that device.
- *
- *
- * By 'execution' we include both (fused) primitive operators, and all the
Relax expressions
- * surrounding them which coordinates data and control flow. Again, typically
non-primitive
- * operators must be executed on a 'CPU'-like device with good support for
control flow.
- *
- * Since TVM targets such a wide range of systems it is not possible for \p
VirtualDevice to impose
- * much semantics on these fields, particularly for \p virtual_device_id and
\p memory_scope.
- * Instead we assume downstream passes and codegen will interpret an validate
these fields
- * appropriately.
- *
- * Targets vs Devices
- * ------------------
- * Generally \p Targets (a compile-time only datastructue) describe compiler
options for a specific
- * microarchitecture and toolchain, while \p Devices (a runtime datastructure
also available at
- * compile time) describe a physical device on the target system. Obviously
the target must agree
- * with the device's microarchitecture, but we otherwise don't impose any
constraints between them:
- * - It's ok to use different \p Targets for the same \p Device, eg to
squeeze some extra perf
- * out of a particular primitive using particular compiler flags.
- * - It's ok to use the same \p Target for multiple \p Devices, eg if we have
multiple CPUs.
- *
- * Traditionally TVM assumes at most one \p Target per \p DLDeviceType. We are
moving away from that
- * assumption.
- *
- * Virtual vs Physical Devices
- * ---------------------------
- * The \p virtual_device_id may be used by downstream passes or the runtime to
help decide which
- * \p device_id to use for a particular physical runtime \p Device. For
example:
- * - Some runtimes may support passing in an array of actual `device`
specifications, and the
- * \p virtual_device_id can be used at runtime as an index into that array.
- * - Some runtimes may support dynamically allocating computations to
physical devices. On these
- * systems a large space of \p virtual_device_ids could be used at compile
time, even though
- * at runtime only a few physical devices will be present.
- *
- * The \p virtual_device_id may also be left unconstrained if not needed.
- *
- * Memory Scopes and Devices
- * -------------------------
- * Multi-device systems can have complex memory hierarchies. For example
- * \code
- * (kDLCPU, 0, "llvm", "global")
- * \endcode
- * and
- * \code
- * (kDLCPU, 1, "llvm", "global")
- * \endcode
- * could denote:
- * - The same memory area accessible from two separate CPUs without any CPU
affinity;
- * - Distinct memory areas in a NUMA architecture for which cross-device
access is handled
- * by the memory system;
- * - Outright distinct memory areas, where one device cannot directly address
the memory of
- * another.
- *
- * Similarly:
- * \code
- * (kDLCPU, 0, "llvm", "global")
- * \endcode
- * and
- * \code
- * (kDLCUDA, 0, "cuda", "host")
- * \endcode
- * could denote the same memory area, but with very different access costs.
- *
- * Furthermore, not all memory scopes are accessible to all devices, and it is
possible for
- * a memory scope to only be accessible to a device when code is compiled with
particular
- * \p Target options.
- *
- * \p VirtualDevices themselves have no system-level understanding. Currently
the \p PlanDevices
- * pass will simply insert "device_copy" operators wherever \p VirtualDevices
are not exactly
- * pointwise equal. We may revisit this in the future as the work on memory
pools matures.
- *
- * Joining and Defaulting
- * ----------------------
- * It is possible to 'join' two \p VirtualDevices to yield the most
constrained \p VirtualDevice
- * which agrees with both join arguments. Eg:
- * \code
- * Join((kDLCPU, -1, "llvm", ""), (kInvalidDeviceType, 3, null, "global))
- * => (kDLCPU, 3, "llvm", "global")
- * Join((kDLCPU, -1, "llvm", ""), (kInvalidDeviceType, 3, null, "local))
- * => null (no join possible)
- * \endcode
- *
- * Related to 'join' is 'default', which only takes constrained fields from
the rhs when the
- * lhs is unconstrained:
- * \code
- * Default(kDLCPU, -1, "llvm", "local"), (kDLCPU, 3, null, "global"))
- * => (kDLCPU, 3, "llvm", "local")
- * \endcode
- *
- * These operations are needed during device planning.
- */
-
-class VirtualDeviceNode : public AttrsNode {
- private:
- /*!
- * \brief The \p DLDeviceType (represented as an int) of the virtual device.
If \p target is
- * known then this will be equal to \p target->GetTargetDeviceType(). If \p
target is null then
- * the target is to be determined later.
- *
- * This is needed to support the legacy "on_device" and "device_copy" calls
which only allow
- * a \p DLDeviceTypes (as an integer) to be given.
- *
- * kInvalidDeviceType denotes unconstrained. An int since the DLDeviceType
enum representation
- * is not fixed. Private to discourage further int vs DLDeviceType confusion.
- */
- int /* actually DLDeviceType */ device_type_int;
-
- public:
- DLDeviceType device_type() const { return
static_cast<DLDeviceType>(device_type_int); }
-
- /*!
- * \brief The device identifier for the virtual device. This must be
resolved to a physical
- * device identifier either during compilation or at runtime.
- *
- * -1 denotes unconstrained.
- */
- int virtual_device_id;
-
- /*!
- * \brief The \p Target describing how to compile for the virtual device.
- *
- * Null denotes unconstrained. Note that if a target later becomes known for
this \p VirtualDevice
- * then it must be consistent with the \p device_type if already known. This
is enforced by the
- * Join and Default methods.
- */
- Target target;
-
- /*!
- * \brief The scope of memory w.r.t. the virtual device which holds data.
- *
- * Empty denotes unconstrained.
- */
- MemoryScope memory_scope;
-
- /*!
- * \brief Returns true if virtual device is 'fully unconstrained', ie no
target/device type,
- * device id or memory scope is specified.
- */
- bool IsFullyUnconstrained() const {
- return !target.defined() && device_type() == kInvalidDeviceType &&
virtual_device_id == -1 &&
- memory_scope.empty();
- }
-
- /*!
- * \brief Returns true if virtual device is 'fully constrained', ie target,
device id and memory
- * scope are all specified.
- */
- bool IsFullyConstrained() const {
- return target.defined() && virtual_device_id != -1 &&
!memory_scope.empty();
- }
-
- /*!
- * \brief Returns the (virtual) \p Device implied by this \p VirtualDevice.
Both the \p
- * device_type and \p virtual_device_must be constrained. The returned \p
Device may not
- * correspond to any physical device available at compile time or even
runtime: see "Virtual vs
- * Physical Devices" above.
- */
- Device ToDevice() const {
- TVM_FFI_ICHECK(device_type_int != kInvalidDeviceType);
- TVM_FFI_ICHECK(virtual_device_id != -1);
- Device device;
- device.device_type = device_type();
- device.device_id = virtual_device_id;
- return device;
- }
-
- static void RegisterReflection() {
- namespace refl = tvm::ffi::reflection;
- refl::ObjectDef<VirtualDeviceNode>()
- .def_ro("device_type_int", &VirtualDeviceNode::device_type_int,
- "The type of the virtual device.",
refl::DefaultValue(kInvalidDeviceType))
- .def_ro("virtual_device_id", &VirtualDeviceNode::virtual_device_id,
- "The device id of the virtual device.", refl::DefaultValue(-1))
- .def_ro("target", &VirtualDeviceNode::target,
- "The target describing how to compile for the virtual device.",
- refl::DefaultValue(Target()))
- .def_ro("memory_scope", &VirtualDeviceNode::memory_scope,
- "The area of memory w.r.t. the virtual device where data is
stored.",
- refl::DefaultValue(""));
- }
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("target.VirtualDevice", VirtualDeviceNode,
AttrsNode);
-
- friend class VirtualDevice;
-};
-
-/*!
- * \brief Managed reference class to \p VirtualDeviceNode.
- */
-class VirtualDevice : public ffi::ObjectRef {
- public:
- /*!
- * \brief Construct a virtual device.
- * \param device_type_int The device type for the virtual device, or \p
kInvalidDeviceType if
- * unconstrained. If \p target is defined then must match its \p
target->GetTargetDeviceType().
- * \param virtual_device_id The device id for the virtual device, or -1 if
unconstrained.
- * \param target The target describing how to compile for the virtual
device, or null if
- * unconstrained.
- * \param memory_scope The memory scope w.r.t. the virtual device which
holds data, or "" if
- * unconstrained.
- */
- TVM_DLL explicit VirtualDevice(int device_type_int = kInvalidDeviceType,
- int virtual_device_id = -1, Target target =
{},
- MemoryScope memory_scope = {});
-
- /*! \brief Returns the unique fully unconstrained \p VirtualDevice. */
- static VirtualDevice FullyUnconstrained();
-
- /*!
- * \brief Returns the \p VirtualDevice for \p device_type and (if not -1) \p
virtual_device_id.
- * The target and memory scope will be unconstrained.
- */
- static VirtualDevice ForDeviceType(DLDeviceType device_type, int
virtual_device_id = -1) {
- TVM_FFI_ICHECK_GT(device_type, 0);
- return VirtualDevice(device_type, virtual_device_id);
- }
- static VirtualDevice ForDeviceType(int device_type, int virtual_device_id =
-1) {
- return ForDeviceType(static_cast<DLDeviceType>(device_type),
virtual_device_id);
- }
- static VirtualDevice ForDeviceType(int64_t device_type, int
virtual_device_id = -1) {
- return ForDeviceType(static_cast<int>(device_type), virtual_device_id);
- }
-
- /*! \brief Returns the \p VirtualDevice for \p device. */
- static VirtualDevice ForDevice(const Device& device) {
- return ForDeviceType(device.device_type, device.device_id);
- }
-
- /*! \brief Returns the \p VirtualDevice for \p device and \p target. */
- static VirtualDevice ForDeviceAndTarget(const Device& device, Target target)
{
- return VirtualDevice(device.device_type, device.device_id,
std::move(target));
- }
-
- /*! \brief Returns the \p VirtualDevice for \p target. */
- static VirtualDevice ForTarget(Target target) {
- DLDeviceType device_type =
static_cast<DLDeviceType>(target->GetTargetDeviceType());
- return VirtualDevice(device_type, /*virtual_device_id=*/0,
std::move(target));
- }
-
- /*! \brief Returns the \p VirtualDevice for \p memory_scope alone. */
- static VirtualDevice ForMemoryScope(MemoryScope memory_scope) {
- return VirtualDevice(kInvalidDeviceType, -1, {}, std::move(memory_scope));
- }
-
- /*! \brief Returns the \p VirtualDevice for \p device, \p target and \p
memory_scope. */
- TVM_DLL static VirtualDevice ForDeviceTargetAndMemoryScope(const Device&
device, Target target,
- MemoryScope
memory_scope) {
- return VirtualDevice(device.device_type, device.device_id,
std::move(target),
- std::move(memory_scope));
- }
-
- /*!
- * \brief Returns the 'join' of \p lhs and \p rhs. The result will agree
pointwise with
- * \p lhs and \p rhs on all their constrained fields. Returns the null
optional if no such
- * join exists, ie there's disagreement on at least one constrained field.
- */
- TVM_DLL static ffi::Optional<VirtualDevice> Join(const VirtualDevice& lhs,
- const VirtualDevice& rhs);
-
- /*!
- * \brief Returns the 'default' of \p lhs and \p rhs. The result will be \p
lhs, except any
- * unconstrained fields in \p lhs will take their value from \p rhs. Always
well-defined.
- */
- TVM_DLL static VirtualDevice Default(const VirtualDevice& lhs, const
VirtualDevice& rhs);
-
- TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(VirtualDevice, ffi::ObjectRef,
VirtualDeviceNode);
-
- friend class VirtualDeviceCache; // Private implementation helper.
-};
-
-/*!
- * \brief A cache of \p VirtualDevices. This can be used:
- * - To avoid ending up with lots of identical instances, since the space of
VirtualDevices for any
- * one compilation is very small but the number of points they need to be
constructed can
- * be very large (eg during device planning).
- * - So we can assume \p VirtualDevices are pointer equal if and only if they
are structurally
- * equal. This simplifies the unification of 'device domains' which are built
on \p VirtualDevices.
- */
-class TVM_DLL VirtualDeviceCache {
- public:
- /*! \brief Returns the unique \p VirtualDevice representing given fields. */
- VirtualDevice Make(int device_type = kInvalidDeviceType, int
virtual_device_id = -1,
- Target target = {}, MemoryScope memory_scope = {});
-
- /*!
- * \brief Returns the unique \p VirtualDevice structurally equal to the
given \p virtual_device.
- */
- VirtualDevice Unique(const VirtualDevice& virtual_device);
-
- private:
- /*! \brief Already constructed VirtualDevices. */
- std::unordered_set<VirtualDevice, ffi::StructuralHash, ffi::StructuralEqual>
cache_;
-};
-
-/*! brief The attribute key for the virtual device. This key will be promoted
to first class on
- * functions. For use in the parser and printer only.
- *
- * Type: VirtualDevice
- */
-constexpr const char* kVirtualDevice = "virtual_device";
-
-} // namespace tvm
-
-#endif // TVM_TARGET_VIRTUAL_DEVICE_H_
diff --git a/include/tvm/tirx/layout.h b/include/tvm/tirx/layout.h
index 1580338ac4..529ea35823 100644
--- a/include/tvm/tirx/layout.h
+++ b/include/tvm/tirx/layout.h
@@ -29,6 +29,7 @@
#include <tvm/ffi/object.h>
#include <tvm/ir/attr_registry_map.h>
#include <tvm/ir/module.h>
+#include <tvm/target/target.h>
#include <tvm/tirx/exec_scope.h>
#include <tvm/tirx/var.h>
diff --git a/python/tvm/ir/__init__.py b/python/tvm/ir/__init__.py
index 977ec90dcc..bfb378d3bd 100644
--- a/python/tvm/ir/__init__.py
+++ b/python/tvm/ir/__init__.py
@@ -50,7 +50,7 @@ from .expr import (
is_prim_var,
)
from .function import BaseFunc, CallingConv
-from .global_info import GlobalInfo, DummyGlobalInfo, VDevice
+from .global_info import GlobalInfo
from .module import IRModule
from .op import Op, register_intrin_lowering, register_op_attr
diff --git a/python/tvm/ir/global_info.py b/python/tvm/ir/global_info.py
index a9198afac7..a964d4b2e5 100644
--- a/python/tvm/ir/global_info.py
+++ b/python/tvm/ir/global_info.py
@@ -18,10 +18,7 @@
import tvm_ffi
-import tvm
-from tvm.runtime import Device, Object
-
-from . import _ffi_api
+from tvm.runtime import Object
@tvm_ffi.register_object("ir.GlobalInfo")
@@ -38,30 +35,3 @@ class GlobalInfo(Object):
def same_as(self, other):
"""Overload with structural equality."""
return super().__eq__(other)
-
-
-@tvm_ffi.register_object("ir.DummyGlobalInfo")
-class DummyGlobalInfo(GlobalInfo):
- """DummyGlobalInfo"""
-
- def __init__(self) -> None:
- self.__init_handle_by_constructor__(
- _ffi_api.DummyGlobalInfo,
- )
-
-
-@tvm_ffi.register_object("ir.VDevice")
-class VDevice(GlobalInfo):
- """VDevice"""
-
- def __init__(
- self,
- target=None,
- vdevice_id: int = 0,
- memory_scope: str = "global",
- ) -> None:
- if isinstance(target, dict | str):
- target = tvm.target.Target(tvm.runtime.convert(target))
- if isinstance(target, Device):
- target = tvm.target.Target.from_device(target)
- self.__init_handle_by_constructor__(_ffi_api.VDevice, target,
vdevice_id, memory_scope)
diff --git a/python/tvm/relax/__init__.py b/python/tvm/relax/__init__.py
index c28ca1b2c0..fa3850c23d 100644
--- a/python/tvm/relax/__init__.py
+++ b/python/tvm/relax/__init__.py
@@ -22,6 +22,9 @@ from tvm.runtime import vm
from tvm.runtime.vm import VirtualMachine, VMInstrumentReturnKind
from tvm.ir import Call
+# Global information
+from .global_info import DummyGlobalInfo, VDevice
+
# Expr
from .expr import (
Expr,
diff --git a/python/tvm/target/virtual_device.py
b/python/tvm/relax/global_info.py
similarity index 51%
rename from python/tvm/target/virtual_device.py
rename to python/tvm/relax/global_info.py
index 37b888196b..2eacc8b072 100644
--- a/python/tvm/target/virtual_device.py
+++ b/python/tvm/relax/global_info.py
@@ -14,26 +14,39 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-# ruff: noqa: F821
-"""Python bindings for creating VirtualDevices."""
+"""Global information used by Relax."""
import tvm_ffi
+import tvm
+from tvm.ir import GlobalInfo
+from tvm.runtime import Device
+
from . import _ffi_api
-@tvm_ffi.register_object("target.VirtualDevice")
-class VirtualDevice(tvm_ffi.core.Object):
- """A compile time representation for where data is to be stored at runtime,
- and how to compile code to compute it."""
+@tvm_ffi.register_object("relax.DummyGlobalInfo")
+class DummyGlobalInfo(GlobalInfo):
+ """DummyGlobalInfo"""
- def __init__(self, device=None, target=None, memory_scope="") -> None:
- if device is None:
- # The 'unconstrained' device has device type -1 and device id -1.
- device = tvm.device(-1, -1)
+ def __init__(self) -> None:
self.__init_handle_by_constructor__(
- _ffi_api.VirtualDevice_ForDeviceTargetAndMemoryScope, device,
target, memory_scope
+ _ffi_api.DummyGlobalInfo,
)
- def dlpack_device_type(self) -> int:
- return self.device_type_int
+
+@tvm_ffi.register_object("relax.VDevice")
+class VDevice(GlobalInfo):
+ """VDevice"""
+
+ def __init__(
+ self,
+ target=None,
+ vdevice_id: int = 0,
+ memory_scope: str = "global",
+ ) -> None:
+ if isinstance(target, dict | str):
+ target = tvm.target.Target(tvm.runtime.convert(target))
+ if isinstance(target, Device):
+ target = tvm.target.Target.from_device(target)
+ self.__init_handle_by_constructor__(_ffi_api.VDevice, target,
vdevice_id, memory_scope)
diff --git a/python/tvm/relax/script/builder/ir.py
b/python/tvm/relax/script/builder/ir.py
index 1f19fbb05b..e3f7c5518a 100644
--- a/python/tvm/relax/script/builder/ir.py
+++ b/python/tvm/relax/script/builder/ir.py
@@ -25,7 +25,7 @@ from typing import Any
import tvm
from tvm import DataType, relax
-from tvm.ir import IRModule, VDevice
+from tvm.ir import IRModule
from tvm.relax import (
Call,
Expr,
@@ -38,6 +38,7 @@ from tvm.relax import (
const,
)
from tvm.relax.dpl import PatternMatchingRewriter
+from tvm.relax.global_info import VDevice
############################### Operators ###############################
from tvm.relax.op import (
diff --git a/python/tvm/relax/transform/transform.py
b/python/tvm/relax/transform/transform.py
index ff4601290a..a28943db1e 100644
--- a/python/tvm/relax/transform/transform.py
+++ b/python/tvm/relax/transform/transform.py
@@ -36,6 +36,7 @@ from tvm.runtime import Object, Tensor
from tvm.tirx import IndexMap, PrimFunc
from ..expr import Var
+from ..global_info import VDevice
from . import _ffi_api
from .legalize_ops.common import LegalizeFunc
@@ -483,12 +484,12 @@ def EliminateCommonSubexpr(call_only=False) ->
FunctionPass:
return _ffi_api.EliminateCommonSubexpr(call_only) # type: ignore
-def UpdateVDevice(new_vdevice: tvm.ir.VDevice, index: int) ->
tvm.ir.transform.Pass:
+def UpdateVDevice(new_vdevice: VDevice, index: int) -> tvm.ir.transform.Pass:
"""Update virtual device.
Parameters
----------
- new_vdevice : tvm.ir.VDevice
+ new_vdevice : tvm.relax.VDevice
The new virtual device.
index : int
The device index indicates the device on which the update will be
performed.
diff --git a/python/tvm/relax/type.py b/python/tvm/relax/type.py
index 98f34d06f0..b5018ec7ea 100644
--- a/python/tvm/relax/type.py
+++ b/python/tvm/relax/type.py
@@ -21,7 +21,8 @@
import tvm_ffi
from tvm_ffi import Array
-from tvm.ir import EnvFunc, PrimType, Span, TupleType, VDevice
+from tvm.ir import EnvFunc, PrimType, Span, TupleType
+from tvm.relax.global_info import VDevice
from . import _ffi_api
from .expr import Expr, ShapeExpr, Type
diff --git a/python/tvm/relax/utils.py b/python/tvm/relax/utils.py
index 78af8ac6b9..91ff545bb7 100644
--- a/python/tvm/relax/utils.py
+++ b/python/tvm/relax/utils.py
@@ -29,9 +29,10 @@ import tvm_ffi
from tvm_ffi import Array, Map
import tvm
+from tvm.relax.global_info import VDevice
from .. import tirx
-from ..ir import Attrs, Type, VDevice
+from ..ir import Attrs, Type
from ..te import Tensor as te_Tensor
from ..te import create_prim_func
from . import _ffi_api
diff --git a/python/tvm/script/ir_builder/ir/ir.py
b/python/tvm/script/ir_builder/ir/ir.py
index a61ad3c344..e2810ce698 100644
--- a/python/tvm/script/ir_builder/ir/ir.py
+++ b/python/tvm/script/ir_builder/ir/ir.py
@@ -18,13 +18,15 @@
from typing import TYPE_CHECKING, Any, TypeVar
-from tvm.ir import BaseFunc, DummyGlobalInfo, GlobalInfo, GlobalVar, VDevice
+from tvm.ir import BaseFunc, GlobalInfo, GlobalVar
from tvm.runtime import Object as tvm_Object
from . import _ffi_api
from .frame import IRModuleFrame
if TYPE_CHECKING:
+ from tvm.relax import DummyGlobalInfo, VDevice
+
T = TypeVar("T")
def meta_var(value: T) -> T:
@@ -162,17 +164,19 @@ def module_global_infos(global_infos: dict[str,
list[GlobalInfo]]) -> None:
############################### GlobalInfo ###############################
-def dummy_global_info() -> DummyGlobalInfo:
+def dummy_global_info() -> "DummyGlobalInfo":
"""Create a dummy global info expression.
Returns
-------
res : DummyGlobalInfo
The result dummy global info.
"""
+ from tvm.relax import DummyGlobalInfo # pylint:
disable=import-outside-toplevel
+
return DummyGlobalInfo() # type: ignore[attr-defined] # pylint:
disable=no-member
-def vdevice(target=None, vdevice_id: int = 0, memory_scope: str = "global") ->
VDevice:
+def vdevice(target=None, vdevice_id: int = 0, memory_scope: str = "global") ->
"VDevice":
"""Create a virtual device global info.
Parameters
----------
@@ -188,10 +192,12 @@ def vdevice(target=None, vdevice_id: int = 0,
memory_scope: str = "global") -> V
res : VDevice
The result virtual device.
"""
+ from tvm.relax import VDevice # pylint: disable=import-outside-toplevel
+
return VDevice(target, vdevice_id, memory_scope) # type:
ignore[attr-defined] # pylint: disable=no-member
-def lookup_vdevice(target_kind: str | None = None, device_index: int = -1) ->
VDevice:
+def lookup_vdevice(target_kind: str | None = None, device_index: int = -1) ->
"VDevice":
"""Retrieve a virtual device from the globalinfo vdevice list.
Parameters
----------
diff --git a/python/tvm/target/__init__.py b/python/tvm/target/__init__.py
index 7303a0d097..20e26bccf3 100644
--- a/python/tvm/target/__init__.py
+++ b/python/tvm/target/__init__.py
@@ -32,7 +32,6 @@ and :py:func:`tvm.target.register_tag` to register new tags.
"""
from .target import Target, TargetKind
-from .virtual_device import VirtualDevice
from .tag import list_tags, register_tag
from . import codegen
from . import tag_registry # registers tags on import
diff --git a/src/ir/global_info.cc b/src/relax/ir/global_info.cc
similarity index 85%
rename from src/ir/global_info.cc
rename to src/relax/ir/global_info.cc
index d8bba04c51..751e6d3186 100644
--- a/src/ir/global_info.cc
+++ b/src/relax/ir/global_info.cc
@@ -18,13 +18,14 @@
*/
/*!
- * \file src/ir/global_info.cc
+ * \file src/relax/ir/global_info.cc
* \brief Module global info.
*/
#include <tvm/ffi/reflection/registry.h>
-#include <tvm/ir/global_info.h>
+#include <tvm/relax/global_info.h>
namespace tvm {
+namespace relax {
TVM_FFI_STATIC_INIT_BLOCK() {
VDeviceNode::RegisterReflection();
@@ -33,7 +34,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("ir.DummyGlobalInfo", []() {
+ refl::GlobalDef().def("relax.DummyGlobalInfo", []() {
auto n = DummyGlobalInfo(ffi::make_object<DummyGlobalInfoNode>());
return n;
});
@@ -49,8 +50,9 @@ VDevice::VDevice(Target tgt, int dev_id, MemoryScope
mem_scope) {
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("ir.VDevice", [](Target tgt, int dev_id, MemoryScope
mem_scope) {
+ refl::GlobalDef().def("relax.VDevice", [](Target tgt, int dev_id,
MemoryScope mem_scope) {
return VDevice(tgt, dev_id, mem_scope);
});
}
+} // namespace relax
} // namespace tvm
diff --git a/src/relax/script/printer/call.cc b/src/relax/script/printer/call.cc
index fd79de5472..628cbfa5f8 100644
--- a/src/relax/script/printer/call.cc
+++ b/src/relax/script/printer/call.cc
@@ -210,7 +210,7 @@ ffi::Optional<ExprDoc> PrintToVDevice(const Call& n, const
AccessPath& n_p, cons
ffi::Array<ExprDoc> kwargs_values;
TVM_FFI_ICHECK(n->attrs.defined());
if (const auto* attrs = n->attrs.as<relax::ToVDeviceAttrs>()) {
- VDevice vdev = attrs->dst_vdevice;
+ relax::VDevice vdev = attrs->dst_vdevice;
std::string dev_kind = vdev->target->kind->name;
int dev_index = FindVDeviceIndexByTargetKind(vdev, d);
kwargs_keys.push_back("dst_vdevice");
diff --git a/src/relax/script/printer/utils.h b/src/relax/script/printer/utils.h
index cb7c8c4b46..c83e15fe2c 100644
--- a/src/relax/script/printer/utils.h
+++ b/src/relax/script/printer/utils.h
@@ -143,11 +143,11 @@ Doc PrintRelaxVar(tvm::Var n, AccessPath p, IRDocsifier
d);
ExprDoc PrintShapeVar(const PrimExpr& e, const AccessPath& e_p, const
IRDocsifier& d);
-inline int FindVDeviceIndexByTargetKind(const VDevice& vdevice, const
IRDocsifier& d) {
+inline int FindVDeviceIndexByTargetKind(const relax::VDevice& vdevice, const
IRDocsifier& d) {
ffi::Array<GlobalInfo> vdevices = d->global_infos["vdevice"];
int kind_index = 0;
for (size_t i = 0; i < vdevices.size(); ++i) {
- auto vdev = vdevices[i].as_or_throw<VDevice>();
+ auto vdev = vdevices[i].as_or_throw<relax::VDevice>();
if (vdev.same_as(vdevice)) {
return kind_index;
}
diff --git a/src/script/ir_builder/ir/ir.cc b/src/script/ir_builder/ir/ir.cc
index ab9c0e935f..872a9f851f 100644
--- a/src/script/ir_builder/ir/ir.cc
+++ b/src/script/ir_builder/ir/ir.cc
@@ -19,6 +19,7 @@
#include <tvm/ffi/function.h>
#include <tvm/ffi/reflection/registry.h>
#include <tvm/ir/module.h>
+#include <tvm/relax/global_info.h>
#include <tvm/runtime/logging.h>
#include <tvm/script/ir_builder/ir/ir.h>
@@ -150,7 +151,7 @@ void ModuleGlobalInfos(ffi::Map<ffi::String,
ffi::Array<GlobalInfo>> global_info
}
}
-VDevice LookupVDevice(ffi::String target_kind, int device_index) {
+relax::VDevice LookupVDevice(ffi::String target_kind, int device_index) {
if (IRBuilder::IsInScope()) {
IRModuleFrame frame = FindModuleFrame();
if (frame->global_infos.empty()) {
@@ -162,11 +163,11 @@ VDevice LookupVDevice(ffi::String target_kind, int
device_index) {
TVM_FFI_THROW(ValueError) << "The target VDevice in the GlobalInfos was
not found.";
}
if (target_kind == "vdevice") {
- return vdevices[device_index].as_or_throw<VDevice>();
+ return vdevices[device_index].as_or_throw<relax::VDevice>();
}
int count = 0;
for (auto vdevice : vdevices) {
- auto vdev = vdevice.as_or_throw<VDevice>();
+ auto vdev = vdevice.as_or_throw<relax::VDevice>();
if (vdev->target->kind->name == target_kind) {
if (count == device_index) {
return vdev;
@@ -176,7 +177,7 @@ VDevice LookupVDevice(ffi::String target_kind, int
device_index) {
}
}
LOG(WARNING) << "The annotated device was not found, please check your
vdevice list.";
- return VDevice();
+ return relax::VDevice();
}
bool LookupName(const ffi::String& name) {
diff --git a/src/script/printer/ir/ir.cc b/src/script/printer/ir/ir.cc
index a2f1237210..11d4811cf8 100644
--- a/src/script/printer/ir/ir.cc
+++ b/src/script/printer/ir/ir.cc
@@ -17,6 +17,7 @@
* under the License.
*/
#include <tvm/ir/type.h>
+#include <tvm/relax/global_info.h>
#include "./utils.h"
@@ -171,15 +172,15 @@ TVM_FFI_STATIC_INIT_BLOCK() {
}
TVM_FFI_STATIC_INIT_BLOCK() {
- IRDocsifier::vtable().set_dispatch<DummyGlobalInfo>(
+ IRDocsifier::vtable().set_dispatch<relax::DummyGlobalInfo>(
"", [](GlobalInfo ginfo, AccessPath p, IRDocsifier d) -> Doc {
return IR(d, "dummy_global_info")->Call({});
});
}
TVM_FFI_STATIC_INIT_BLOCK() {
- IRDocsifier::vtable().set_dispatch<VDevice>(
- "", [](VDevice vdev, AccessPath p, IRDocsifier d) -> Doc {
+ IRDocsifier::vtable().set_dispatch<relax::VDevice>(
+ "", [](relax::VDevice vdev, AccessPath p, IRDocsifier d) -> Doc {
d->AddGlobalInfo("vdevice", vdev);
ffi::Map<ffi::String, ffi::Any> config = vdev->target->ToConfig();
return IR(d, "vdevice")
diff --git a/src/target/virtual_device.cc b/src/target/virtual_device.cc
deleted file mode 100644
index 92803cd143..0000000000
--- a/src/target/virtual_device.cc
+++ /dev/null
@@ -1,201 +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 tvm/target/virtual_device.cc
- * \brief A compile time representation for where data is to be stored at
runtime, and how to
- * compile code to compute it.
- */
-#include <tvm/ffi/reflection/registry.h>
-#include <tvm/runtime/device_api.h>
-#include <tvm/target/virtual_device.h>
-
-#include <sstream>
-
-namespace tvm {
-
-VirtualDevice::VirtualDevice(int device_type_int, int virtual_device_id,
Target target,
- MemoryScope memory_scope) {
- TVM_FFI_ICHECK(!target.defined() || device_type_int ==
target->GetTargetDeviceType())
- << "target " << target->str() << " has device type " <<
target->GetTargetDeviceType()
- << " but virtual device has device type " << device_type_int;
- auto node = ffi::make_object<VirtualDeviceNode>();
- node->device_type_int = device_type_int;
- node->virtual_device_id = virtual_device_id;
- node->target = std::move(target);
- node->memory_scope = std::move(memory_scope);
- data_ = std::move(node);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- VirtualDeviceNode::RegisterReflection();
- refl::TypeAttrDef<VirtualDeviceNode>().def(
- refl::type_attr::kRepr, [](VirtualDevice vd, ffi::Function fn_repr) ->
ffi::String {
- auto* node = vd.get();
- std::ostringstream os;
- os << "VirtualDevice(";
- if (node->IsFullyUnconstrained()) {
- os << "?";
- } else {
- bool need_sep = false;
- if (node->device_type() != kInvalidDeviceType) {
- os << "device_type=" << node->device_type();
- need_sep = true;
- }
- if (node->virtual_device_id >= 0) {
- if (need_sep) os << ", ";
- os << "virtual_device_id=" << node->virtual_device_id;
- need_sep = true;
- }
- if (node->target.defined()) {
- if (need_sep) os << ", ";
- os << "target=" <<
fn_repr(ffi::AnyView(node->target)).cast<ffi::String>();
- need_sep = true;
- }
- if (!node->memory_scope.empty()) {
- if (need_sep) os << ", ";
- os << "memory_scope='" << node->memory_scope << "'";
- }
- }
- os << ")";
- return os.str();
- });
-}
-
-/* static */ VirtualDevice VirtualDevice::FullyUnconstrained() {
- static const VirtualDevice unconstrained{};
- return unconstrained;
-}
-
-/* static */
-ffi::Optional<VirtualDevice> VirtualDevice::Join(const VirtualDevice& lhs,
- const VirtualDevice& rhs) {
- if (lhs == rhs) {
- return lhs;
- }
- DLDeviceType joined_device_type;
- if (lhs->device_type() != kInvalidDeviceType) {
- joined_device_type = lhs->device_type();
- if (rhs->device_type() != kInvalidDeviceType && lhs->device_type() !=
rhs->device_type()) {
- return {};
- }
- } else {
- joined_device_type = rhs->device_type();
- }
- int joined_virtual_device_id;
- if (lhs->virtual_device_id >= 0) {
- joined_virtual_device_id = lhs->virtual_device_id;
- if (rhs->virtual_device_id >= 0 && lhs->virtual_device_id !=
rhs->virtual_device_id) {
- return {};
- }
- } else {
- joined_virtual_device_id = rhs->virtual_device_id;
- }
- Target joined_target;
- if (lhs->target.defined()) {
- joined_target = lhs->target;
- if (rhs->target.defined() && lhs->target != rhs->target) {
- return {};
- }
- } else {
- joined_target = rhs->target;
- }
- MemoryScope joined_memory_scope;
- if (!lhs->memory_scope.empty()) {
- joined_memory_scope = lhs->memory_scope;
- if (!rhs->memory_scope.empty() && lhs->memory_scope != rhs->memory_scope) {
- return {};
- }
- } else {
- joined_memory_scope = rhs->memory_scope;
- }
- return VirtualDevice(joined_device_type, joined_virtual_device_id,
joined_target,
- joined_memory_scope);
-}
-
-/* static */
-VirtualDevice VirtualDevice::Default(const VirtualDevice& lhs, const
VirtualDevice& rhs) {
- if (lhs == rhs) {
- return lhs;
- }
- DLDeviceType defaulted_device_type;
- if (lhs->device_type() != kInvalidDeviceType) {
- defaulted_device_type = lhs->device_type();
- } else {
- defaulted_device_type = rhs->device_type();
- }
- int defaulted_virtual_device_id;
- if (lhs->virtual_device_id >= 0) {
- defaulted_virtual_device_id = lhs->virtual_device_id;
- } else {
- defaulted_virtual_device_id = rhs->virtual_device_id;
- }
- Target defaulted_target;
- if (lhs->target.defined()) {
- defaulted_target = lhs->target;
- } else {
- // We can only default to the rhs's target if it is consistent with the
device type
- if (rhs->target.defined() && rhs->target->GetTargetDeviceType() ==
defaulted_device_type) {
- defaulted_target = rhs->target;
- }
- // else: leave as null
- }
- MemoryScope defaulted_memory_scope;
- if (!lhs->memory_scope.empty()) {
- defaulted_memory_scope = lhs->memory_scope;
- } else {
- defaulted_memory_scope = rhs->memory_scope;
- }
- return VirtualDevice(defaulted_device_type, defaulted_virtual_device_id,
defaulted_target,
- defaulted_memory_scope);
-}
-
-VirtualDevice VirtualDeviceCache::Make(int device_type, int virtual_device_id,
Target target,
- MemoryScope memory_scope) {
- VirtualDevice prototype(device_type, virtual_device_id, std::move(target),
- std::move(memory_scope));
- if (prototype->IsFullyUnconstrained()) {
- return VirtualDevice::FullyUnconstrained();
- }
- auto itr = cache_.find(prototype);
- if (itr == cache_.end()) {
- cache_.emplace(prototype);
- return prototype;
- } else {
- TVM_FFI_ICHECK_EQ(prototype->target.defined(), (*itr)->target.defined());
- if (prototype->target.defined()) {
- TVM_FFI_ICHECK_EQ(prototype->target->host.has_value(),
(*itr)->target->host.has_value());
- }
- return *itr;
- }
-}
-
-VirtualDevice VirtualDeviceCache::Unique(const VirtualDevice& virtual_device) {
- return Make(virtual_device->device_type(), virtual_device->virtual_device_id,
- virtual_device->target, virtual_device->memory_scope);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("target.VirtualDevice_ForDeviceTargetAndMemoryScope",
- VirtualDevice::ForDeviceTargetAndMemoryScope);
-}
-
-} // namespace tvm
diff --git a/tests/cpp/target/virtual_device_test.cc
b/tests/cpp/target/virtual_device_test.cc
deleted file mode 100644
index 8e2000852d..0000000000
--- a/tests/cpp/target/virtual_device_test.cc
+++ /dev/null
@@ -1,129 +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/target/target.h>
-#include <tvm/target/virtual_device.h>
-
-namespace tvm {
-namespace {
-
-TEST(VirtualDevice, Join_Defined) {
- {
- Target target_a = Target("cuda");
- VirtualDevice lhs = VirtualDevice(kDLCUDA, 3);
- VirtualDevice rhs = VirtualDevice(kDLCUDA, -1, target_a, "global");
- ffi::Optional<VirtualDevice> actual = VirtualDevice::Join(lhs, rhs);
- EXPECT_TRUE(actual.operator bool());
- VirtualDevice expected = VirtualDevice(kDLCUDA, 3, target_a, "global");
- EXPECT_TRUE(tvm::ffi::StructuralEqual()(actual.value(), expected));
- }
- {
- Target target_a = Target("cuda");
- VirtualDevice lhs = VirtualDevice(kDLCUDA, -1, target_a, "global");
- VirtualDevice rhs = VirtualDevice(kDLCUDA, 3);
- ffi::Optional<VirtualDevice> actual = VirtualDevice::Join(lhs, rhs);
- EXPECT_TRUE(actual.operator bool());
- VirtualDevice expected = VirtualDevice(kDLCUDA, 3, target_a, "global");
- EXPECT_TRUE(tvm::ffi::StructuralEqual()(actual.value(), expected));
- }
- {
- Target target_a = Target("cuda");
- VirtualDevice lhs = VirtualDevice(kDLCUDA);
- VirtualDevice rhs = VirtualDevice(kDLCUDA, 2, target_a);
- ffi::Optional<VirtualDevice> actual = VirtualDevice::Join(lhs, rhs);
- EXPECT_TRUE(actual.operator bool());
- VirtualDevice expected = VirtualDevice(kDLCUDA, 2, target_a);
- EXPECT_TRUE(tvm::ffi::StructuralEqual()(actual.value(), expected));
- }
- {
- Target target_a = Target("cuda");
- VirtualDevice lhs = VirtualDevice();
- VirtualDevice rhs = VirtualDevice(kDLCUDA, 3, target_a, "global");
- ffi::Optional<VirtualDevice> actual = VirtualDevice::Join(lhs, rhs);
- EXPECT_TRUE(actual.operator bool());
- VirtualDevice expected = rhs;
- EXPECT_TRUE(tvm::ffi::StructuralEqual()(actual.value(), expected));
- }
-}
-
-TEST(VirtualDevice, Join_Undefined) {
- {
- VirtualDevice lhs = VirtualDevice(kDLCUDA);
- VirtualDevice rhs = VirtualDevice(kDLCPU);
- ffi::Optional<VirtualDevice> actual = VirtualDevice::Join(lhs, rhs);
- EXPECT_FALSE(actual);
- }
- {
- VirtualDevice lhs = VirtualDevice(kDLCUDA, 3);
- VirtualDevice rhs = VirtualDevice(kDLCUDA, 4);
- ffi::Optional<VirtualDevice> actual = VirtualDevice::Join(lhs, rhs);
- EXPECT_FALSE(actual);
- }
- {
- VirtualDevice lhs = VirtualDevice(kDLCUDA, 3, Target("cuda"));
- VirtualDevice rhs = VirtualDevice(kDLCUDA, 3, Target("cuda"));
- ffi::Optional<VirtualDevice> actual = VirtualDevice::Join(lhs, rhs);
- EXPECT_FALSE(actual);
- }
- {
- VirtualDevice lhs = VirtualDevice(kDLCUDA, 3, Target("cuda"), "local");
- VirtualDevice rhs = VirtualDevice(kDLCUDA, 3, Target("cuda"), "global");
- ffi::Optional<VirtualDevice> actual = VirtualDevice::Join(lhs, rhs);
- EXPECT_FALSE(actual);
- }
-}
-
-TEST(VirtualDevice, Default) {
- Target target_a = Target("cuda");
- VirtualDevice lhs = VirtualDevice(kDLCUDA, -1, Target(), "global");
- VirtualDevice rhs = VirtualDevice(kDLCUDA, 3, target_a, "local");
- VirtualDevice actual = VirtualDevice::Default(lhs, rhs);
- VirtualDevice expected = VirtualDevice(kDLCUDA, 3, target_a, "global");
- EXPECT_TRUE(tvm::ffi::StructuralEqual()(actual, expected));
-}
-
-TEST(VirtualDevice, Constructor_Invalid) {
- EXPECT_ANY_THROW(VirtualDevice(kDLCPU, -1, Target("cuda")));
-}
-
-TEST(VirtualDeviceCache, Memoized) {
- VirtualDeviceCache cache;
- Target target_a = Target("cuda");
- Target target_b = Target("llvm");
- Target target_c = Target("cuda");
- VirtualDevice virtual_device_a = cache.Make(kDLCUDA, 3, target_a, "local");
- VirtualDevice virtual_device_b = cache.Make(kDLCPU, 1, target_b, "global");
-
- EXPECT_EQ(cache.Make(kDLCUDA, 3, target_a, "local"), virtual_device_a);
- EXPECT_EQ(cache.Make(kDLCPU, 1, target_b, "global"), virtual_device_b);
- EXPECT_NE(cache.Make(kDLCUDA, 2, target_a, "local"), virtual_device_a);
- EXPECT_NE(cache.Make(kDLCPU, 3, target_b, "local"), virtual_device_a);
- EXPECT_NE(cache.Make(kDLCUDA, 3, target_a, "global"), virtual_device_a);
- EXPECT_EQ(cache.Make(kDLCUDA, 3, Target("cuda"), "local"), virtual_device_a);
- EXPECT_NE(
- cache.Make(kDLCUDA, 3,
- Target(ffi::Map<ffi::String, ffi::Any>{{"kind",
ffi::String("cuda")},
-
{"max_threads_per_block", int64_t(4096)}}),
- "local"),
- virtual_device_a);
-}
-
-} // namespace
-} // namespace tvm
diff --git a/tests/python/relax/test_analysis_type_analysis.py
b/tests/python/relax/test_analysis_type_analysis.py
index a367de212f..b0b6a54aa0 100644
--- a/tests/python/relax/test_analysis_type_analysis.py
+++ b/tests/python/relax/test_analysis_type_analysis.py
@@ -217,11 +217,11 @@ def test_base_check():
shape3 = rx.ShapeType([1, 2, 3])
shape4 = rx.ShapeType([1, n, 3])
- vdevice0 = ir.VDevice()
- vdevice1 = ir.VDevice("llvm")
- vdevice2 = ir.VDevice("cuda", 0)
- vdevice3 = ir.VDevice("cuda", 2)
- vdevice4 = ir.VDevice("cuda", 0, "")
+ vdevice0 = rx.VDevice()
+ vdevice1 = rx.VDevice("llvm")
+ vdevice2 = rx.VDevice("cuda", 0)
+ vdevice3 = rx.VDevice("cuda", 2)
+ vdevice4 = rx.VDevice("cuda", 0, "")
tensor0 = rx.TensorType(ndim=-1, dtype="int32")
tensor1 = rx.TensorType(ndim=-1, dtype="float32")
@@ -414,7 +414,7 @@ def test_derive_call_ret_type():
_check_derive(bb, func0(2), [obj0], obj0)
# Tensor with vdevice
- vdev = ir.VDevice("llvm")
+ vdev = rx.VDevice("llvm")
def func1(c):
n, m = tirx.Var("n", "int64"), tirx.Var("m", "int64")
@@ -520,8 +520,8 @@ def test_type_lca():
prim0 = tvm.ir.PrimType("int32")
prim1 = tvm.ir.PrimType("float32")
- vdevice0 = ir.VDevice("llvm")
- vdevice1 = ir.VDevice("cuda", 0)
+ vdevice0 = rx.VDevice("llvm")
+ vdevice1 = rx.VDevice("cuda", 0)
shape0 = rx.ShapeType(ndim=-1)
shape1 = rx.ShapeType(ndim=2)
diff --git a/tests/python/relax/test_backend_dispatch_sort_scan.py
b/tests/python/relax/test_backend_dispatch_sort_scan.py
index c2dc7ef66a..795a56537e 100644
--- a/tests/python/relax/test_backend_dispatch_sort_scan.py
+++ b/tests/python/relax/test_backend_dispatch_sort_scan.py
@@ -567,7 +567,7 @@ def test_dispatch_cumsum_webgpu_axes_and_dtypes(
):
"""WebGPU dispatch collapses arbitrary-rank scans to the appropriate
kernel."""
- vdevice = tvm.ir.VDevice("webgpu", 0)
+ vdevice = tvm.relax.VDevice("webgpu", 0)
x = relax.Var("x", relax.TensorType(shape, in_dtype, vdevice=vdevice))
bb = relax.BlockBuilder()
with bb.function("main", (x,)):
diff --git a/tests/python/relax/test_op_binary.py
b/tests/python/relax/test_op_binary.py
index e3befa2a97..1c9da199f6 100644
--- a/tests/python/relax/test_op_binary.py
+++ b/tests/python/relax/test_op_binary.py
@@ -22,7 +22,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_create.py
b/tests/python/relax/test_op_create.py
index 0e8d403bae..7d4e3899ec 100644
--- a/tests/python/relax/test_op_create.py
+++ b/tests/python/relax/test_op_create.py
@@ -19,7 +19,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
from tvm.script import tirx as T
diff --git a/tests/python/relax/test_op_image.py
b/tests/python/relax/test_op_image.py
index 1a24b90859..2644e0c3de 100644
--- a/tests/python/relax/test_op_image.py
+++ b/tests/python/relax/test_op_image.py
@@ -24,7 +24,8 @@ pytest.importorskip("scipy") # tvm.topi.testing imports scipy
import tvm.topi.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_index.py
b/tests/python/relax/test_op_index.py
index 2894eb98e7..d586471595 100644
--- a/tests/python/relax/test_op_index.py
+++ b/tests/python/relax/test_op_index.py
@@ -21,7 +21,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import ir as I
from tvm.script import relax as R
from tvm.script import tirx as T
diff --git a/tests/python/relax/test_op_linear_algebra.py
b/tests/python/relax/test_op_linear_algebra.py
index 4b7b50854d..56c75d77f0 100644
--- a/tests/python/relax/test_op_linear_algebra.py
+++ b/tests/python/relax/test_op_linear_algebra.py
@@ -20,7 +20,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_manipulate.py
b/tests/python/relax/test_op_manipulate.py
index 694ec82baf..42ddece4c9 100644
--- a/tests/python/relax/test_op_manipulate.py
+++ b/tests/python/relax/test_op_manipulate.py
@@ -20,7 +20,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
from tvm.script import tirx as T
diff --git a/tests/python/relax/test_op_nn.py b/tests/python/relax/test_op_nn.py
index af4d2c25fc..f605ebf0c6 100644
--- a/tests/python/relax/test_op_nn.py
+++ b/tests/python/relax/test_op_nn.py
@@ -20,7 +20,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_nn_convolution.py
b/tests/python/relax/test_op_nn_convolution.py
index 31f5a15059..766e32cf16 100644
--- a/tests/python/relax/test_op_nn_convolution.py
+++ b/tests/python/relax/test_op_nn_convolution.py
@@ -19,7 +19,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_nn_pooling.py
b/tests/python/relax/test_op_nn_pooling.py
index 159a280283..c933f51b4e 100644
--- a/tests/python/relax/test_op_nn_pooling.py
+++ b/tests/python/relax/test_op_nn_pooling.py
@@ -20,7 +20,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_search.py
b/tests/python/relax/test_op_search.py
index fb3aa91e7e..ebf7eca26e 100644
--- a/tests/python/relax/test_op_search.py
+++ b/tests/python/relax/test_op_search.py
@@ -21,7 +21,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_set.py
b/tests/python/relax/test_op_set.py
index 8239669103..161dd73b9a 100644
--- a/tests/python/relax/test_op_set.py
+++ b/tests/python/relax/test_op_set.py
@@ -19,7 +19,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_sort.py
b/tests/python/relax/test_op_sort.py
index c40b58b899..2176bebc80 100644
--- a/tests/python/relax/test_op_sort.py
+++ b/tests/python/relax/test_op_sort.py
@@ -19,7 +19,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_statistical.py
b/tests/python/relax/test_op_statistical.py
index 06c2dbe055..fb969c3a4e 100644
--- a/tests/python/relax/test_op_statistical.py
+++ b/tests/python/relax/test_op_statistical.py
@@ -21,7 +21,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_ternary.py
b/tests/python/relax/test_op_ternary.py
index 82b6df52f1..21f2eceffc 100644
--- a/tests/python/relax/test_op_ternary.py
+++ b/tests/python/relax/test_op_ternary.py
@@ -19,7 +19,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_op_unary.py
b/tests/python/relax/test_op_unary.py
index 9d2658b32e..8d7e332e91 100644
--- a/tests/python/relax/test_op_unary.py
+++ b/tests/python/relax/test_op_unary.py
@@ -21,7 +21,8 @@ import pytest
import tvm
import tvm.testing
from tvm import relax, tirx
-from tvm.ir import Op, VDevice
+from tvm.ir import Op
+from tvm.relax import VDevice
from tvm.script import relax as R
diff --git a/tests/python/relax/test_relax_operators.py
b/tests/python/relax/test_relax_operators.py
index 437cb33bd3..18f1546ca4 100644
--- a/tests/python/relax/test_relax_operators.py
+++ b/tests/python/relax/test_relax_operators.py
@@ -509,7 +509,7 @@ def test_op_to_vdevice(exec_mode):
@R.function
def to_vdev(x: R.Tensor((3, 4), "float32")):
- dst_vdev = tvm.ir.VDevice("llvm", 0, "global")
+ dst_vdev = tvm.relax.VDevice("llvm", 0, "global")
ret = R.to_vdevice(x, "llvm")
return ret
diff --git a/tests/python/relax/test_transform_realize_vdevice.py
b/tests/python/relax/test_transform_realize_vdevice.py
index fbf4a8a26a..c9d5e2f867 100644
--- a/tests/python/relax/test_transform_realize_vdevice.py
+++ b/tests/python/relax/test_transform_realize_vdevice.py
@@ -19,7 +19,7 @@
import tvm
import tvm.testing
-from tvm.ir import VDevice
+from tvm.relax import VDevice
from tvm.relax.transform import RealizeVDevice
from tvm.script.parser import ir as I
from tvm.script.parser import relax as R
diff --git a/tests/python/relax/test_transform_update_vdevice.py
b/tests/python/relax/test_transform_update_vdevice.py
index 618a286115..48dfa2df7b 100644
--- a/tests/python/relax/test_transform_update_vdevice.py
+++ b/tests/python/relax/test_transform_update_vdevice.py
@@ -18,7 +18,7 @@
import tvm
import tvm.testing
-from tvm.ir import VDevice
+from tvm.relax import VDevice
from tvm.relax.transform import UpdateVDevice
from tvm.script.parser import ir as I
from tvm.script.parser import relax as R
diff --git a/tests/python/relax/test_tvmscript_parser.py
b/tests/python/relax/test_tvmscript_parser.py
index 1e7cddb116..1bff4e99f3 100644
--- a/tests/python/relax/test_tvmscript_parser.py
+++ b/tests/python/relax/test_tvmscript_parser.py
@@ -24,7 +24,7 @@ import tvm
import tvm.script
import tvm.testing
from tvm import IRModule, relax, tirx, topi
-from tvm.ir import DummyGlobalInfo, VDevice
+from tvm.relax import DummyGlobalInfo, VDevice
from tvm.script.parser import ir as I
from tvm.script.parser import relax as R
from tvm.script.parser import tirx as T
diff --git a/tests/python/relax/test_vm_build.py
b/tests/python/relax/test_vm_build.py
index d3537615ff..7a10f81538 100644
--- a/tests/python/relax/test_vm_build.py
+++ b/tests/python/relax/test_vm_build.py
@@ -796,14 +796,14 @@ def test_vm_to_device(exec_mode):
def foo1(
x: R.Tensor((2, 3), "float32"),
) -> R.Tensor((2, 3), "float32"):
- copied = R.to_vdevice(x, tvm.ir.VDevice("cuda", 0, "global"))
+ copied = R.to_vdevice(x, tvm.relax.VDevice("cuda", 0, "global"))
return copied
@R.function
def foo2(
x: R.Tensor((2, 3), "float32"),
) -> R.Tensor((2, 3), "float32"):
- copied = R.to_vdevice(x, tvm.ir.VDevice("llvm", 0, "global"))
+ copied = R.to_vdevice(x, tvm.relax.VDevice("llvm", 0, "global"))
return copied
mod = TestToVDevice
diff --git a/tests/python/target/test_virtual_device.py
b/tests/python/target/test_virtual_device.py
deleted file mode 100644
index b72023b811..0000000000
--- a/tests/python/target/test_virtual_device.py
+++ /dev/null
@@ -1,51 +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.
-# ruff: noqa: F401
-import pytest
-
-import tvm
-import tvm.testing
-
-
-def test_make_virtual_device_for_device():
- virtual_device = tvm.target.VirtualDevice(tvm.cuda())
- assert virtual_device.dlpack_device_type() == 2
- # ie kDLCUDA
- assert virtual_device.virtual_device_id == 0
- assert virtual_device.target is None
- assert virtual_device.memory_scope == ""
-
-
-def test_make_virtual_device_for_device_and_target():
- target = tvm.target.Target("cuda")
- virtual_device = tvm.target.VirtualDevice(tvm.cuda(), target)
- assert virtual_device.dlpack_device_type() == 2 # ie kDLCUDA
- assert virtual_device.target == target
- assert virtual_device.memory_scope == ""
-
-
-def test_make_virtual_device_for_device_target_and_memory_scope():
- target = tvm.target.Target("cuda")
- scope = "local"
- virtual_device = tvm.target.VirtualDevice(tvm.cuda(), target, scope)
- assert virtual_device.dlpack_device_type() == 2 # ie kDLCUDA
- assert virtual_device.target == target
- assert virtual_device.memory_scope == scope
-
-
-if __name__ == "__main__":
- tvm.testing.main()