22 std::string name_ =
"";
34 std::string name_ =
"";
45 Tensor4(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
47 allocate(num_i, num_j, num_k, num_l);
53 if (data_ !=
nullptr) {
63 if (rhs.ni_ <= 0 || rhs.nj_ <= 0 || rhs.nk_ <= 0 || rhs.nl_ <= 0) {
66 allocate(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
67 memcpy(data_, rhs.data_, size_*
sizeof(T));
70 int num_i() {
return ni_; }
71 int num_j() {
return nj_; }
72 int num_k() {
return nk_; }
73 int num_l() {
return nl_; }
83 if (rhs.ni_ <= 0 || rhs.nj_ <= 0 || rhs.nk_ <= 0 || rhs.nl_ <= 0) {
87 if (ni_ != rhs.ni_ || nj_ != rhs.nj_ || nk_ != rhs.nk_ || nl_ != rhs.nl_ <= 0) {
91 allocate(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
94 memcpy(data_, rhs.data_,
sizeof(T) * size_);
98 Tensor4& operator=(
const double value)
100 for (
int i = 0; i < size_; i++) {
106 void write(
const std::string& label,
bool memory=
true, T offset={})
const
109 char file_prefix[1000];
110 for (
auto c : label) {
115 file_prefix[n] =
'_';
128 file_prefix[n] =
'\0';
131 std::string file_name;
134 file_name = std::string(file_prefix) +
"_cm.bin";
135 std::cout <<
"[Tensor4::write] file_name: " << file_name << std::endl;
136 fp = fopen(file_name.c_str(),
"wb");
137 fwrite(&size_,
sizeof(
int), 1, fp);
138 fwrite(data_,
sizeof(
double), size_, fp);
142 friend std::ostream& operator << (std::ostream& out,
const Tensor4<T>& lhs)
144 for (
int i = 0; i < lhs.size_; i++) {
146 if (i != lhs.size_-1) {
157 void allocate(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
166 size_ = ni_ * nj_ * nk_ * nl_;
167 data_ =
new T [size_];
168 memset(data_, 0,
sizeof(T)*size_);
176 void check_index(
const int i,
const int j,
const int k,
const int l)
const
178 if (data_ ==
nullptr) {
179 throw std::runtime_error(name_+
"Accessing null data in Tensor4.");
181 if ((i < 0) || (i >= ni_) || (j < 0) || (j >= nj_) || (k < 0) || (k >= nk_) || (l < 0) || (l >= nl_)) {
182 auto i_str = std::to_string(ni_);
183 auto j_str = std::to_string(nj_);
184 auto k_str = std::to_string(nk_);
185 auto l_str = std::to_string(nl_);
186 auto dims = i_str +
" x " + j_str +
" x " + k_str +
" x " + l_str;
187 auto index_str =
" " + std::to_string(i) +
"," + std::to_string(j) +
"," + std::to_string(k) +
"," + std::to_string(l);
188 throw std::runtime_error(
"Index (i,j,k,l)=" + index_str +
" is out of bounds for " + dims +
" array.");
202 if (data_ !=
nullptr) {
222 void resize(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
224 if (data_ !=
nullptr) {
230 allocate(num_i, num_j, num_k, num_l);
237 const T& operator()(
const int i,
const int j,
const int k,
const int l)
const
239 #ifdef Tensor4_check_enabled
240 check_index(i, j, k , l);
242 return data_[i + j*ni_ + p1_*k + p2_*l ];
245 T& operator()(
const int i,
const int j,
const int k,
const int l)
247 #ifdef Tensor4_check_enabled
248 check_index(i, j, k , l);
250 return data_[i + j*ni_ + p1_*k + p2_*l ];
262 for (
int i = 0; i < size_; i++) {
263 result.data_[i] = value * data_[i];
270 if (rhs.data_ ==
nullptr) {
271 throw std::runtime_error(
"Null data for rhs Tensor4.");
273 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
274 for (
int i = 0; i < rhs.size_; i++) {
275 result.data_[i] = value * rhs.data_[i];
284 for (
int i = 0; i < size_; i++) {
285 data_[i] += rhs.data_[i];
294 for (
int i = 0; i < size_; i++) {
295 data_[i] -= rhs.data_[i];
304 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
305 for (
int i = 0; i < size_; i++) {
306 result.data_[i] = data_[i] + rhs.data_[i];
313 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
314 for (
int i = 0; i < size_; i++) {
315 result.data_[i] = data_[i] - rhs.data_[i];