19 static bool show_index_check_message;
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 (show_index_check_message) {
179 std::cout <<
"[Tensor4] **********************************" << std::endl;
180 std::cout <<
"[Tensor4] WARNING: Index checking is enabled " << std::endl;
181 std::cout <<
"[Tensor4] **********************************" << std::endl;
182 show_index_check_message =
false;
185 if (data_ ==
nullptr) {
186 throw std::runtime_error(name_+
"Accessing null data in Tensor4.");
188 if ((i < 0) || (i >= ni_) || (j < 0) || (j >= nj_) || (k < 0) || (k >= nk_) || (l < 0) || (l >= nl_)) {
189 auto i_str = std::to_string(ni_);
190 auto j_str = std::to_string(nj_);
191 auto k_str = std::to_string(nk_);
192 auto l_str = std::to_string(nl_);
193 auto dims = i_str +
" x " + j_str +
" x " + k_str +
" x " + l_str;
194 auto index_str =
" " + std::to_string(i) +
"," + std::to_string(j) +
"," + std::to_string(k) +
"," + std::to_string(l);
195 throw std::runtime_error(
"Index (i,j,k,l)=" + index_str +
" is out of bounds for " + dims +
" array.");
209 if (data_ !=
nullptr) {
229 void resize(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
231 if (data_ !=
nullptr) {
237 allocate(num_i, num_j, num_k, num_l);
244 const T& operator()(
const int i,
const int j,
const int k,
const int l)
const
246 #ifdef Tensor4_check_enabled
247 check_index(i, j, k , l);
249 return data_[i + j*ni_ + p1_*k + p2_*l ];
252 T& operator()(
const int i,
const int j,
const int k,
const int l)
254 #ifdef Tensor4_check_enabled
255 check_index(i, j, k , l);
257 return data_[i + j*ni_ + p1_*k + p2_*l ];
269 for (
int i = 0; i < size_; i++) {
270 result.data_[i] = value * data_[i];
277 if (rhs.data_ ==
nullptr) {
278 throw std::runtime_error(
"Null data for rhs Tensor4.");
280 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
281 for (
int i = 0; i < rhs.size_; i++) {
282 result.data_[i] = value * rhs.data_[i];
291 for (
int i = 0; i < size_; i++) {
292 data_[i] += rhs.data_[i];
301 for (
int i = 0; i < size_; i++) {
302 data_[i] -= rhs.data_[i];
311 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
312 for (
int i = 0; i < size_; i++) {
313 result.data_[i] = data_[i] + rhs.data_[i];
320 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
321 for (
int i = 0; i < size_; i++) {
322 result.data_[i] = data_[i] - rhs.data_[i];