11#include "utils/vec_range.hpp"
12#include "utils/dynamic_arg_resolver.hpp"
16#include <initializer_list>
25 class Tensor_impl:
public intrusive_ptr_base<Tensor_impl>{
29 Storage_init_interface
__SII;
36 std::vector<cytnx_uint64> _shape;
39 std::vector<cytnx_uint64> _mapper;
40 std::vector<cytnx_uint64> _invmapper;
46 boost::intrusive_ptr<Tensor_impl> _clone_meta_only()
const{
47 boost::intrusive_ptr<Tensor_impl> out(
new Tensor_impl());
48 out->_mapper = this->_mapper;
49 out->_invmapper = this->_invmapper;
50 out->_shape = this->_shape;
51 out->_contiguous = this->_contiguous;
54 Tensor_impl(): _contiguous(true){};
56 void Init(
const std::vector<cytnx_uint64> &shape,
const unsigned int &dtype=
Type.Double,
int device=-1);
57 void Init(
const Storage &in);
69 Tensor_impl(
const Tensor_impl &rhs);
70 Tensor_impl& operator=(
const Tensor_impl &rhs);
72 unsigned int dtype()
const{
73 return this->_storage.dtype();
76 return this->_storage.device();
79 std::string dtype_str()
const {
80 return Type.getname(this->_storage.dtype());
82 std::string device_str()
const{
83 return Device.getname(this->_storage.device());
86 const std::vector<cytnx_uint64>& shape()
const{
90 const bool& is_contiguous()
const{
91 return this->_contiguous;
94 const std::vector<cytnx_uint64>& mapper()
const{
97 const std::vector<cytnx_uint64>& invmapper()
const{
98 return this->_invmapper;
104 const Storage& storage()
const{
108 boost::intrusive_ptr<Tensor_impl> clone()
const{
109 boost::intrusive_ptr<Tensor_impl> out = this->_clone_meta_only();
110 out->_storage = this->_storage.clone();
115 void to_(
const int &device){
116 this->_storage.to_(device);
118 boost::intrusive_ptr<Tensor_impl> to(
const int &device){
119 if(this->device()==device){
124 boost::intrusive_ptr<Tensor_impl> out = this->_clone_meta_only();
125 out->_storage = this->_storage.to(device);
130 void permute_(
const std::vector<cytnx_uint64> &rnks);
132 boost::intrusive_ptr<Tensor_impl> permute(
const std::vector<cytnx_uint64> &rnks);
135 T& at(
const std::vector<cytnx_uint64> &locator)
const {
136 cytnx_error_msg(locator.size() != this->_shape.size(),
"%s",
"The input index does not match Tensor's rank.");
139 std::vector<cytnx_uint64> c_shape(this->_shape.size());
140 std::vector<cytnx_uint64> c_loc(this->_shape.size());
145 for(cytnx_int64 i=this->_shape.size()-1; i>=0; i--){
146 if(locator[i]>=this->_shape[i]){
147 cytnx_error_msg(
true,
"%s",
"Attempting to access out-of-bound index in Tensor.");
149 c_shape[i] = this->_shape[this->_invmapper[i]];
150 c_loc[i] = locator[this->_invmapper[i]];
151 RealRank += mtplyr*c_loc[i];
152 mtplyr *= c_shape[i];
154 return this->_storage.at<T>(RealRank);
157 boost::intrusive_ptr<Tensor_impl> get(
const std::vector<cytnx::Accessor> &accessors);
158 boost::intrusive_ptr<Tensor_impl> get_deprecated(
const std::vector<cytnx::Accessor> &accessors);
159 void set(
const std::vector<cytnx::Accessor> &accessors,
const boost::intrusive_ptr<Tensor_impl> &rhs);
162 void set(
const std::vector<cytnx::Accessor> &accessors,
const T& rc);
164 void set(
const std::vector<cytnx::Accessor> &accessors,
const Scalar::Sproxy& rc);
167 void fill(
const Tx& val){
168 this->storage().fill(val);
171 boost::intrusive_ptr<Tensor_impl> contiguous(){
174 if(this->_contiguous){
175 boost::intrusive_ptr<Tensor_impl> out(
this);
179 boost::intrusive_ptr<Tensor_impl> out(
new Tensor_impl());
180 std::vector<cytnx_uint64> oldshape(this->_shape.size());
181 for(cytnx_uint64 i=0;i<this->_shape.size();i++){
182 oldshape[i] = this->_shape[this->_invmapper[i]];
185 out->_storage._impl = this->_storage._impl->Move_memory(oldshape,this->_mapper, this->_invmapper);
187 out->_invmapper = vec_range(this->_invmapper.size());
188 out->_mapper = out->_invmapper;
189 out->_shape = this->_shape;
190 out->_contiguous =
true;
198 if(!this->_contiguous){
199 std::vector<cytnx_uint64> oldshape(this->_shape.size());
200 for(cytnx_uint64 i=0;i<this->_shape.size();i++){
201 oldshape[i] = this->_shape[this->_invmapper[i]];
204 this->_storage._impl = this->_storage._impl->Move_memory(oldshape,this->_mapper, this->_invmapper);
205 this->_mapper = vec_range(this->_invmapper.size());
206 this->_invmapper = this->_mapper;
207 this->_contiguous =
true;
212 void reshape_(
const std::vector<cytnx_int64> &new_shape){
213 if(!this->_contiguous){
216 std::vector<cytnx_uint64> result_shape(new_shape.size());
218 bool has_undetermine =
false;
219 unsigned int Udet_id = 0;
220 for(
int i=0;i<new_shape.size();i++){
222 if(new_shape[i]!=-1)
cytnx_error_msg(new_shape[i]!=-1,
"%s",
"[ERROR] reshape can only have dimension > 0 and one undetermine rank specify as -1");
223 if(has_undetermine)
cytnx_error_msg(new_shape[i]!=-1,
"%s",
"[ERROR] reshape can only have dimension > 0 and one undetermine rank specify as -1");
225 has_undetermine =
true;
227 new_N *= new_shape[i];
228 result_shape[i] = new_shape[i];
234 cytnx_error_msg(new_N > this->_storage.size(),
"%s",
"[ERROR] new shape exceed the total number of elements.");
235 cytnx_error_msg(this->_storage.size()%new_N,
"%s",
"[ERROR] unmatch size when reshape with undetermine dimension");
236 result_shape[Udet_id] = this->_storage.size()/new_N;
238 cytnx_error_msg(new_N != this->_storage.size(),
"%s",
"[ERROR] new shape does not match the number of elements.");
241 this->_shape = result_shape;
242 this->_mapper = vec_range(result_shape.size());
243 this->_invmapper = this->_mapper;
247 boost::intrusive_ptr<Tensor_impl> reshape(
const std::vector<cytnx_int64> &new_shape){
248 boost::intrusive_ptr<Tensor_impl> out(
new Tensor_impl());
249 if(this->is_contiguous()){
250 out = this->_clone_meta_only();
251 out->_storage = this->_storage;
253 out = this->contiguous();
257 out->reshape_(new_shape);
263 boost::intrusive_ptr<Tensor_impl> astype(
const int& new_type){
266 if(this->dtype() == new_type){
269 boost::intrusive_ptr<Tensor_impl> out = this->_clone_meta_only();
270 out->_storage = this->_storage.astype(new_type);
282 template<
class T> Tensor
operator+(
const Tensor &lhs,
const T &rc);
283 template<
class T> Tensor
operator-(
const Tensor &lhs,
const T &rhs);
284 template<
class T> Tensor
operator*(
const Tensor &lhs,
const T &rhs);
285 template<
class T> Tensor
operator/(
const Tensor &lhs,
const T &rhs);
297 boost::intrusive_ptr<Tensor_impl>
_insimpl;
298 std::vector<cytnx::Accessor>
_accs;
308 const T& operator=(
const T &
rc){
314 this->_insimpl->set(
_accs,
tmp._impl);
458 Scalar::Sproxy
item()
const{
478 template<
class ...
Ts>
484 template<
class ...
Ts>
490 template<
class ...
Ts>
497 template<
class ...
Ts>
502 template<
class ...
Ts>
511 std::vector<cytnx::Accessor>
tmp =
accs;
523 std::vector<cytnx::Accessor>
tmp =
accs;
528 std::vector<cytnx_int64>
tmp =
accs;
532 std::vector<cytnx::Accessor>
acc_in;
533 for(
int i=0;
i<
accs.size();
i++){
539 std::vector<cytnx_int64>
tmp =
accs;
543 std::vector<cytnx::Accessor>
acc_in;
544 for(
int i=0;
i<
accs.size();
i++){
554 void _Save(std::fstream &
f)
const;
555 void _Load(std::fstream &
f);
566 void Save(
const std::string &
fname)
const;
589 boost::intrusive_ptr<Tensor_impl> _impl;
605 Tensor& operator=(
const Tensor &
rhs){
661 unsigned int dtype()
const {
return this->_impl->dtype();}
668 int device()
const {
return this->_impl->device();}
675 std::string
dtype_str()
const {
return this->_impl->dtype_str();}
682 std::string
device_str()
const{
return this->_impl->device_str();}
689 const std::vector<cytnx_uint64>&
shape()
const{
690 return this->_impl->shape();
698 return this->_impl->shape().size();
773 return this->_impl->is_contiguous();
781 template<
class ...
Ts>
784 this->_impl->permute_(
argv);
810 template<
class ...
Ts>
882 this->_impl->reshape_(
shape);
886 this->_impl->reshape_(
shape);
888 template<
class ...Ts>
892 this->_impl->reshape_(
shape);
919 template<
class ...
Ts>
984 template<
class T,
class...Ts>
987 return this->
at<T>(argv);
989 template<
class T,
class...Ts>
992 return this->
at<T>(argv);
1017 cytnx_error_msg(this->_impl->storage().size()!=1,
"[ERROR][Tensor.item<T>]%s",
"item can only be called from a Tensor with only one element\n");
1018 return this->_impl->storage().at<
T>(0);
1023 const T&
item()
const{
1024 cytnx_error_msg(this->_impl->storage().size()!=1,
"[ERROR][Tensor.item<T>]%s",
"item can only be called from a Tensor with only one element\n");
1025 return this->_impl->storage().at<
T>(0);
1028 const Scalar::Sproxy
item()
const{
1033 Scalar::Sproxy
item(){
1125 void set(
const std::initializer_list<cytnx::Accessor> &
accessors,
const T &
rc){
1140 return this->_impl->storage();
1160 this->_impl->fill(
val);
1165 if(this->
shape() != rhs.
shape())
return false;
1210 return *
this +=
rhs;
1219 return *
this -=
rhs;
1228 return *
this *=
rhs;
1237 return *
this /=
rhs;
1242 return *
this ==
rhs;
1257 return this->
Mul(-1.);
1281 cytnx_error_msg(
rhs.shape().size()!=(
this->shape().size()-1),
"[ERROR] try to append a Tensor with rank not match.%s",
"\n");
1283 for(
unsigned int i=0;
i<
rhs.shape().size();
i++){
1290 if(
rhs.dtype() !=
this->dtype()){
1295 if(!
in.is_contiguous())
1300 this->_impl->_shape[0]+=1;
1304 in._impl->_storage.data(),
1314 cytnx_error_msg((this->
shape().size()-1)!=1,
"[ERROR] append a storage to Tensor can only accept rank-2 Tensor.%s",
"\n");
1325 this->_impl->_shape[0]+=1;
1327 this->_impl->_storage.resize(
oldsize+
in.size());
1330 Type.typeSize(
in.dtype())*
in.size());
1359 cytnx_error_msg(this->
shape().size()!=1,
"[ERROR] trying to append a scalar into multidimentional Tensor is not allow.\n Only rank-1 Tensor can accept scalar append.%s",
"\n");
1360 cytnx_error_msg(!this->
is_contiguous(),
"[ERROR] append require the Tensor to be contiguous. suggestion: call contiguous() or contiguous_() first.",
"\n");
1361 this->_impl->_shape[0]+=1;
1362 this->_impl->_storage.append(
rhs);
1368 std::vector<Tensor>
Svd(
const bool &
is_U=
true,
const bool &
is_vT=
true)
const;
1369 std::vector<Tensor>
Eigh(
const bool &
is_V=
true,
const bool &
row_v=
false)
const;
1395 Tensor
operator+(
const Tensor &lhs,
const Scalar::Sproxy &rhs);
1396 Tensor
operator-(
const Tensor &lhs,
const Scalar::Sproxy &rhs);
1397 Tensor
operator*(
const Tensor &lhs,
const Scalar::Sproxy &rhs);
1398 Tensor
operator/(
const Tensor &lhs,
const Scalar::Sproxy &rhs);
1400 std::ostream&
operator<<(std::ostream& os,
const Tensor &in);
object that mimic the python slice to access elements in C++ [this is for c++ API only].
Definition Accessor.hpp:16
an memeory storage with multi-type/multi-device support
Definition Storage.hpp:918
Storage astype(const unsigned int &new_type) const
cast the type of current Storage
Definition Storage.hpp:1036
const unsigned long long & size() const
the size ( no. of elements ) in the Storage
Definition Storage.hpp:1185
an tensor (multi-dimensional array)
Definition Tensor.hpp:289
void append(const Storage &srhs)
Definition Tensor.hpp:1308
Tensor & operator*=(const T &rc)
Tensor & Inv_(const double &clip)
Definition Tensor.cpp:1165
Tensor & operator/=(const T &rc)
Tensor operator-()
Definition Tensor.hpp:1256
void fill(const T &val)
fill all the element of current Tensor with the value.
Definition Tensor.hpp:1159
Tensor InvM() const
Definition Tensor.cpp:1162
bool same_data(const Tensor &rhs) const
Definition Tensor.cpp:1221
void to_(const int &device)
move the current Tensor to the device.
Definition Tensor.hpp:768
void append(const T &rhs)
Definition Tensor.hpp:1358
Tensor & operator-=(const T &rc)
Tensor & Add_(const T &rhs)
Definition Tensor.hpp:1209
Tensor Abs() const
Definition Tensor.cpp:1206
std::string device_str() const
the device (in string) of the Tensor
Definition Tensor.hpp:682
void reshape_(const std::vector< cytnx_int64 > &new_shape)
reshape the Tensor, inplacely
Definition Tensor.hpp:876
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:855
static Tensor Load(const std::string &fname)
Load current Tensor to file.
Definition Tensor.cpp:841
Tensor permute_(const std::vector< cytnx_uint64 > &rnks)
Definition Tensor.hpp:776
Tensor Mul(const T &rhs)
Definition Tensor.hpp:1223
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:661
Tensor Sub(const T &rhs)
Definition Tensor.hpp:1214
Tensor Inv(const double &clip) const
Definition Tensor.cpp:1169
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:834
void Tofile(const std::string &fname) const
Definition Tensor.cpp:766
T & at(const std::vector< cytnx_uint64 > &locator)
[C++ only] get an element at specific location.
Definition Tensor.hpp:976
Tensor reshape(const std::vector< cytnx_int64 > &new_shape) const
return a new Tensor that is reshaped.
Definition Tensor.hpp:913
T & item()
get an from a rank-0 Tensor
Definition Tensor.hpp:1016
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:719
std::vector< Tensor > Eigh(const bool &is_V=true, const bool &row_v=false) const
Definition Tensor.cpp:1153
void append(const Tensor &rhs)
Definition Tensor.hpp:1274
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:1096
Tensor Norm() const
Definition Tensor.cpp:1189
Tensor astype(const int &new_type) const
return a new Tensor that cast to different dtype.
Definition Tensor.hpp:944
Tensor & Div_(const T &rhs)
Definition Tensor.hpp:1236
Tensor & operator+=(const T &rc)
Tensor Conj() const
Definition Tensor.cpp:1178
Tensor & Pow_(const cytnx_double &p)
Definition Tensor.cpp:1197
std::string dtype_str() const
the dtype (in string) of the Tensor
Definition Tensor.hpp:675
Tensor & Mul_(const T &rhs)
Definition Tensor.hpp:1227
cytnx_uint64 rank() const
the rank of the Tensor
Definition Tensor.hpp:697
Tensor Trace(const cytnx_uint64 &a, const cytnx_uint64 &b) const
Definition Tensor.cpp:1216
const bool & is_contiguous() const
Definition Tensor.hpp:772
Tensor Exp() const
Definition Tensor.cpp:1186
Tensor & Abs_()
Definition Tensor.cpp:1202
Tensor Add(const T &rhs)
Definition Tensor.hpp:1205
void flatten_()
Definition Tensor.hpp:1267
void Save(const std::string &fname) const
Save current Tensor to file.
Definition Tensor.cpp:792
Tensor flatten() const
Definition Tensor.hpp:1260
Tensor & Conj_()
Definition Tensor.cpp:1174
Tensor Pow(const cytnx_double &p) const
Definition Tensor.cpp:1193
int device() const
the device-id of the Tensor
Definition Tensor.hpp:668
Tensor real()
Definition Tensor.cpp:892
Tensor imag()
Definition Tensor.cpp:899
Tensor to(const int &device) const
copy a tensor to new device
Definition Tensor.hpp:745
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:1063
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:1120
Tensor Max() const
Definition Tensor.cpp:1209
Tensor permute(const std::vector< cytnx_uint64 > &rnks) const
perform tensor permute on the cytnx::Tensor and return a new instance.
Definition Tensor.hpp:804
Tensor Div(const T &rhs)
Definition Tensor.hpp:1232
Tensor Mod(const T &rhs)
Definition Tensor.hpp:1252
bool equiv(const Tensor &rhs)
Definition Tensor.hpp:1164
Tensor Cpr(const T &rhs)
Definition Tensor.hpp:1241
Tensor & Exp_()
Definition Tensor.cpp:1182
Tensor & InvM_()
Definition Tensor.cpp:1158
std::vector< Tensor > Svd(const bool &is_U=true, const bool &is_vT=true) const
Definition Tensor.cpp:1150
const std::vector< cytnx_uint64 > & shape() const
the shape of the Tensor
Definition Tensor.hpp:689
Tensor Min() const
Definition Tensor.cpp:1212
const T & at(const std::vector< cytnx_uint64 > &locator) const
Definition Tensor.hpp:980
Storage & storage() const
return the storage of current Tensor.
Definition Tensor.hpp:1139
static Tensor from_storage(const Storage &in)
Definition Tensor.hpp:647
static Tensor Fromfile(const std::string &fname, const unsigned int &dtype, const cytnx_int64 &count=-1)
Definition Tensor.cpp:835
void Init(const std::vector< cytnx_uint64 > &shape, const unsigned int &dtype=Type.Double, const int &device=-1)
initialize a Tensor
Definition Tensor.hpp:637
Tensor(const std::vector< cytnx_uint64 > &shape, const unsigned int &dtype=Type.Double, const int &device=-1)
Definition Tensor.hpp:642
Tensor & Sub_(const T &rhs)
Definition Tensor.hpp:1218
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:18
Definition Accessor.hpp:12
Device_class Device
Definition Device.cpp:105
cytnx::UniTensor operator*(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
double cytnx_double
Definition Type.hpp:20
uint32_t cytnx_uint32
Definition Type.hpp:23
bool cytnx_bool
Definition Type.hpp:31
std::complex< double > cytnx_complex128
Definition Type.hpp:30
float cytnx_float
Definition Type.hpp:21
std::ostream & operator<<(std::ostream &os, const Scalar &in)
Definition Scalar.cpp:14
int16_t cytnx_int16
Definition Type.hpp:27
std::complex< float > cytnx_complex64
Definition Type.hpp:29
cytnx::UniTensor operator-(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
int32_t cytnx_int32
Definition Type.hpp:26
uint16_t cytnx_uint16
Definition Type.hpp:24
uint64_t cytnx_uint64
Definition Type.hpp:22
int64_t cytnx_int64
Definition Type.hpp:25
Storage_init_interface __SII
Definition Storage.cpp:13
Type_class Type
Definition Type.cpp:137
cytnx::UniTensor operator+(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
cytnx::UniTensor operator/(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)