Struct IValue

Struct Documentation

struct IValue

IValue (Interpreter Value) is a tagged union over the types supported by the TorchScript interpreter.

IValues contain their values as an IValue::Payload, which holds primitive types (int64_t, bool, double, Device) and Tensor as values, and all other types as a c10::intrusive_ptr. In order to optimize performance of the destructor and related operations by making the Tensor and c10::intrusive_ptr paths generate the same code, we represent a null c10::intrusive_ptr as UndefinedTensorImpl::singleton(), not nullptr.

IValues are used as inputs to and outputs from the TorchScript interpreter. To retrieve the value contained within an IValue, use the .toX() methods, where X is the type you are trying to get. Note that neither the .toX() methods nor the templated .to<T> functions do any kind of casting, they only unwrap the contained value. For example:

// Make the IValue
torch::IValue my_ivalue(26);
std::cout << my_ivalue << "\n";

// Unwrap the IValue
int64_t my_int = my_ivalue.toInt();
std::cout << my_int << "\n";

// This will throw an error!
// `my_ivalue` is tagged as an int and cannot be used as another type
torch::Tensor my_tensor = my_ivalue.toTensor();

Public Types

template<class T>
using enable_if_ivalue_constructible = std::enable_if_t<std::is_constructible_v<IValue, T>, std::nullptr_t>
template<class T>
using enable_if_list_is_ivalue_constructible = std::enable_if_t<std::is_constructible_v<IValue, T> && !std::is_same_v<T, c10::SymInt>, std::nullptr_t>
template<class T>
using enable_if_symint = std::enable_if_t<std::is_same_v<T, c10::SymInt>, std::nullptr_t>
template<class T>
using enable_if_ilist_is_ivalue_constructible = std::enable_if_t<std::is_constructible_v<IValue, T> && std::is_constructible_v<IValue, typename IListRef<T>::boxed_type> && !std::is_same_v<T, c10::SymInt>, std::nullptr_t>
using HashAliasedIValues = std::unordered_set<IValue, HashAliasedIValue, CompAliasedIValues>
using HashAliasedIValueMap = std::unordered_map<IValue, IValue, HashAliasedIValue, CompAliasedIValues>
using HashIdentityIValues = std::unordered_set<IValue, HashIdentityIValue, CompIdentityIValues>
using HashIdentityIValueMap = std::unordered_map<IValue, IValue, HashIdentityIValue, CompIdentityIValues>

Public Functions

inline IValue(const IValue &rhs)
inline IValue(IValue &&rhs) noexcept
inline IValue &operator=(IValue &&rhs) & noexcept
inline IValue &operator=(IValue const &rhs) &
void dump() const
IValue equals(const IValue &rhs) const

Equality comparison.

The semantics are the same as Python’s ==:

  1. Numerical types are compared by value.

  2. Tensors compute element-wise equality, returning a BoolTensor (see: torch.eq())

  3. Strings are compared by value.

  4. Sequence types (list, tuple) are compared lexicographically by comparing their elements. Different sequence types never compare equal.

  5. Mappings (dict) must have equal (key, value) pairs.

  6. If not listed above, the default behavior for is to test identity equality (e.g. pointer equality).

Why does this return an IValue instead of a bool? Because in PyTorch, tensor1 == tensor2 returns a BoolTensor, not a bool.

NOTE: we (like Python) assume that identity equality implies value equality for efficiency. TODO: need to support customizing equality

bool is(const IValue &rhs) const

Identity comparison.

Checks if this is the same object as rhs. The semantics are the same as Python’s is operator.

NOTE: Like in Python, this operation is poorly defined for primitive types like numbers and strings. Prefer to use == unless you really want to check identity equality.

inline IValue hash() const

Hashing for IValues.

Returns an IValue-boxed int.

Some notes:

  • Like eager, Tensors are hashed by looking at the pointer. This is not strictly correct because two value-equal tensors with different tensor pointers will hash differently, but we choose to reproduce the eager semantics.

  • Hashing is not defined on all built-in IValue types (e.g. list and dict), following Python. Calling hash() on these types will throw.

