Caffe2 - C++ API
A deep learning, cross platform ML framework
ivalue.cpp
1 #include <ATen/core/ivalue.h>
2 #include <ATen/core/Formatting.h>
3 #include <cmath>
4 
5 namespace c10 {
6 namespace ivalue {
7 
8 CAFFE2_API c10::intrusive_ptr<ConstantString> ConstantString::create(
9  std::string str_) {
10  return c10::make_intrusive<ConstantString>(std::move(str_));
11 }
12 
13 } // namespace ivalue
14 
15 namespace {
16 
17 template<typename List>
18 std::ostream& printList(std::ostream & out, const List &v,
19  const std::string start, const std::string finish) {
20  out << start;
21  for(size_t i = 0; i < v->elements().size(); ++i) {
22  if(i > 0)
23  out << ", ";
24  // make sure we use ivalue printing, and not default printing for the element type
25  out << IValue(v->elements()[i]);
26  }
27  out << finish;
28  return out;
29 }
30 
31 template<typename Dict>
32 std::ostream& printDict(std::ostream& out, const Dict& v) {
33  out << "{";
34 
35  bool first = true;
36  for (const auto& pair : v->elements()) {
37  if (!first) {
38  out << ", ";
39  }
40  out << pair.first << ": " << pair.second;
41  first = false;
42  }
43 
44  out << "}";
45  return out;
46 }
47 
48 } // anonymous namespace
49 
50 std::ostream& operator<<(std::ostream & out, const IValue & v) {
51  switch(v.tag) {
52  case IValue::Tag::None:
53  return out << v.toNone();
54  case IValue::Tag::Tensor:
55  return out << v.toTensor();
56  case IValue::Tag::Double: {
57  double d = v.toDouble();
58  int c = std::fpclassify(d);
59  if (c == FP_NORMAL || c == FP_ZERO) {
60  int64_t i = int64_t(d);
61  if (double(i) == d) {
62  return out << i << ".";
63  }
64  }
65  auto orig_prec = out.precision();
66  return out
67  << std::setprecision(std::numeric_limits<double>::max_digits10)
68  << v.toDouble()
69  << std::setprecision(orig_prec);
70  } case IValue::Tag::Int:
71  return out << v.toInt();
72  case IValue::Tag::Bool:
73  return out << (v.toBool() ? "True" : "False");
74  case IValue::Tag::Tuple:
75  return printList(out, v.toTuple(), "(", ")");
76  case IValue::Tag::IntList:
77  return printList(out, v.toIntList(), "[", "]");
78  case IValue::Tag::DoubleList:
79  return printList(out, v.toDoubleList(), "[", "]");
80  case IValue::Tag::BoolList:
81  return printList(out, v.toBoolList(), "[", "]");
82  case IValue::Tag::String:
83  return out << v.toStringRef();
84  case IValue::Tag::TensorList:
85  return printList(out, v.toTensorList(), "[", "]");
86  case IValue::Tag::Blob:
87  return out << *v.toBlob();
88  case IValue::Tag::GenericList:
89  return printList(out, v.toGenericList(), "[", "]");
90  case IValue::Tag::Future:
91  return out << "Future";
92  case IValue::Tag::Device:
93  return out << v.toDevice();
94  case IValue::Tag::GenericDict:
95  return printDict(out, v.toGenericDict());
96  case IValue::Tag::Object:
97  // TODO we should print the object contents
98  return out << "Object<" << v.toObject()->name().toUnqualString()
99  << ">";
100  }
101  AT_ERROR("Tag not found\n");
102 }
103 
104 #undef TORCH_FORALL_TAGS
105 
106 void IValue::dump() const {
107  std::cout << *this << "\n";
108 }
109 
110 } // namespace c10
To register your own kernel for an operator, do in one (!) cpp file: C10_REGISTER_KERNEL(OperatorHand...
Definition: alias_info.h:7