Cytnx v1.0.0
Loading...
Searching...
No Matches
Tensor.hpp
Go to the documentation of this file.
1#ifndef CYTNX_TENSOR_H_
2#define CYTNX_TENSOR_H_
3
4#include "Type.hpp"
5#include "cytnx_error.hpp"
6#include "Device.hpp"
8#include <iostream>
9#include <fstream>
10#include "utils/dynamic_arg_resolver.hpp"
11#include "Accessor.hpp"
12#include <utility>
13#include <vector>
14#include <initializer_list>
15#include <string>
16
17#ifdef BACKEND_TORCH
18#else
19
20 #include "backend/Scalar.hpp"
21 #include "backend/Storage.hpp"
22 #include "backend/Tensor_impl.hpp"
23
24namespace cytnx {
25
26 class Tensor;
27
29 // [Note] these are fwd from linalg.hpp
30 template <class T>
31 Tensor operator+(const Tensor &lhs, const T &rc);
32 template <class T>
33 Tensor operator-(const Tensor &lhs, const T &rhs);
34 template <class T>
35 Tensor operator*(const Tensor &lhs, const T &rhs);
36 template <class T>
37 Tensor operator/(const Tensor &lhs, const T &rhs);
39
41 class Tensor {
42 private:
43 public:
45 // this is a proxy class to allow get/set element using [] as python!
46 struct Tproxy {
47 boost::intrusive_ptr<Tensor_impl> _insimpl;
48 std::vector<cytnx::Accessor> _accs;
49 Tproxy(boost::intrusive_ptr<Tensor_impl> _ptr, const std::vector<cytnx::Accessor> &accs)
50 : _insimpl(std::move(_ptr)), _accs(accs) {}
51
52 // when used to set elems:
53 const Tensor &operator=(const Tensor &rhs) {
54 this->_insimpl->set(_accs, rhs._impl);
55 return rhs;
56 }
57
58 template <class T>
59 const T &operator=(const T &rc) {
60 this->_insimpl->set(_accs, rc);
61 return rc;
62 }
63 const Tproxy &operator=(const Tproxy &rc) {
65 this->_insimpl->set(_accs, tmp._impl);
66 return rc;
67 }
68
69 template <class T>
70 Tensor operator+=(const T &rc) {
72 self._impl = _insimpl->get(_accs);
73 self += rc;
74 _insimpl->set(_accs, self._impl);
75 self._impl = this->_insimpl;
76 return self;
77 }
78 Tensor operator+=(const Tproxy &rc);
79
80 template <class T>
81 Tensor operator-=(const T &rc) {
83 self._impl = _insimpl->get(_accs);
84 self -= rc;
85 _insimpl->set(_accs, self._impl);
86 self._impl = this->_insimpl;
87 return self;
88 }
89 Tensor operator-=(const Tproxy &rc);
90
91 template <class T>
92 Tensor operator/=(const T &rc) {
94 self._impl = _insimpl->get(_accs);
95 self /= rc;
96 _insimpl->set(_accs, self._impl);
97 self._impl = this->_insimpl;
98 return self;
99 }
100 Tensor operator/=(const Tproxy &rc);
101
102 template <class T>
103 Tensor operator*=(const T &rc) {
104 Tensor self;
105 self._impl = _insimpl->get(_accs);
106 self *= rc;
107 _insimpl->set(_accs, self._impl);
108 self._impl = this->_insimpl;
109 return self;
110 }
111 Tensor operator*=(const Tproxy &rc);
112
113 // alias to resolve conflict with op ovld for rc=Tensor
114 /*
115 template<class T>
116 Tensor _operatorADD(const T &rc) const{
117 Tensor out;
118 out._impl = _insimpl->get(_accs);
119 return out.Add(rc);
120 }
121 */
122 Tensor operator+(const cytnx_complex128 &rc) const; //{return this->_operatorADD(rc);};
123 Tensor operator+(const cytnx_complex64 &rc) const; //{return this->_operatorADD(rc);};
124 Tensor operator+(const cytnx_double &rc) const; //{return this->_operatorADD(rc);};
125 Tensor operator+(const cytnx_float &rc) const; //{return this->_operatorADD(rc);};
126 Tensor operator+(const cytnx_uint64 &rc) const; //{return this->_operatorADD(rc);};
127 Tensor operator+(const cytnx_int64 &rc) const; //{return this->_operatorADD(rc);};
128 Tensor operator+(const cytnx_uint32 &rc) const; //{return this->_operatorADD(rc);};
129 Tensor operator+(const cytnx_int32 &rc) const; //{return this->_operatorADD(rc);};
130 Tensor operator+(const cytnx_uint16 &rc) const; //{return this->_operatorADD(rc);};
131 Tensor operator+(const cytnx_int16 &rc) const; //{return this->_operatorADD(rc);};
132 Tensor operator+(const cytnx_bool &rc) const; //{return this->_operatorADD(rc);};
133 Tensor operator+(const Tproxy &rc) const;
134
135 /*
136 template<class T>
137 Tensor _operatorSUB(const T &rc) const{
138 Tensor out;
139 out._impl = _insimpl->get(_accs);
140 return out.Sub(rc);
141 }
142 */
143 Tensor operator-(const cytnx_complex128 &rc) const; //{return this->_operatorSUB(rc);};
144 Tensor operator-(const cytnx_complex64 &rc) const; //{return this->_operatorSUB(rc);};
145 Tensor operator-(const cytnx_double &rc) const; //{return this->_operatorSUB(rc);};
146 Tensor operator-(const cytnx_float &rc) const; //{return this->_operatorSUB(rc);};
147 Tensor operator-(const cytnx_uint64 &rc) const; //{return this->_operatorSUB(rc);};
148 Tensor operator-(const cytnx_int64 &rc) const; //{return this->_operatorSUB(rc);};
149 Tensor operator-(const cytnx_uint32 &rc) const; //{return this->_operatorSUB(rc);};
150 Tensor operator-(const cytnx_int32 &rc) const; //{return this->_operatorSUB(rc);};
151 Tensor operator-(const cytnx_uint16 &rc) const; //{return this->_operatorSUB(rc);};
152 Tensor operator-(const cytnx_int16 &rc) const; //{return this->_operatorSUB(rc);};
153 Tensor operator-(const cytnx_bool &rc) const; //{return this->_operatorSUB(rc);};
154 Tensor operator-(const Tproxy &rc) const;
155
156 Tensor operator-() const;
157
158 /*
159 template<class T>
160 Tensor _operatorMUL(const T &rc) const{
161 Tensor out;
162 out._impl = _insimpl->get(_accs);
163 return out.Mul(rc);
164 }
165 */
166 Tensor operator*(const cytnx_complex128 &rc) const; //{return this->_operatorMUL(rc);};
167 Tensor operator*(const cytnx_complex64 &rc) const; //{return this->_operatorMUL(rc);};
168 Tensor operator*(const cytnx_double &rc) const; //{return this->_operatorMUL(rc);};
169 Tensor operator*(const cytnx_float &rc) const; //{return this->_operatorMUL(rc);};
170 Tensor operator*(const cytnx_uint64 &rc) const; //{return this->_operatorMUL(rc);};
171 Tensor operator*(const cytnx_int64 &rc) const; //{return this->_operatorMUL(rc);};
172 Tensor operator*(const cytnx_uint32 &rc) const; //{return this->_operatorMUL(rc);};
173 Tensor operator*(const cytnx_int32 &rc) const; //{return this->_operatorMUL(rc);};
174 Tensor operator*(const cytnx_uint16 &rc) const; //{return this->_operatorMUL(rc);};
175 Tensor operator*(const cytnx_int16 &rc) const; //{return this->_operatorMUL(rc);};
176 Tensor operator*(const cytnx_bool &rc) const; //{return this->_operatorMUL(rc);};
177 Tensor operator*(const Tproxy &rc) const;
178
179 /*
180 template<class T>
181 Tensor _operatorDIV(const T &rc) const{
182 Tensor out;
183 out._impl = _insimpl->get(_accs);
184 return out.Div(rc);
185 }
186 */
187 Tensor operator/(const cytnx_complex128 &rc) const; //{return this->_operatorDIV(rc);};
188 Tensor operator/(const cytnx_complex64 &rc) const; //{return this->_operatorDIV(rc);};
189 Tensor operator/(const cytnx_double &rc) const; //{return this->_operatorDIV(rc);};
190 Tensor operator/(const cytnx_float &rc) const; //{return this->_operatorDIV(rc);};
191 Tensor operator/(const cytnx_uint64 &rc) const; //{return this->_operatorDIV(rc);};
192 Tensor operator/(const cytnx_int64 &rc) const; //{return this->_operatorDIV(rc);};
193 Tensor operator/(const cytnx_uint32 &rc) const; //{return this->_operatorDIV(rc);};
194 Tensor operator/(const cytnx_int32 &rc) const; //{return this->_operatorDIV(rc);};
195 Tensor operator/(const cytnx_uint16 &rc) const; //{return this->_operatorDIV(rc);};
196 Tensor operator/(const cytnx_int16 &rc) const; //{return this->_operatorDIV(rc);};
197 Tensor operator/(const cytnx_bool &rc) const; //{return this->_operatorDIV(rc);};
198 Tensor operator/(const Tproxy &rc) const;
199
200 template <class T>
201 T item() const {
202 Tensor out;
203 out._impl = _insimpl->get(_accs);
204 return out.item<T>();
205 }
206
207 Scalar::Sproxy item() const {
208 Tensor out;
209 out._impl = _insimpl->get(_accs);
210 return out.item();
211 }
212
213 // when used to get elems:
214 operator Tensor() const {
215 Tensor out;
216 out._impl = _insimpl->get(_accs);
217 return out;
218 }
219
220 Storage storage() const {
221 Tensor out;
222 out._impl = _insimpl->get(_accs);
223 return out.storage();
224 }
225
226 }; // proxy class of Tensor.
227
229
231 // these two are using the python way!
232 //----------------------------------------
233 template <class... Ts>
234 Tproxy operator()(const std::string &e1, const Ts &...elems) {
235 // std::cout << e1 << std::endl;
236 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
237 return (*this)[tmp];
238 }
239 template <class... Ts>
240 Tproxy operator()(const cytnx_int64 &e1, const Ts &...elems) {
241 // std::cout << e1<< std::endl;
242 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
243 return (*this)[tmp];
244 }
245 template <class... Ts>
246 Tproxy operator()(const cytnx::Accessor &e1, const Ts &...elems) {
247 // std::cout << e1 << std::endl;
248 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
249 return (*this)[tmp];
250 }
251 template <class... Ts>
252 const Tproxy operator()(const std::string &e1, const Ts &...elems) const {
253 // std::cout << e1 << std::endl;
254 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
255 return (*this)[tmp];
256 }
257 template <class... Ts>
258 const Tproxy operator()(const cytnx_int64 &e1, const Ts &...elems) const {
259 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
260 return (*this)[tmp];
261 }
262 template <class... Ts>
263 const Tproxy operator()(const cytnx::Accessor &e1, const Ts &...elems) const {
264 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
265 return (*this)[tmp];
266 }
267
268 //-----------------------------------------
269
270 Tproxy operator[](const std::initializer_list<cytnx::Accessor> &accs) {
271 std::vector<cytnx::Accessor> tmp = accs;
272 return (*this)[tmp];
273 }
274 Tproxy operator[](const std::vector<cytnx::Accessor> &accs) {
275 return Tproxy(this->_impl, accs);
276 }
277
278 const Tproxy operator[](const std::vector<cytnx::Accessor> &accs) const {
279 return Tproxy(this->_impl, accs);
280 }
281 const Tproxy operator[](const std::initializer_list<cytnx::Accessor> &accs) const {
282 std::vector<cytnx::Accessor> tmp = accs;
283 return (*this)[tmp];
284 }
285
286 Tproxy operator[](const std::initializer_list<cytnx_int64> &accs) {
287 std::vector<cytnx_int64> tmp = accs;
288 return (*this)[tmp];
289 }
290 Tproxy operator[](const std::vector<cytnx_int64> &accs) {
291 std::vector<cytnx::Accessor> acc_in;
292 for (int i = 0; i < accs.size(); i++) {
293 acc_in.push_back(cytnx::Accessor(accs[i]));
294 }
295 return Tproxy(this->_impl, acc_in);
296 }
297 const Tproxy operator[](const std::initializer_list<cytnx_int64> &accs) const {
298 std::vector<cytnx_int64> tmp = accs;
299 return (*this)[tmp];
300 }
301 const Tproxy operator[](const std::vector<cytnx_uint64> &accs) const {
302 std::vector<cytnx::Accessor> acc_in;
303 for (int i = 0; i < accs.size(); i++) {
304 acc_in.push_back(cytnx::Accessor(accs[i]));
305 }
306 return Tproxy(this->_impl, acc_in);
307 }
308 const Tproxy operator[](const std::vector<cytnx_int64> &accs) const {
309 std::vector<cytnx::Accessor> acc_in;
310 for (int i = 0; i < accs.size(); i++) {
311 acc_in.push_back(cytnx::Accessor(accs[i]));
312 }
313 return Tproxy(this->_impl, acc_in);
314 }
316 //-------------------------------------------
317
319 void _Save(std::fstream &f) const;
320 void _Load(std::fstream &f);
321
323
332 void Save(const std::string &fname) const;
336 void Save(const char *fname) const;
337
346 void Tofile(const std::string &fname) const;
347
351 void Tofile(const char *fname) const;
352
356 void Tofile(std::fstream &f) const;
357
366 static Tensor Load(const std::string &fname);
370 static Tensor Load(const char *fname);
371
392 static Tensor Fromfile(const std::string &fname, const unsigned int &dtype,
393 const cytnx_int64 &count = -1);
394 static Tensor Fromfile(const char *fname, const unsigned int &dtype,
395 const cytnx_int64 &count = -1);
396
397 // static Tensor Frombinary(const std::string &fname);
398
400 boost::intrusive_ptr<Tensor_impl> _impl;
401 Tensor() : _impl(new Tensor_impl()){};
402 Tensor(const Tensor &rhs) { _impl = rhs._impl; }
403
404 /*
405 template<class Tp>
406 Tensor(const std::initializer_list<Tp> &rhs){
407 Storage stmp = std::vector<Tp>(rhs);
408 boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
409 tmp->Init(stmp);
410 this->_impl = tmp;
411 }
412 */
413
414 Tensor &operator=(const Tensor &rhs) {
415 _impl = rhs._impl;
416 return *this;
417 }
418
419 void operator=(const Tproxy &rhsp) { // this is used to handle proxy assignment
420 this->_impl = rhsp._insimpl->get(rhsp._accs);
421 }
423
425 // default device==Device.cpu (-1)
450 void Init(const std::vector<cytnx_uint64> &shape, const unsigned int &dtype = Type.Double,
451 const int &device = -1, const bool &init_zero = true) {
452 boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
453 this->_impl = tmp;
454 this->_impl->Init(shape, dtype, device, init_zero);
455 }
456 // void Init(const Storage& storage) {
457 // boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
458 // this->_impl = tmp;
459 // this->_impl->Init(storage);
460 // }
461 // void Init(const Storage& storage, const std::vector<cytnx_uint64> &shape,
462 // const unsigned int &dtype = Type.Double, const int &device = -1) {
463 // boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
464 // this->_impl = tmp;
465 // this->_impl->Init(storage, shape, dtype, device);
466 // }
467
480 Tensor(const std::vector<cytnx_uint64> &shape, const unsigned int &dtype = Type.Double,
481 const int &device = -1, const bool &init_zero = 1)
482 : _impl(new Tensor_impl()) {
483 this->Init(shape, dtype, device, init_zero);
484 }
485 // Tensor(const Storage& storage)
486 // : _impl(new Tensor_impl()) {
487 // this->Init(storage);
488 // }
489 // Tensor(const Storage& storage, const std::vector<cytnx_uint64> &shape,
490 // const unsigned int &dtype = Type.Double, const int &device = -1)
491 // : _impl(new Tensor_impl()) {
492 // this->Init(storage, shape, dtype, device);
493 // }
495
496 // This mechanism is to remove the 'void' type from Type_list. Taking advantage of it
497 // appearing first ...
498
500 struct internal {
501 template <typename Variant>
502 struct exclude_first;
503
504 template <typename First, typename... Rest>
505 struct exclude_first<std::variant<First, Rest...>> {
506 using type = std::variant<Rest...>;
507 };
508 }; // internal
510
511 // std::variant of pointers to Type_list, without void ....
514 std::add_pointer>;
515
516 // convert this->_impl->_storage._impl->Mem to a typed variant of pointers, excluding void*
518
519 // convert this->_impl->_strorage->Mem to the given pointer type.
520 // Throws an exception if T does not match this->dtype
521 template <typename T>
522 T *ptr_as(bool check_type = true) const {
523 if (check_type) {
524 cytnx_error_msg(this->dtype() != Type_class::cy_typeid_v<std::remove_cv_t<T>>,
525 "[ERROR] Attempt to convert dtype %d (%s) to pointer of type %s",
526 this->dtype(), Type_class::getname(this->dtype()).c_str(),
527 Type_class::getname(Type_class::cy_typeid_v<std::remove_cv_t<T>>).c_str());
528 }
529 return reinterpret_cast<T *>(this->_impl->_storage._impl->data());
530 }
531
532 #ifdef UNI_GPU
533 // std::variant of pointers to Type_list_gpu, without void ....
534 using gpu_pointer_types =
536 std::add_pointer>;
537
538 // convert this->_impl->_storage->Mem to a typed variant of pointers, excluding void*
540
541 // convert this->_impl->_strorage->Mem to the given pointer type.
542 // Throws an exception if T does not match this->dtype
543 template <typename T>
544 T *gpu_ptr_as(bool check_type = true) const {
545 if (check_type) {
547 this->dtype() != Type_class::cy_typeid_gpu_v<std::remove_cv_t<T>>,
548 "[ERROR] Attempt to convert dtype %d (%s) to GPU pointer of type %s", this->dtype(),
549 Type_class::getname(this->dtype()).c_str(),
550 Type_class::getname(Type_class::cy_typeid_gpu_v<std::remove_cv_t<T>>).c_str());
551 }
552 return reinterpret_cast<T *>(this->_impl->_storage._impl->data());
553 }
554 #endif
555
561 static Tensor from_storage(const Storage &in) {
562 Tensor out;
563 boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
564 out._impl = tmp;
565 out._impl->Init(in);
566 return out;
567 }
568
574 unsigned int dtype() const { return this->_impl->dtype(); }
575
581 int device() const { return this->_impl->device(); }
582
588 std::string dtype_str() const { return this->_impl->dtype_str(); }
589
595 std::string device_str() const { return this->_impl->device_str(); }
596
601 const std::vector<cytnx_uint64> &shape() const { return this->_impl->shape(); }
602
607 cytnx_uint64 rank() const { return this->_impl->shape().size(); }
608
626 Tensor clone() const {
627 Tensor out;
628 out._impl = this->_impl->clone();
629 return out;
630 }
631
652 Tensor to(const int &device) const {
653 Tensor out;
654 out._impl = this->_impl->to(device);
655 return out;
656 }
657
675 void to_(const int &device) { this->_impl->to_(device); }
676
681 const bool &is_contiguous() const { return this->_impl->is_contiguous(); }
682
683 Tensor &permute_(const std::vector<cytnx_uint64> &rnks) {
684 this->_impl->permute_(rnks);
685 return *this;
686 }
688 template <class... Ts>
689 Tensor &permute_(const cytnx_uint64 &e1, const Ts &...elems) {
690 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
691 this->_impl->permute_(argv);
692 return *this;
693 }
695
714 Tensor permute(const std::vector<cytnx_uint64> &rnks) const {
715 Tensor out;
716 out._impl = this->_impl->permute(rnks);
717 return out;
718 }
720 template <class... Ts>
721 Tensor permute(const cytnx_uint64 &e1, const Ts &...elems) const {
722 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
723 return this->permute(argv);
724 }
726
743 Tensor out;
744 out._impl = this->_impl->contiguous();
745 return out;
746 }
747
763 this->_impl->contiguous_();
764 return *this;
765 }
766
788 Tensor &reshape_(const std::vector<cytnx_int64> &new_shape) {
789 this->_impl->reshape_(new_shape);
790 return *this;
791 }
793 Tensor &reshape_(const std::vector<cytnx_uint64> &new_shape) {
794 std::vector<cytnx_int64> shape(new_shape.begin(), new_shape.end());
795 this->_impl->reshape_(shape);
796 return *this;
797 }
798 Tensor &reshape_(const std::initializer_list<cytnx_int64> &new_shape) {
799 std::vector<cytnx_int64> shape = new_shape;
800 this->_impl->reshape_(shape);
801 return *this;
802 }
803 template <class... Ts>
804 Tensor &reshape_(const cytnx_int64 &e1, const Ts... elems) {
805 std::vector<cytnx_int64> shape = dynamic_arg_int64_resolver(e1, elems...);
806 // std::cout << shape << std::endl;
807 this->_impl->reshape_(shape);
808 return *this;
809 }
811
836 Tensor reshape(const std::vector<cytnx_int64> &new_shape) const {
837 Tensor out;
838 out._impl = this->_impl->reshape(new_shape);
839 return out;
840 }
841
845 Tensor reshape(const std::vector<cytnx_uint64> &new_shape) const {
846 std::vector<cytnx_int64> tmp(new_shape.size());
847 memcpy(&tmp[0], &new_shape[0], sizeof(cytnx_uint64) * new_shape.size());
848 Tensor out;
849 out._impl = this->_impl->reshape(tmp);
850 return out;
851 }
852
856 Tensor reshape(const std::initializer_list<cytnx_int64> &new_shape) const {
857 return this->reshape(std::vector<cytnx_int64>(new_shape));
858 }
859
861 template <class... Ts>
862 Tensor reshape(const cytnx_int64 &e1, const Ts &...elems) const {
863 std::vector<cytnx_int64> argv = dynamic_arg_int64_resolver(e1, elems...);
864 return this->reshape(argv);
865 }
867
889 Tensor astype(const int &new_type) const {
890 Tensor out;
891 out._impl = this->_impl->astype(new_type);
892 return out;
893 }
894
895 // Tensor diagonal(){
896 // for(unsigned int i=0;i<this->shape().size();i++){
897 // if(this->shape()[i] != this->shape()[0],"[ERROR] Tensor.diagonal() can only be called
898 // when the subject has equal dimension in each rank.%s","\n");
899 // }
900 //
901 // }
902
923 template <class T>
924 T &at(const std::vector<cytnx_uint64> &locator) {
925 return this->_impl->at<T>(locator);
926 }
927
931 template <class T>
932 const T &at(const std::vector<cytnx_uint64> &locator) const {
933 return this->_impl->at<T>(locator);
934 }
936 template <class T, class... Ts>
937 const T &at(const cytnx_uint64 &e1, const Ts &...elems) const {
938 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
939 return this->at<T>(argv);
940 }
941 template <class T, class... Ts>
942 T &at(const cytnx_uint64 &e1, const Ts &...elems) {
943 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
944 return this->at<T>(argv);
945 }
946
947 const Scalar::Sproxy at(const std::vector<cytnx_uint64> &locator) const {
948 return this->_impl->at(locator);
949 }
950
951 Scalar::Sproxy at(const std::vector<cytnx_uint64> &locator) { return this->_impl->at(locator); }
953
979 template <class T>
980 T &item() {
981 cytnx_error_msg(this->_impl->storage().size() != 1, "[ERROR][Tensor.item<T>]%s",
982 "item can only be called from a Tensor with only one element\n");
983 return this->_impl->storage().at<T>(0);
984 }
985
987 template <class T>
988 const T &item() const {
989 cytnx_error_msg(this->_impl->storage().size() != 1, "[ERROR][Tensor.item<T>]%s",
990 "item can only be called from a Tensor with only one element\n");
991 return this->_impl->storage().at<T>(0);
992 }
993
994 const Scalar::Sproxy item() const {
995 Scalar::Sproxy out(this->storage()._impl, 0);
996 return out;
997 }
998
999 Scalar::Sproxy item() {
1000 Scalar::Sproxy out(this->storage()._impl, 0);
1001 return out;
1002 }
1003
1005
1027 Tensor get(const std::vector<cytnx::Accessor> &accessors) const {
1028 Tensor out;
1029 out._impl = this->_impl->get(accessors);
1030 return out;
1031 }
1032
1033 /*
1034 Tensor get_v2(const std::vector<cytnx::Accessor> &accessors) const{
1035 Tensor out;
1036 out._impl = this->_impl->get_v2(accessors);
1037 return out;
1038 }
1039 */
1040
1059 void set(const std::vector<cytnx::Accessor> &accessors, const Tensor &rhs) {
1060 this->_impl->set(accessors, rhs._impl);
1061 }
1062
1081 template <class T>
1082 void set(const std::vector<cytnx::Accessor> &accessors, const T &rc) {
1083 this->_impl->set(accessors, rc);
1084 }
1086 template <class T>
1087 void set(const std::initializer_list<cytnx::Accessor> &accessors, const T &rc) {
1088 std::vector<cytnx::Accessor> args = accessors;
1089 this->set(args, rc);
1090 }
1092
1102 Storage &storage() const { return this->_impl->storage(); }
1103
1118 template <class T>
1119 void fill(const T &val) {
1120 this->_impl->fill(val);
1121 }
1122
1127 bool equivshape(const Tensor &rhs) {
1128 if (this->shape() != rhs.shape()) return false;
1129 return true;
1130 }
1131
1140
1149
1150 // Arithmic:
1167 template <class T>
1169
1186 template <class T>
1188
1205 template <class T>
1207
1225 template <class T>
1227
1228 // Tensor &operator+=(const Tproxy &rc);
1229 // Tensor &operator-=(const Tproxy &rc);
1230 // Tensor &operator*=(const Tproxy &rc);
1231 // Tensor &operator/=(const Tproxy &rc);
1232 /*
1233 Tensor operator+(const Tproxy &rc){
1234 return *this + Tensor(rc);
1235 }
1236 Tensor operator-(const Tproxy &rc){
1237 return *this - Tensor(rc);
1238 }
1239 Tensor operator*(const Tproxy &rc){
1240 return *this * Tensor(rc);
1241 }
1242 Tensor operator/(const Tproxy &rc){
1243 return *this / Tensor(rc);
1244 }
1245 */
1251 template <class T>
1252 Tensor Add(const T &rhs) {
1253 return *this + rhs;
1254 }
1255
1261 template <class T>
1262 Tensor &Add_(const T &rhs) {
1263 return *this += rhs;
1264 }
1265
1271 template <class T>
1272 Tensor Sub(const T &rhs) {
1273 return *this - rhs;
1274 }
1275
1281 template <class T>
1282 Tensor &Sub_(const T &rhs) {
1283 return *this -= rhs;
1284 }
1285
1291 template <class T>
1292 Tensor Mul(const T &rhs) {
1293 return *this * rhs;
1294 }
1295
1301 template <class T>
1302 Tensor &Mul_(const T &rhs) {
1303 return *this *= rhs;
1304 }
1305
1312 template <class T>
1313 Tensor Div(const T &rhs) {
1314 return *this / rhs;
1315 }
1316
1323 template <class T>
1324 Tensor &Div_(const T &rhs) {
1325 return *this /= rhs;
1326 }
1327
1334 template <class T>
1335 Tensor Cpr(const T &rhs) {
1336 return *this == rhs;
1337 }
1338
1339 // /**
1340 // * @brief Compare each element of the current tensor with the input tensor.
1341 // * @details This function Compare each element of the current tensor with the input tensor.
1342 // * @param[in] rhs the compared tensor.
1343 // */
1344 // bool approx_eq(const Tensor &rhs, const cytnx_double tol = 0) {
1345 // if (this->device() != rhs.device()) {
1346 // if (User_debug)
1347 // std::cout << "[approx_eq] Tensor device " << this->device()
1348 // << "not equal to rhs tensor device " << rhs.device() << std::endl;
1349 // return false;
1350 // }
1351 // // if (this->dtype() != rhs.dtype()) {
1352 // // std::cout << "[approx_eq] Tensor dtype " << this->dtype()
1353 // // << "not equal to rhs tensor dtype " << rhs.dtype() << std::endl;
1354 // // return false;
1355 // // }
1356 // if (this->shape() != rhs.shape()) {
1357 // if (User_debug)
1358 // std::cout << "[approx_eq] Tensor shape " << this->shape()
1359 // << "not equal to rhs tensor shape " << rhs.shape() << std::endl;
1360 // return false;
1361 // }
1362 // if (this->is_contiguous() != rhs.is_contiguous()) {
1363 // if (User_debug)
1364 // std::cout << "[AreNearlyEqTensor] Tensor contiguous flag " << this->is_contiguous()
1365 // << "not equal to rhs tensor flag " << rhs.is_contiguous() << std::endl;
1366 // return false;
1367 // }
1368 // return this->_impl->_storage.approx_eq(rhs._impl->_storage._impl, tol);
1369 // }
1370
1371 // template<class T>
1372 // Tensor& Cpr_(const T &rhs){
1373 //
1374 // return *this == rhs;
1375 // }
1376
1377 template <class T>
1378 Tensor Mod(const T &rhs) {
1379 return *this % rhs;
1380 }
1381
1388 Tensor operator-() { return this->Mul(-1.); }
1389
1397 Tensor flatten() const {
1398 Tensor out = this->clone();
1399 out.contiguous_();
1400 out.reshape_({-1});
1401 return out;
1402 }
1403
1411 void flatten_() {
1412 this->contiguous_();
1413 this->reshape_({-1});
1414 }
1415
1442 void append(const Tensor &rhs) {
1443 // Tensor in;
1444 if (!this->is_contiguous()) this->contiguous_();
1445
1446 // check Tensor in shape:
1447 cytnx_error_msg(rhs.shape().size() == 0 || this->shape().size() == 0,
1448 "[ERROR] try to append a null Tensor.%s", "\n");
1449 cytnx_error_msg(rhs.shape().size() != (this->shape().size() - 1),
1450 "[ERROR] try to append a Tensor with rank not match.%s", "\n");
1451 cytnx_uint64 Nelem = 1;
1452 for (unsigned int i = 0; i < rhs.shape().size(); i++) {
1453 cytnx_error_msg(rhs.shape()[i] != this->shape()[i + 1],
1454 "[ERROR] dimension mismatch @ rhs.rank: [%d] this: [%d] rhs: [%d]\n", i,
1455 this->shape()[i + 1], rhs.shape()[i]);
1456 Nelem *= rhs.shape()[i];
1457 }
1458
1459 // check type:
1460 Tensor in;
1461 if (rhs.dtype() != this->dtype()) {
1462 in = rhs.astype(this->dtype());
1463 if (!in.is_contiguous()) in.contiguous_();
1464 } else {
1465 if (!in.is_contiguous())
1466 in = rhs.contiguous();
1467 else
1468 in = rhs;
1469 }
1470 this->_impl->_shape[0] += 1;
1471 cytnx_uint64 oldsize = this->_impl->_storage.size();
1472 this->_impl->_storage.resize(oldsize + Nelem);
1473 memcpy(((char *)this->_impl->_storage.data()) +
1474 oldsize * Type.typeSize(this->dtype()) / sizeof(char),
1475 in._impl->_storage.data(), Type.typeSize(in.dtype()) * Nelem);
1476 }
1504 void append(const Storage &srhs) {
1505 if (!this->is_contiguous()) this->contiguous_();
1506
1507 // check Tensor in shape:
1508 cytnx_error_msg(srhs.size() == 0 || this->shape().size() == 0,
1509 "[ERROR] try to append a null Tensor.%s", "\n");
1510 cytnx_error_msg((this->shape().size() - 1) != 1,
1511 "[ERROR] append a storage to Tensor can only accept rank-2 Tensor.%s", "\n");
1512 cytnx_error_msg(this->shape().back() != srhs.size(), "[ERROR] Tensor dmension mismatch!%s",
1513 "\n");
1514
1515 // check type:
1516 Storage in;
1517 if (srhs.dtype() != this->dtype()) {
1518 in = srhs.astype(this->dtype());
1519 } else {
1520 in = srhs;
1521 }
1522 this->_impl->_shape[0] += 1;
1523 cytnx_uint64 oldsize = this->_impl->_storage.size();
1524 this->_impl->_storage.resize(oldsize + in.size());
1525 memcpy(((char *)this->_impl->_storage.data()) +
1526 oldsize * Type.typeSize(this->dtype()) / sizeof(char),
1527 in._impl->data(), Type.typeSize(in.dtype()) * in.size());
1528 }
1529 /*
1530 void append(const Tensor &rhs){
1531 // convert to the same type.
1532 Tensor in;
1533 if(rhs.dtype() != this->dtype()){
1534 in = rhs.astype(this->dtype());
1535 }else{
1536 in = rhs;
1537 }
1538
1539 // 1) check rank
1540 if(this->shape().size()==1){
1541 // check if rhs is a scalar tensor (only one element)
1542 cytnx_error_msg(!(rhs.shape().size()==1 && rhs.shape()[0]==1),"[ERROR] trying to append
1543 a scalar into multidimentional Tensor is not allow.\n Only rank-1 Tensor can accept scalar
1544 append.%s","\n"); this->_impl->_shape[0]+=1; this->_impl->_storage.append(0);
1545
1546 }else{
1547 cytnx_error_msg(rhs.shape().size() != this->shape().size()-1,"[ERROR] try to append a
1548 Tensor with rank not match.%s","\n");
1549
1550 }
1551 cytnx_error_msg(!this->is_contiguous(),"[ERROR] append require the Tensor to be contiguous.
1552 suggestion: call contiguous() or contiguous_() first.","\n");
1553 }
1554 */
1566 template <class T>
1567 void append(const T &rhs) {
1568 cytnx_error_msg(this->shape().size() != 1,
1569 "[ERROR] trying to append a scalar into multidimentional Tensor is not "
1570 "allow.\n Only rank-1 Tensor can accept scalar append.%s",
1571 "\n");
1573 "[ERROR] append require the Tensor to be contiguous. suggestion: call "
1574 "contiguous() or contiguous_() first.",
1575 "\n");
1576 this->_impl->_shape[0] += 1;
1577 this->_impl->_storage.append(rhs);
1578 }
1579
1588 bool same_data(const Tensor &rhs) const;
1589
1590 // linalg:
1596 std::vector<Tensor> Svd(const bool &is_UvT = true) const;
1597
1603 std::vector<Tensor> Eigh(const bool &is_V = true, const bool &row_v = false) const;
1604
1610
1615 Tensor InvM() const;
1616
1621 Tensor &Inv_(const double &clip);
1622
1627 Tensor Inv(const double &clip) const;
1628
1634
1639 Tensor Conj() const;
1640
1646
1651 Tensor Exp() const;
1652
1657 Tensor Norm() const;
1658
1663 Tensor Pow(const cytnx_double &p) const;
1664
1670
1675 Tensor Trace(const cytnx_uint64 &a = 0, const cytnx_uint64 &b = 1) const;
1676
1681 Tensor Abs() const;
1682
1688
1693 Tensor Max() const;
1694
1699 Tensor Min() const;
1700
1701 }; // class Tensor
1702
1703 Tensor operator+(const Tensor &lhs, const Tensor::Tproxy &rhs);
1704 Tensor operator-(const Tensor &lhs, const Tensor::Tproxy &rhs);
1705 Tensor operator*(const Tensor &lhs, const Tensor::Tproxy &rhs);
1706 Tensor operator/(const Tensor &lhs, const Tensor::Tproxy &rhs);
1707
1708 Tensor operator+(const Tensor &lhs, const Scalar::Sproxy &rhs);
1709 Tensor operator-(const Tensor &lhs, const Scalar::Sproxy &rhs);
1710 Tensor operator*(const Tensor &lhs, const Scalar::Sproxy &rhs);
1711 Tensor operator/(const Tensor &lhs, const Scalar::Sproxy &rhs);
1712
1714 std::ostream &operator<<(std::ostream &os, const Tensor &in);
1715 std::ostream &operator<<(std::ostream &os, const Tensor::Tproxy &in);
1717 //{ os << Tensor(in);};
1718} // namespace cytnx
1719
1720#endif // BACKEND_TORCH
1721
1722#endif // CYTNX_TENSOR_H_
constexpr Type_class Type
data type
Definition Type.hpp:426
object that mimic the python slice to access elements in C++ [this is for c++ API only].
Definition Accessor.hpp:17
an tensor (multi-dimensional array)
Definition Tensor.hpp:41
void append(const Storage &srhs)
the append function of the Storage.
Definition Tensor.hpp:1504
Tensor & operator*=(const T &rc)
multiplication assignment operator with a Tensor or a scalar.
Tensor & Inv_(const double &clip)
the Inv_ member function. Same as cytnx::linalg::Inv_(Tensor &Tin, const double &clip)
Tensor & operator/=(const T &rc)
division assignment operator with a Tensor or a scalar.
Tensor operator-()
The negation function.
Definition Tensor.hpp:1388
void fill(const T &val)
fill all the element of current Tensor with the value.
Definition Tensor.hpp:1119
Tensor InvM() const
the InvM member function. Same as cytnx::linalg::InvM(const Tensor &Tin), where Tin is the current Te...
bool same_data(const Tensor &rhs) const
Check whether two tensors share the same internal memory.
void to_(const int &device)
move the current Tensor to the device.
Definition Tensor.hpp:675
Tensor & permute_(const std::vector< cytnx_uint64 > &rnks)
Definition Tensor.hpp:683
Tensor reshape(const std::vector< cytnx_uint64 > &new_shape) const
Definition Tensor.hpp:845
Tensor(const std::vector< cytnx_uint64 > &shape, const unsigned int &dtype=Type.Double, const int &device=-1, const bool &init_zero=1)
Construct a new Tensor object.
Definition Tensor.hpp:480
void append(const T &rhs)
the append function of the scalar.
Definition Tensor.hpp:1567
Tensor & operator-=(const T &rc)
subtraction assignment operator with a Tensor or a scalar.
Tensor & Add_(const T &rhs)
Addition function with a Tensor or a scalar, inplacely. Same as operator+=(const T &rhs).
Definition Tensor.hpp:1262
Tensor Abs() const
the Abs member function. Same as linalg::Abs(const Tensor &Tin), where Tin is the current Tensor.
Tensor reshape(const std::initializer_list< cytnx_int64 > &new_shape) const
Definition Tensor.hpp:856
std::string device_str() const
the device (in string) of the Tensor
Definition Tensor.hpp:595
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:762
Tensor Mul(const T &rhs)
Multiplication function with a Tensor or a scalar. Same as cytnx::operator*(const Tensor &self,...
Definition Tensor.hpp:1292
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:574
Tensor Sub(const T &rhs)
Subtraction function with a Tensor or a scalar. Same as cytnx::operator-(const Tensor &self,...
Definition Tensor.hpp:1272
Tensor Inv(const double &clip) const
the Inv member function. Same as cytnx::linalg::Inv(const Tensor &Tin, const double &clip)
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:742
void Tofile(const std::string &fname) const
Save current Tensor to the binary file.
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition Tensor.hpp:924
Tensor reshape(const std::vector< cytnx_int64 > &new_shape) const
return a new Tensor that is reshaped.
Definition Tensor.hpp:836
static Tensor Fromfile(const std::string &fname, const unsigned int &dtype, const cytnx_int64 &count=-1)
Load current Tensor from the binary file.
T & item()
get the element from a rank-0 Tensor.
Definition Tensor.hpp:980
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:626
std::vector< Tensor > Eigh(const bool &is_V=true, const bool &row_v=false) const
the Eigh member function. Same as cytnx::linalg::Eigh(const Tensor &Tin, const bool &is_V,...
void Tofile(const char *fname) const
void append(const Tensor &rhs)
the append function.
Definition Tensor.hpp:1442
static Tensor Load(const char *fname)
void Save(const char *fname) const
void set(const std::vector< cytnx::Accessor > &accessors, const Tensor &rhs)
set elements with the input Tensor using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1059
static Tensor Fromfile(const char *fname, const unsigned int &dtype, const cytnx_int64 &count=-1)
Tensor Norm() const
the Norm member function. Same as linalg::Norm(const Tensor &Tin), where Tin is the current Tensor.
Tensor astype(const int &new_type) const
return a new Tensor that cast to different dtype.
Definition Tensor.hpp:889
Tensor & Div_(const T &rhs)
Division function with a Tensor or a scalar, inplacely. Same as operator/=(const T &rhs).
Definition Tensor.hpp:1324
make_variant_from_transform_t< typename internal::exclude_first< Type_list >::type, std::add_pointer > pointer_types
Definition Tensor.hpp:514
pointer_types ptr() const
static Tensor Load(const std::string &fname)
Load current Tensor from file.
Tensor & operator+=(const T &rc)
addition assignment operator with a Tensor or a scalar.
Tensor Conj() const
the Conj member function. Same as cytnx::linalg::Conj(const Tensor &Tin), where Tin is the current Te...
Tensor Trace(const cytnx_uint64 &a=0, const cytnx_uint64 &b=1) const
the Trace member function. Same as linalg::Trace(const Tensor &Tin, const cytnx_uint64 &a,...
bool equivshape(const Tensor &rhs)
compare the shape of two tensors.
Definition Tensor.hpp:1127
Tensor & Pow_(const cytnx_double &p)
the Pow_ member function. Same as linalg::Pow_(Tensor &Tin, const cytnx_double &p),...
std::vector< Tensor > Svd(const bool &is_UvT=true) const
the SVD member function. Same as cytnx::linalg::Svd(const Tensor &Tin, const bool &is_UvT) ,...
std::string dtype_str() const
the dtype (in string) of the Tensor
Definition Tensor.hpp:588
Tensor & Mul_(const T &rhs)
Multiplication function with a Tensor or a scalar, inplacely. Same as operator*=(const T &rhs).
Definition Tensor.hpp:1302
cytnx_uint64 rank() const
the rank of the Tensor
Definition Tensor.hpp:607
const bool & is_contiguous() const
return whether the Tensor is contiguous or not.
Definition Tensor.hpp:681
Tensor Exp() const
the Exp member function. Same as linalg::Exp(const Tensor &Tin), where Tin is the current Tensor.
Tensor & Abs_()
the Abs_ member function. Same as linalg::Abs_(Tensor &Tin), where Tin is the current Tensor.
Tensor Add(const T &rhs)
Addition function with a Tensor or a scalar. Same as cytnx::operator+(const Tensor &self,...
Definition Tensor.hpp:1252
void flatten_()
The flatten function, inplacely.
Definition Tensor.hpp:1411
void Save(const std::string &fname) const
Save current Tensor to file.
Tensor flatten() const
The flatten function.
Definition Tensor.hpp:1397
Tensor & Conj_()
the Conj_ member function. Same as cytnx::linalg::Conj_(Tensor &Tin), where Tin is the current Tensor...
Tensor Pow(const cytnx_double &p) const
the Pow member function. Same as linalg::Pow(const Tensor &Tin, const cytnx_double &p),...
int device() const
the device-id of the Tensor
Definition Tensor.hpp:581
Tensor real()
return the real part of the tensor.
Tensor imag()
return the imaginary part of the tensor.
Tensor to(const int &device) const
copy a tensor to new device
Definition Tensor.hpp:652
T * ptr_as(bool check_type=true) const
Definition Tensor.hpp:522
Tensor & reshape_(const std::vector< cytnx_int64 > &new_shape)
reshape the Tensor, inplacely
Definition Tensor.hpp:788
void Tofile(std::fstream &f) const
Tensor get(const std::vector< cytnx::Accessor > &accessors) const
get elements using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1027
void set(const std::vector< cytnx::Accessor > &accessors, const T &rc)
set elements with the input constant using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1082
Tensor Max() const
the Max member function. Same as linalg::Max(const Tensor &Tin), where Tin is the current Tensor.
Tensor permute(const std::vector< cytnx_uint64 > &rnks) const
perform tensor permute on the cytnx::Tensor and return a new instance.
Definition Tensor.hpp:714
Tensor Div(const T &rhs)
Division function with a Tensor or a scalar. Same as cytnx::operator/(const Tensor &self,...
Definition Tensor.hpp:1313
Tensor Mod(const T &rhs)
Definition Tensor.hpp:1378
void Init(const std::vector< cytnx_uint64 > &shape, const unsigned int &dtype=Type.Double, const int &device=-1, const bool &init_zero=true)
initialize a Tensor
Definition Tensor.hpp:450
Tensor Cpr(const T &rhs)
The comparison function.
Definition Tensor.hpp:1335
Tensor & Exp_()
the Exp_ member function. Same as linalg::Exp_(Tensor &Tin), where Tin is the current Tensor.
Tensor & InvM_()
the InvM_ member function. Same as cytnx::linalg::InvM_(Tensor &Tin), where Tin is the current Tensor...
const std::vector< cytnx_uint64 > & shape() const
the shape of the Tensor
Definition Tensor.hpp:601
Tensor Min() const
the Min member function. Same as linalg::Min(const Tensor &Tin), where Tin is the current Tensor.
const T & at(const std::vector< cytnx_uint64 > &locator) const
Definition Tensor.hpp:932
Storage & storage() const
return the storage of current Tensor.
Definition Tensor.hpp:1102
static Tensor from_storage(const Storage &in)
Convert a Storage to Tensor.
Definition Tensor.hpp:561
Tensor & Sub_(const T &rhs)
Subtraction function with a Tensor or a scalar, inplacely. Same as operator-=(const T &rhs).
Definition Tensor.hpp:1282
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:18
Definition Accessor.hpp:12
cytnx::UniTensor operator*(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The multiplication operator between two UniTensor.
cytnx::UniTensor operator-(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The subtraction operator between two UniTensor.
cytnx::UniTensor operator+(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The addition operator between two UniTensor.
cytnx::UniTensor operator/(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The division operator between two UniTensor.