inline IValue(at::TensorBase t)
inline bool isTensor() const
at::Tensor toTensor() &&
at::Tensor &toTensor() &
const at::Tensor &toTensor() const &
inline at::TensorImpl *unsafeToTensorImpl() const
inline IValue(at::Storage s)
inline bool isStorage() const
c10::Storage toStorage() &&
c10::Storage toStorage() const &
inline const IValue &toIValue() const
inline IValue &toIValue()
inline bool isCapsule() const
c10::intrusive_ptr<torch::CustomClassHolder> toCapsule() &&
c10::intrusive_ptr<torch::CustomClassHolder> toCapsule() const &
template<typename T, std::enable_if_t<std::is_base_of_v<torch::CustomClassHolder, T>, int> = 0>
IValue(intrusive_ptr<T> custom_class)
bool isCustomClass() const
template<typename T>
c10::intrusive_ptr<T> toCustomClass() &&
template<typename T>
c10::intrusive_ptr<T> toCustomClass() const &
IValue(c10::intrusive_ptr<ivalue::Tuple> v)
template<typename ...Args, std::enable_if_t<!std::disjunction_v<std::is_lvalue_reference<Args>..., std::negation<std::is_constructible<IValue, Args>>...>, std::nullptr_t> = nullptr>
IValue(const std::tuple<Args...> &t)
template<typename ...Args, std::enable_if_t<!std::disjunction_v<std::is_lvalue_reference<Args>..., std::negation<std::is_constructible<IValue, Args>>...>, std::nullptr_t> = nullptr>
IValue(std::tuple<Args...> &&t)
inline bool isTuple() const
c10::intrusive_ptr<ivalue::Tuple> toTuple() &&
c10::intrusive_ptr<ivalue::Tuple> toTuple() const &
ivalue::Tuple &toTupleRef() const
inline IValue(double d)
inline bool isDouble() const
inline double toDouble() const
template<typename T>
IValue(c10::complex<T> c)
inline bool isComplexDouble() const
c10::complex<double> toComplexDouble() const
IValue(c10::intrusive_ptr<ivalue::Future> v)
inline bool isFuture() const
c10::intrusive_ptr<ivalue::Future> toFuture() &&
c10::intrusive_ptr<ivalue::Future> toFuture() const &
IValue(c10::intrusive_ptr<ivalue::Await> v)
inline bool isAwait() const
c10::intrusive_ptr<ivalue::Await> toAwait() &&
c10::intrusive_ptr<ivalue::Await> toAwait() const &
IValue(c10::intrusive_ptr<c10::RRefInterface> v)
inline bool isRRef() const
c10::intrusive_ptr<c10::RRefInterface> toRRef() &&
c10::intrusive_ptr<c10::RRefInterface> toRRef() const &
IValue(c10::intrusive_ptr<at::Quantizer> v)
inline bool isQuantizer() const
c10::intrusive_ptr<at::Quantizer> toQuantizer() &&
c10::intrusive_ptr<at::Quantizer> toQuantizer() const &
inline IValue(int64_t i)
inline IValue(const c10::SymInt &i)
inline bool isSymInt() const
c10::SymInt toSymInt() &&
c10::SymInt toSymInt() const &
inline IValue(const c10::SymFloat &i)
inline bool isSymFloat() const
c10::SymFloat toSymFloat() &&
c10::SymFloat toSymFloat() const &
inline IValue(const c10::SymBool &i)
inline bool isSymBool() const
c10::SymBool toSymBool() &&
c10::SymBool toSymBool() const &
inline IValue(int32_t i)
inline bool isInt() const
inline int64_t toInt() const
inline IValue(bool b)
inline bool isBool() const
inline bool toBool() const
bool isIntList() const
bool isSymIntList() const
c10::List<int64_t> toIntList() &&
c10::List<int64_t> toIntList() const &
std::vector<int64_t> toIntVector() const
std::vector<c10::SymInt> toSymIntVector() const
at::DimVector toDimVector() const
IValue(c10::intrusive_ptr<ivalue::ConstantString> v)
IValue(std::string v)
inline IValue(const char *v)
inline IValue(c10::string_view v)
inline bool isString() const
c10::intrusive_ptr<ivalue::ConstantString> toString() &&
c10::intrusive_ptr<ivalue::ConstantString> toString() const &
const std::string &toStringRef() const
std::optional<std::reference_wrapper<const std::string>> toOptionalStringRef() const
c10::string_view toStringView() const
bool isDoubleList() const
c10::List<double> toDoubleList() &&
c10::List<double> toDoubleList() const &
std::vector<double> toDoubleVector() const
bool isComplexDoubleList() const
c10::List<c10::complex<double>> toComplexDoubleList() &&
c10::List<c10::complex<double>> toComplexDoubleList() const &
std::vector<c10::complex<double>> toComplexDoubleVector() const
bool isBoolList() const
c10::List<bool> toBoolList() &&
c10::List<bool> toBoolList() const &
bool isTensorList() const
c10::List<at::Tensor> toTensorList() &&
c10::List<at::Tensor> toTensorList() const &
std::vector<at::Tensor> toTensorVector() const
bool isOptionalTensorList() const
c10::List<std::optional<at::Tensor>> toOptionalTensorList() &&
c10::List<std::optional<at::Tensor>> toOptionalTensorList() const &
std::vector<std::optional<at::Tensor>> toOptionalTensorVector() const
IValue(c10::List<IValue> v)
inline bool isList() const
c10::List<IValue> toList() &&
c10::List<IValue> toList() const &
c10::ArrayRef<IValue> toListRef() const
template<class T, enable_if_list_is_ivalue_constructible<T> = nullptr>
IValue(c10::List<T> &&v)
template<class T, enable_if_list_is_ivalue_constructible<T> = nullptr>
IValue(const c10::List<T> &v)
template<class T, enable_if_list_is_ivalue_constructible<T> = nullptr>
IValue(at::ArrayRef<T> v)
template<class T, enable_if_list_is_ivalue_constructible<T> = nullptr>
IValue(const std::vector<T> &v)
template<class T, enable_if_list_is_ivalue_constructible<T> = nullptr>
IValue(std::vector<T> &&v)
template<class T, size_t N>
IValue(std::array<T, N> v)
template<class T, enable_if_symint<T> = nullptr>
IValue(at::ArrayRef<T> v)
template<class T, enable_if_symint<T> = nullptr>
IValue(at::OptionalArrayRef<T> v)
template<class T, enable_if_symint<T> = nullptr>
IValue(const std::vector<T> &v)
template<class T, enable_if_symint<T> = nullptr>
IValue(std::vector<T> &&v)
template<class T, enable_if_ilist_is_ivalue_constructible<T> = nullptr>
IValue(c10::IListRef<T> v)
IValue(c10::Dict<IValue, IValue> v)
inline bool isGenericDict() const
c10::Dict<IValue, IValue> toGenericDict() &&
c10::Dict<IValue, IValue> toGenericDict() const &
template<class Key, class Value>
IValue(c10::Dict<Key, Value> v)
template<class Key, class Value>
IValue(std::unordered_map<Key, Value> v)
template<class T, enable_if_ivalue_constructible<T> = nullptr>
IValue(std::optional<T> v)
template<class T, enable_if_list_is_ivalue_constructible<T> = nullptr>
IValue(c10::OptionalArrayRef<T> v)
IValue(c10::intrusive_ptr<ivalue::Object> v)
inline bool isObject() const
c10::intrusive_ptr<ivalue::Object> toObject() &&
c10::intrusive_ptr<ivalue::Object> toObject() const &
ivalue::Object &toObjectRef() const
torch::jit::Module toModule() const
bool isModule() const
IValue(c10::intrusive_ptr<ivalue::PyObjectHolder> v)
inline bool isPyObject() const
c10::intrusive_ptr<ivalue::PyObjectHolder> toPyObjectHolder() &&
c10::intrusive_ptr<ivalue::PyObjectHolder> toPyObjectHolder() const &
PyObject *toPyObject() const
explicit IValue(c10::intrusive_ptr<ivalue::EnumHolder> v)
inline bool isEnum() const
c10::intrusive_ptr<ivalue::EnumHolder> toEnumHolder() &&
c10::intrusive_ptr<ivalue::EnumHolder> toEnumHolder() const &
IValue() = default
inline bool isNone() const
inline std::string toNone() const
inline IValue(const at::Scalar &s)
inline bool isScalar() const
inline at::Scalar toScalar() const
inline IValue(c10::Device d)
inline bool isDevice() const
inline c10::Device toDevice() const
inline IValue(c10::Stream s)
c10::Stream toStream() &&
c10::Stream toStream() const &
inline bool isStream() const
inline IValue(ScalarType t)
inline at::ScalarType toScalarType() const
inline IValue(Layout l)
inline at::Layout toLayout() const
inline IValue(MemoryFormat m)
inline at::MemoryFormat toMemoryFormat() const
inline IValue(at::QScheme qscheme)
inline at::QScheme toQScheme() const
inline IValue(at::Dimname dimname)
inline at::Dimname toDimname() const
inline IValue(at::Generator g)
inline bool isGenerator() const
at::Generator toGenerator() &&
at::Generator toGenerator() const &
inline std::string tagKind() const
template<typename T>
T to() &&
template<typename T>
c10::detail::ivalue_to_const_ref_overload_return<T>::type to() const &
template<typename T>
std::optional<T> toOptional()
template<typename T>
std::optional<T> toOptional() const
std::ostream &repr(std::ostream &stream, std::function<bool(std::ostream&, const IValue &v)> customFormatter) const
inline bool isPtrType() const
template<typename T = c10::PlatformType>
TypePtr type() const
bool overlaps(const IValue &rhs) const
void getSubValues(HashAliasedIValues &subValues) const
void visit(const std::function<bool(const IValue&)> &visitor) const
IValue deepcopy(std::optional<at::Device> device = std::nullopt) const
IValue deepcopy(HashIdentityIValueMap &memo, std::optional<at::Device> device = std::nullopt) const
inline bool isIntrusivePtr() const
inline bool isIntrusivePtrLegacyBehavior() const
inline IValue(const Payload &p, Tag t)

