monolish  0.17.2
MONOlithic LInear equation Solvers for Highly-parallel architecture
monolish_tensor_dense.hpp
Go to the documentation of this file.
1 #pragma once
2 #include "monolish_matrix.hpp"
3 #include "monolish_tensor.hpp"
4 #include "monolish_vector.hpp"
5 
6 namespace monolish {
7 template <typename Float> class vector;
8 template <typename TYPE, typename Float> class view1D;
9 template <typename TYPE, typename Float> class view_Dense;
10 template <typename TYPE, typename Float> class view_tensor_Dense;
11 namespace tensor {
12 template <typename Float> class tensor_COO;
13 template <typename Float> class tensor_Dense {
14 private:
18  std::vector<size_t> shape;
19 
23  mutable std::shared_ptr<bool> gpu_status = std::make_shared<bool>(false);
24 
28  size_t first = 0;
29 
30 public:
34  std::shared_ptr<Float> val;
35 
39  size_t val_nnz = 0;
40 
44  size_t alloc_nnz = 0;
45 
49  bool val_create_flag = false;
50 
52 
62 
76 
86 
96  convert(tens);
97  val_create_flag = true;
98  }
99 
107  void convert(const matrix::Dense<Float> &dense);
108 
117  convert(dense);
118  val_create_flag = true;
119  }
120 
128  void convert(const vector<Float> &vec);
129 
138  convert(vec);
139  val_create_flag = true;
140  }
141 
150  tensor_Dense(const std::vector<size_t> &shape);
151 
160  tensor_Dense(const std::initializer_list<size_t> &shape);
161 
170  tensor_Dense(const std::vector<size_t> &shape, const Float *value);
171 
181  tensor_Dense(const std::vector<size_t> &shape,
182  const std::vector<Float> &value);
183 
194  tensor_Dense(const std::vector<size_t> &shape, const Float min,
195  const Float max);
196 
208  tensor_Dense(const std::vector<size_t> &shape, const Float min,
209  const Float max, const std::uint32_t seed);
210 
224  tensor_Dense(const tensor_Dense<Float> &tens, Float value);
225 
239 
253 
267  const view_tensor_Dense<tensor::tensor_Dense<Float>, Float> &tens);
268 
278  void set_ptr(const std::vector<size_t> &shape,
279  const std::vector<Float> &value);
280 
290  void set_ptr(const std::vector<size_t> &shape, const Float *value);
291 
301  void set_ptr(const std::vector<size_t> &shape, const Float value);
302 
310  [[nodiscard]] std::vector<size_t> get_shape() const { return shape; }
311 
319  [[nodiscard]] size_t get_nnz() const { return val_nnz; }
320 
328  [[nodiscard]] size_t get_alloc_nnz() const { return alloc_nnz; }
329 
336  [[nodiscard]] size_t get_first() const { return first; }
337 
344  [[nodiscard]] size_t get_offset() const { return get_first(); }
345 
353  void set_shape(const std::vector<size_t> &shape) { this->shape = shape; };
354 
362  // void set_nnz(const size_t NZ) { val_nnz = NZ; };
363 
369  void set_first(size_t i) { first = i; }
370 
378  [[nodiscard]] std::string type() const { return "tensor_Dense"; }
379 
380  // TODO
388  [[nodiscard]] double get_data_size() const {
389  return get_nnz() * sizeof(Float) / 1.0e+9;
390  }
391 
401  [[nodiscard]] Float at(const size_t pos) const;
402 
412  [[nodiscard]] Float at(const std::vector<size_t> &pos) const;
413 
423  template <typename... Args>
424  [[nodiscard]] Float at(const std::vector<size_t> &pos, const size_t dim,
425  const Args... args) const {
426  std::vector<size_t> pos_copy = pos;
427  pos_copy.push_back(dim);
428  return this->at(pos_copy, args...);
429  };
430 
440  template <typename... Args>
441 #if !defined(__clang__) && defined(__GNUC__)
442  [[nodiscard]] Float at(const size_t dim, const size_t dim2,
443  const Args... args) const {
444  std::vector<size_t> pos(1);
445  pos[0] = dim;
446  return this->at(pos, dim2, args...);
447  };
448 #else
449  [[nodiscard]] Float at(const size_t dim, const Args... args) const {
450  std::vector<size_t> pos(1);
451  pos[0] = dim;
452  return this->at(pos, args...);
453  };
454 #endif
455 
465  [[nodiscard]] Float at(const size_t pos) {
466  return static_cast<const tensor_Dense *>(this)->at(pos);
467  };
468 
478  [[nodiscard]] Float at(const std::vector<size_t> &pos) {
479  return static_cast<const tensor_Dense *>(this)->at(pos);
480  };
481 
491  template <typename... Args>
492  [[nodiscard]] Float at(const std::vector<size_t> &pos, const Args... args) {
493  return static_cast<const tensor_Dense *>(this)->at(pos, args...);
494  };
495 
505  template <typename... Args>
506  [[nodiscard]] Float at(const size_t dim, const Args... args) {
507  return static_cast<const tensor_Dense *>(this)->at(dim, args...);
508  };
509 
519  void insert(const size_t pos, const Float Val);
520 
530  void insert(const std::vector<size_t> &pos, const Float Val);
531 
540  void print_all(bool force_cpu = false) const;
541 
542  // communication
543  // ///////////////////////////////////////////////////////////////////////////
551  void send() const;
552 
560  void recv();
561 
569  void nonfree_recv();
570 
578  void device_free() const;
579 
584  [[nodiscard]] bool get_device_mem_stat() const { return *gpu_status; }
585 
590  [[nodiscard]] std::shared_ptr<bool> get_gpu_status() const {
591  return gpu_status;
592  }
593 
602  if (val_create_flag) {
603  if (get_device_mem_stat()) {
604  device_free();
605  }
606  }
607  }
608 
615  [[nodiscard]] const Float *data() const { return val.get(); }
616 
623  [[nodiscard]] Float *data() { return val.get(); }
624 
633  void resize(const size_t N, Float Val = 0) {
634  if (get_device_mem_stat()) {
635  throw std::runtime_error("Error, GPU matrix cant use resize");
636  }
637  if (val_create_flag) {
638  std::shared_ptr<Float> tmp(new Float[N], std::default_delete<Float[]>());
639  size_t copy_size = std::min(val_nnz, N);
640  for (size_t i = 0; i < copy_size; ++i) {
641  tmp.get()[i] = data()[i];
642  }
643  for (size_t i = copy_size; i < N; ++i) {
644  tmp.get()[i] = Val;
645  }
646  val = tmp;
647  alloc_nnz = N;
648  val_nnz = N;
649  } else {
650  throw std::runtime_error("Error, not create vector cant use resize");
651  }
652  }
653 
662  void resize(const std::vector<size_t> &shape, Float val = 0) {
663  size_t N = 1;
664  for (auto n : shape) {
665  N *= n;
666  }
667  resize(N, val);
668  this->shape = shape;
669  }
670 
676  void move(const matrix::Dense<Float> &dense);
677 
683  void move(const vector<Float> &vec);
684 
691  [[nodiscard]] const Float *begin() const { return data() + get_offset(); }
692 
699  [[nodiscard]] Float *begin() { return data() + get_offset(); }
700 
707  [[nodiscard]] const Float *end() const {
708  return data() + get_offset() + get_nnz();
709  }
710 
717  [[nodiscard]] Float *end() { return data() + get_offset() + get_nnz(); }
718 
727  void fill(Float value);
728 
741  void operator=(const tensor_Dense<Float> &tens);
742 
755  void operator=(const view_tensor_Dense<vector<Float>, Float> &tens);
756 
770 
783  void
785 
795  [[nodiscard]] Float &operator[](size_t i) {
796  if (get_device_mem_stat()) {
797  throw std::runtime_error("Error, GPU vector cant use operator[]");
798  }
799  return data()[first + i];
800  }
801 
812  [[nodiscard]] bool equal(const tensor_Dense<Float> &tens,
813  bool compare_cpu_and_device = false) const;
814 
826  [[nodiscard]] bool operator==(const tensor_Dense<Float> &tens) const;
827 
839  [[nodiscard]] bool operator!=(const tensor_Dense<Float> &tens) const;
840 
850  size_t get_index(const std::vector<size_t> &pos) const {
851  if (pos.size() != this->shape.size()) {
852  throw std::runtime_error("pos size should be same with the shape");
853  }
854  size_t ind = 0;
855  for (auto i = 0; i < pos.size(); ++i) {
856  ind *= this->shape[i];
857  ind += pos[i];
858  }
859  return ind;
860  }
861 
871  std::vector<size_t> get_index(const size_t pos) const {
872  std::vector<size_t> ind(this->shape.size(), 0);
873  auto pos_copy = pos;
874  for (int i = (int)this->shape.size() - 1; i >= 0; --i) {
875  ind[i] = pos_copy % this->shape[i];
876  pos_copy /= this->shape[i];
877  }
878  return ind;
879  }
880 
889  void reshape(const std::vector<int> &shape);
890 
899  template <typename... Args>
900  void reshape(const std::vector<int> &shape, const size_t dim,
901  const Args... args) {
902  std::vector<int> shape_copy = shape;
903  shape_copy.push_back(dim);
904  reshape(shape_copy, args...);
905  return;
906  }
907 
916  template <typename... Args> void reshape(const int dim, const Args... args) {
917  std::vector<int> shape(1);
918  shape[0] = dim;
919  reshape(shape, args...);
920  return;
921  }
922 
924 
933  void diag_add(const Float alpha);
934 
943  void diag_sub(const Float alpha);
944 
953  void diag_mul(const Float alpha);
954 
963  void diag_div(const Float alpha);
964 
973  void diag_add(const vector<Float> &vec);
974  void diag_add(const view1D<vector<Float>, Float> &vec);
975  void diag_add(const view1D<matrix::Dense<Float>, Float> &vec);
976  void diag_add(const view1D<tensor::tensor_Dense<Float>, Float> &vec);
977 
986  void diag_sub(const vector<Float> &vec);
987  void diag_sub(const view1D<vector<Float>, Float> &vec);
988  void diag_sub(const view1D<matrix::Dense<Float>, Float> &vec);
989  void diag_sub(const view1D<tensor::tensor_Dense<Float>, Float> &vec);
990 
999  void diag_mul(const vector<Float> &vec);
1000  void diag_mul(const view1D<vector<Float>, Float> &vec);
1001  void diag_mul(const view1D<matrix::Dense<Float>, Float> &vec);
1002  void diag_mul(const view1D<tensor::tensor_Dense<Float>, Float> &vec);
1003 
1012  void diag_div(const vector<Float> &vec);
1013  void diag_div(const view1D<vector<Float>, Float> &vec);
1014  void diag_div(const view1D<matrix::Dense<Float>, Float> &vec);
1015  void diag_div(const view1D<tensor::tensor_Dense<Float>, Float> &vec);
1016 };
1017 } // namespace tensor
1018 } // namespace monolish
Dense format Matrix.
void reshape(const std::vector< int > &shape)
Reshape tensor.
bool equal(const tensor_Dense< Float > &tens, bool compare_cpu_and_device=false) const
Comparing tensors (A == tens)
void reshape(const std::vector< int > &shape, const size_t dim, const Args... args)
Reshape tensor.
std::vector< size_t > get_index(const size_t pos) const
get vector index from aligned index (A[pos[0]][pos[1]]... = A[ind])
std::string type() const
get format name "tensor_Dense"
void diag_mul(const vector< Float > &vec)
Vector and diag. vector of Dense format matrix mul.
size_t get_index(const std::vector< size_t > &pos) const
get aligned index from vector index (A[pos] = A[ind[0]][ind[1]]...)
void convert(const matrix::Dense< Float > &dense)
create tensor_Dense tensor from Dense matrix
void diag_add(const view1D< matrix::Dense< Float >, Float > &vec)
tensor_Dense(const std::initializer_list< size_t > &shape)
Allocate dense tensor.
size_t get_first() const
get first position
bool operator!=(const tensor_Dense< Float > &tens) const
Comparing tensors (A != tens)
void diag_div(const view1D< tensor::tensor_Dense< Float >, Float > &vec)
tensor_Dense(const view_tensor_Dense< vector< Float >, Float > &tens)
Create Dense matrix from view Dense matrix.
void operator=(const view_tensor_Dense< tensor::tensor_Dense< Float >, Float > &tens)
tensor copy
std::vector< size_t > shape
shape
tensor_Dense(const std::vector< size_t > &shape, const std::vector< Float > &value)
Allocate tensor_Dense tensor.
void set_ptr(const std::vector< size_t > &shape, const Float value)
Set tensor_Dense array from array.
std::shared_ptr< Float > val
Dense tensor format value (pointer)
Float at(const std::vector< size_t > &pos, const Args... args)
get element A[pos[0]][pos[1]]... (onlu CPU)
void insert(const size_t pos, const Float Val)
set element A[index]...
Float at(const std::vector< size_t > &pos)
get element A[pos[0]][pos[1]]... (onlu CPU)
void operator=(const view_tensor_Dense< matrix::Dense< Float >, Float > &tens)
tensor copy
void diag_add(const Float alpha)
Scalar and diag. vector of Dense format matrix add.
void insert(const std::vector< size_t > &pos, const Float Val)
set element A[pos[0]][pos[1]]...
void recv()
recv. data to GPU, and free data on GPU
void send() const
send data to GPU
void diag_sub(const view1D< tensor::tensor_Dense< Float >, Float > &vec)
void diag_sub(const view1D< matrix::Dense< Float >, Float > &vec)
size_t val_nnz
# of non-zero element (M * N)
tensor_Dense(const matrix::Dense< Float > &dense)
Create tensor_Dense tensor from Dense matrix.
void diag_add(const view1D< vector< Float >, Float > &vec)
std::vector< size_t > get_shape() const
get shape
void diag_add(const view1D< tensor::tensor_Dense< Float >, Float > &vec)
void print_all(bool force_cpu=false) const
print all elements to standard I/O
void diag_sub(const view1D< vector< Float >, Float > &vec)
size_t alloc_nnz
allocated tensor size
void resize(const std::vector< size_t > &shape, Float val=0)
resize tensor value
void fill(Float value)
fill tensor elements with a scalar value
Float at(const size_t dim, const Args... args) const
get element A[pos[0]][pos[1]]...
size_t first
first position of data array
std::shared_ptr< bool > gpu_status
true: sended, false: not send
tensor_Dense(const tensor::tensor_Dense< Float > &tens)
Create tensor_Dense tensor from tensor_Dense tensor.
Float at(const std::vector< size_t > &pos) const
get element A[pos[0]][pos[1]]...
void move(const matrix::Dense< Float > &dense)
move tensor_Dense tensor from Dense matrix
Float * end()
returns a end iterator
void diag_div(const view1D< matrix::Dense< Float >, Float > &vec)
void diag_add(const vector< Float > &vec)
Vector and diag. vector of Dense format matrix add.
Float * data()
returns a direct pointer to the tensor
void diag_mul(const view1D< tensor::tensor_Dense< Float >, Float > &vec)
void nonfree_recv()
recv. data to GPU (w/o free)
void diag_mul(const view1D< matrix::Dense< Float >, Float > &vec)
const Float * data() const
returns a direct pointer to the tensor
Float at(const size_t pos)
get element A[index]... (onlu CPU)
Float at(const std::vector< size_t > &pos, const size_t dim, const Args... args) const
get element A[pos[0]][pos[1]]...
void set_shape(const std::vector< size_t > &shape)
Set shape.
tensor_Dense(const std::vector< size_t > &shape, const Float min, const Float max)
Allocate tensor_Dense tensor.
const Float * end() const
returns a end iterator
bool val_create_flag
tensor create flag
void diag_div(const Float alpha)
Scalar and diag. vector of Dense format matrix div.
void set_first(size_t i)
Set # of non-zero elements.
size_t get_alloc_nnz() const
get # of alloced non-zeros
void move(const vector< Float > &vec)
move tensor_Dense tensor from vector
void convert(const tensor::tensor_COO< Float > &tens)
Create tensor_Dense tensor from tensor_COO tensor.
size_t get_nnz() const
get # of non-zeros
tensor_Dense(const std::vector< size_t > &shape, const Float min, const Float max, const std::uint32_t seed)
Allocate tensor_Dense tensor.
void diag_sub(const vector< Float > &vec)
Vector and diag. vector of Dense format matrix sub.
tensor_Dense(const view_tensor_Dense< tensor::tensor_Dense< Float >, Float > &tens)
Create Dense matrix from view Dense matrix.
const Float * begin() const
returns a begin iterator
tensor_Dense(const std::vector< size_t > &shape, const Float *value)
Allocate dense tensor.
Float & operator[](size_t i)
reference to the element at position (v[i])
tensor_Dense(const view_tensor_Dense< matrix::Dense< Float >, Float > &tens)
Create Dense matrix from view Dense matrix.
void diag_sub(const Float alpha)
Scalar and diag. vector of Dense format matrix sub.
tensor_Dense(const tensor::tensor_COO< Float > &tens)
Create tensor_Dense tensor from tensor_COO tensor.
tensor_Dense(const vector< Float > &vec)
create tensor_Dense tensor from vector
void convert(const vector< Float > &vec)
create tensor_Dense tensor from vector
void set_ptr(const std::vector< size_t > &shape, const Float *value)
Set tensor_Dense array from array.
void operator=(const tensor_Dense< Float > &tens)
tensor copy
void device_free() const
free data on GPU
Float at(const size_t dim, const Args... args)
get element A[pos[0]][pos[1]]... (onlu CPU)
void set_ptr(const std::vector< size_t > &shape, const std::vector< Float > &value)
Set tensor_Dense array from std::vector.
void reshape(const int dim, const Args... args)
Reshape tensor.
Float * begin()
returns a begin iterator
Float at(const size_t pos) const
get element A[index]...
double get_data_size() const
Memory data space required by the matrix.
void resize(const size_t N, Float Val=0)
resize tensor value
~tensor_Dense()
destructor of dense tensor, free GPU memory
std::shared_ptr< bool > get_gpu_status() const
gpu status shared pointer
tensor_Dense(const tensor_Dense< Float > &tens, Float value)
Create tensor_Dense tensor of the same size as input tensor.
void diag_mul(const Float alpha)
Scalar and diag. vector of Dense format matrix mul.
void diag_div(const view1D< vector< Float >, Float > &vec)
void operator=(const view_tensor_Dense< vector< Float >, Float > &tens)
tensor copy
bool operator==(const tensor_Dense< Float > &tens) const
Comparing tensors (A == tens)
void diag_div(const vector< Float > &vec)
Vector and diag. vector of Dense format matrix div.
bool get_device_mem_stat() const
true: sended, false: not send
size_t get_offset() const
get first position (same as get_first())
tensor_Dense(const std::vector< size_t > &shape)
Allocate dense tensor.
void diag_mul(const view1D< vector< Float >, Float > &vec)
void convert(const tensor::tensor_Dense< Float > &tens)
Create tensor_Dense tensor from tensor_Dense tensor.
void max(const matrix::CRS< double > &A, const matrix::CRS< double > &B, matrix::CRS< double > &C)
Create a new CRS matrix with greatest elements of two matrices (C[0:nnz] = max(A[0:nnz],...
void min(const matrix::CRS< double > &A, const matrix::CRS< double > &B, matrix::CRS< double > &C)
Create a new CRS matrix with smallest elements of two matrices (C[0:nnz] = min(A[0:nnz],...
monolish namespaces