Public Members

friend MaybeOwnedTraits< IValue >
Payload payload
Tag tag = {IValue::Tag::None}

Public Static Functions

static size_t hash(const IValue &iv)
static inline IValue make_capsule(intrusive_ptr<torch::CustomClassHolder> blob)
static inline IValue uninitialized()


friend struct WeakIValue
friend bool operator==(const IValue &lhs, const IValue &rhs)

This implements the same semantics as bool(lhs == rhs) in Python.

which is the same as equals() except for Tensor types.

friend bool operator!=(const IValue &lhs, const IValue &rhs)
friend std::ostream &operator<<(std::ostream &out, const IValue &v)
struct CompAliasedIValues

Public Functions

inline bool operator()(const IValue &lhs, const IValue &rhs) const
struct CompIdentityIValues

Public Functions

inline bool operator()(const IValue &lhs, const IValue &rhs) const
struct HashAliasedIValue

Public Functions

inline size_t hashTensor(const at::Tensor &ten) const
inline size_t operator()(const IValue &val) const
struct HashIdentityIValue

Public Functions

inline size_t operator()(const IValue &val) const
union Payload

Public Functions

inline Payload()
inline ~Payload()

Public Members

union c10::IValue::Payload::TriviallyCopyablePayload u
at::Tensor as_tensor
union TriviallyCopyablePayload

Public Functions

inline TriviallyCopyablePayload()

Public Members

int64_t as_int
double as_double
bool as_bool
c10::intrusive_ptr_target *as_intrusive_ptr
c10::DeviceType type
DeviceIndex index
struct c10::IValue::Payload::TriviallyCopyablePayload::[anonymous] as_device
template<typename T>
struct TagType


Access comprehensive developer documentation for PyTorch

View Docs


Get in-depth tutorials for beginners and advanced developers

View Tutorials


Find development resources and get your questions answered

View Resources