FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
dense_vector_blocked.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
10#include <kernel/lafem/forward.hpp>
12#include <kernel/util/type_traits.hpp>
13#include <kernel/util/math.hpp>
14#include <kernel/util/random.hpp>
15#include <kernel/lafem/container.hpp>
16#include <kernel/lafem/dense_vector.hpp>
17#include <kernel/lafem/arch/dot_product.hpp>
18#include <kernel/lafem/arch/norm.hpp>
19#include <kernel/lafem/arch/scale.hpp>
20#include <kernel/lafem/arch/axpy.hpp>
21#include <kernel/lafem/arch/component_product.hpp>
22#include <kernel/lafem/arch/component_copy.hpp>
23#include <kernel/lafem/arch/component_invert.hpp>
24#include <kernel/lafem/arch/max_abs_index.hpp>
25#include <kernel/lafem/arch/min_abs_index.hpp>
26#include <kernel/lafem/arch/max_index.hpp>
27#include <kernel/lafem/arch/min_index.hpp>
28#include <kernel/lafem/arch/max_rel_diff.hpp>
29#include <kernel/util/tiny_algebra.hpp>
30#include <kernel/util/statistics.hpp>
31#include <kernel/util/time_stamp.hpp>
32#include <kernel/adjacency/permutation.hpp>
34
35#include <iostream>
36#include <fstream>
37#include <string>
38#include <stdint.h>
39
40namespace FEAT
41{
42 namespace LAFEM
43 {
45 namespace Intern
46 {
47 template <typename DT_, int BlockSize_, Perspective perspective_>
48 struct DenseVectorBlockedPerspectiveHelper
49 {
50 typedef Tiny::Vector<DT_, BlockSize_> Type;
51 };
52
53 template <typename DT_, int BlockSize_>
54 struct DenseVectorBlockedPerspectiveHelper<DT_, BlockSize_, Perspective::pod>
55 {
56 typedef DT_ Type;
57 };
58 } // namespace Intern
60
79 template <typename DT_, typename IT_, int BlockSize_>
80 class DenseVectorBlocked : public Container<DT_, IT_>
81 {
82 public:
84 typedef DT_ DataType;
86 typedef IT_ IndexType;
88 static constexpr int BlockSize = BlockSize_;
91
93 template <typename DT2_ = DT_, typename IT2_ = IT_>
95
97 template <typename DataType2_, typename IndexType2_>
99
106 {
107 public:
109 typedef DT_ DataType;
110 typedef IT_ IndexType;
112
113 private:
114 IT_ _num_entries;
115 ValueType * _data;
116
117 public:
118 explicit ScatterAxpy(VectorType & vector) :
119 _num_entries(IT_(vector.size())),
120 _data(vector.elements())
121 {
122 }
123
124 template <typename LocalVector_, typename Mapping_>
125 void operator()(const LocalVector_ & loc_vec, const Mapping_ & mapping, DT_ alpha = DT_(1))
126 {
127 // loop over all local entries
128 for (int i(0); i < mapping.get_num_local_dofs(); ++i)
129 {
130 // get dof index
131 Index dof_idx = mapping.get_index(i);
132 ASSERT(dof_idx < _num_entries);
133
134 // update vector data
135 _data[dof_idx] += alpha * loc_vec[i];
136 }
137 }
138 }; // class ScatterAxpy
139
146 {
147 public:
149 typedef DT_ DataType;
150 typedef IT_ IndexType;
152
153 private:
154 Index _num_entries;
155 const ValueType * _data;
156
157 public:
158 explicit GatherAxpy(const VectorType & vector) :
159 _num_entries(vector.size()),
160 _data(vector.elements())
161 {
162 }
163
164 template <typename LocalVector_, typename Mapping_>
165 void operator()(LocalVector_ & loc_vec, const Mapping_ & mapping, DT_ alpha = DT_(1))
166 {
167 // loop over all local entries
168 for (int i(0); i < mapping.get_num_local_dofs(); ++i)
169 {
170 // get dof index
171 Index dof_idx = mapping.get_index(i);
172 ASSERT(dof_idx < _num_entries);
173
174 // update local vector data
175 loc_vec[i].axpy(alpha, _data[dof_idx]);
176 }
177 }
178 }; // class GatherAxpy
179
180 private:
181 Index & _size()
182 {
183 return this->_scalar_index.at(0);
184 }
185
186 public:
193 Container<DT_, IT_> (0)
194 {
195 }
196
205 explicit DenseVectorBlocked(Index size_in) :
206 Container<DT_, IT_>(size_in)
207 {
208 if (size_in == Index(0))
209 return;
210
211 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(size<Perspective::pod>()));
212
213 this->_elements_size.push_back(size<Perspective::pod>());
214 }
215
227 explicit DenseVectorBlocked(Index size_in, DT_ value) :
228 Container<DT_, IT_>(size_in)
229 {
230 if (size_in == Index(0))
231 return;
232
233 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(size<Perspective::pod>()));
234 this->_elements_size.push_back(size<Perspective::pod>());
235
236 MemoryPool::set_memory(this->_elements.at(0), value, size<Perspective::pod>());
237 }
238
247 explicit DenseVectorBlocked(Index size_in, DT_ * data) :
248 Container<DT_, IT_>(size_in)
249 {
250 if (size_in == Index(0))
251 return;
252
253 this->_elements.push_back(data);
254 this->_elements_size.push_back(size<Perspective::pod>());
255
256 for (Index i(0) ; i < this->_elements.size() ; ++i)
258 for (Index i(0) ; i < this->_indices.size() ; ++i)
260 }
261
270 Container<DT_, IT_>(other.size() / Index(BlockSize_))
271 {
272 convert(other);
273 }
274
286 explicit DenseVectorBlocked(const DenseVectorBlocked & dv_in, Index size_in, Index offset_in) :
287 Container<DT_, IT_>(size_in)
288 {
289 this->_foreign_memory = true;
290
291 DT_ * te(const_cast<DT_ *>(dv_in.template elements<Perspective::pod>()));
292 this->_elements.push_back(te + offset_in * Index(BlockSize_));
293 this->_elements_size.push_back(size<Perspective::pod>());
294 }
295
304 explicit DenseVectorBlocked(FileMode mode, const String& filename) :
305 Container<DT_, IT_>(0)
306 {
307 read_from(mode, filename);
308 }
309
318 explicit DenseVectorBlocked(FileMode mode, std::istream& file) :
319 Container<DT_, IT_>(0)
320 {
321 read_from(mode, file);
322 }
323
331 template <typename DT2_ = DT_, typename IT2_ = IT_>
332 explicit DenseVectorBlocked(std::vector<char> input) :
333 Container<DT_, IT_>(0)
334 {
335 deserialize<DT2_, IT2_>(input);
336 }
337
348 explicit DenseVectorBlocked(Random & rng, Index size_in, DataType min, DataType max) :
349 Container<DT_, IT_>(size_in)
350 {
351 if (size_in == Index(0))
352 return;
353
354 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(size<Perspective::pod>()));
355 this->_elements_size.push_back(size<Perspective::pod>());
356
357 this->format(rng, min, max);
358 }
359
368 Container<DT_, IT_>(std::forward<DenseVectorBlocked>(other))
369 {
370 }
371
376 {
377 }
378
389 {
390 this->move(std::forward<DenseVectorBlocked>(other));
391
392 return *this;
393 }
394
403 {
405 t.clone(*this, clone_mode);
406 return t;
407 }
408
417 template< typename DT2_, typename IT2_>
419 {
420 Container<DT_, IT_>::clone(other, clone_mode);
421 }
422
430 template <typename DT2_, typename IT2_>
432 {
433 this->assign(other);
434 }
435
443 template <typename DT2_, typename IT2_>
445 {
446 XASSERTM(other.size() % Index(BlockSize_) == 0, "DenseVector cannot be converted to given blocksize!");
447
448 this->clear();
449
450 this->_scalar_index.push_back(other.size() / Index(BlockSize_));
451
452 this->_elements.push_back(other.get_elements().at(0));
453 this->_elements_size.push_back(size<Perspective::pod>());
454
455 for (Index i(0) ; i < this->_elements.size() ; ++i)
457 for (Index i(0) ; i < this->_indices.size() ; ++i)
459 }
460
468 template <typename DT2_ = DT_, typename IT2_ = IT_>
469 void deserialize(std::vector<char> input)
470 {
471 this->template _deserialize<DT2_, IT2_>(FileMode::fm_dvb, input);
472 }
473
487 template <typename DT2_ = DT_, typename IT2_ = IT_>
488 std::vector<char> serialize(const LAFEM::SerialConfig& config = LAFEM::SerialConfig()) const
489 {
490 return this->template _serialize<DT2_, IT2_>(FileMode::fm_dvb, config);
491 }
492
501 template <Perspective perspective_ = Perspective::native>
502 auto elements() const -> const typename Intern::DenseVectorBlockedPerspectiveHelper<DT_, BlockSize_, perspective_>::Type *
503 {
504 if (this->size() == 0)
505 return nullptr;
506
507 return (const typename Intern::DenseVectorBlockedPerspectiveHelper<DT_, BlockSize_, perspective_>::Type *)(this->_elements.at(0));
508 }
509
512 template <Perspective perspective_ = Perspective::native>
513 auto elements() -> typename Intern::DenseVectorBlockedPerspectiveHelper<DT_, BlockSize_, perspective_>::Type *
514 {
515 if (this->size() == 0)
516 return nullptr;
517
518 return (typename Intern::DenseVectorBlockedPerspectiveHelper<DT_, BlockSize_, perspective_>::Type *)(this->_elements.at(0));
519 }
520
527 template <Perspective perspective_ = Perspective::native>
528 Index size() const
529 {
530 if constexpr(perspective_ == Perspective::pod)
531 return static_cast<const Container<DT_, IT_> *>(this)->size() * Index(BlockSize_);
532 else
533 return static_cast<const Container<DT_, IT_> *>(this)->size();
534 }
535
544 {
545 ASSERT(index < this->size());
546
547 MemoryPool::synchronize();
548
549 return this->elements<Perspective::native>()[index];
550 }
551
559 {
560 ASSERT(index < this->size());
561 this->elements<Perspective::native>()[index] = value;
562 MemoryPool::synchronize();
563 }
564
570 static String name()
571 {
572 return "DenseVectorBlocked";
573 }
574
581 void copy(const DenseVectorBlocked & x, bool full = false)
582 {
583 this->_copy_content(x, full);
584 }
585
592 void read_from(FileMode mode, const String& filename)
593 {
594 std::ios_base::openmode bin = std::ifstream::in | std::ifstream::binary;
595 if (mode == FileMode::fm_mtx)
596 bin = std::ifstream::in;
597 std::ifstream file(filename.c_str(), bin);
598 if (! file.is_open())
599 XABORTM("Unable to open Vector file " + filename);
600 read_from(mode, file);
601 file.close();
602 }
603
610 void read_from(FileMode mode, std::istream & file)
611 {
612 switch (mode)
613 {
614 case FileMode::fm_mtx:
615 {
616 this->clear();
617 this->_scalar_index.push_back(0);
618
619 Index rows;
620 String line;
621 std::getline(file, line);
622 if (line.find("%%MatrixMarket matrix array real general") == String::npos)
623 {
624 XABORTM("Input-file is not a compatible mtx-vector-file");
625 }
626 while (! file.eof())
627 {
628 std::getline(file, line);
629 if (file.eof())
630 XABORTM("Input-file is empty");
631
632 String::size_type begin(line.find_first_not_of(" "));
633 if (line.at(begin) != '%')
634 break;
635 }
636 {
637 String::size_type begin(line.find_first_not_of(" "));
638 line.erase(0, begin);
639 String::size_type end(line.find_first_of(" "));
640 String srows(line, 0, end);
641 rows = (Index)atol(srows.c_str());
642 line.erase(0, end);
643
644 begin = line.find_first_not_of(" ");
645 line.erase(0, begin);
646 end = line.find_first_of(" ");
647 String scols(line, 0, end);
648 Index cols((Index)atol(scols.c_str()));
649 line.erase(0, end);
650 if (cols != 1)
651 XABORTM("Input-file is no dense-vector-file");
652 }
653
654 DenseVectorBlocked<DT_, IT_, BlockSize_> tmp(rows / BlockSize_);
655 DT_ * pval(tmp.template elements<Perspective::pod>());
656
657 while (! file.eof())
658 {
659 std::getline(file, line);
660 if (file.eof())
661 break;
662
663 String::size_type begin(line.find_first_not_of(" "));
664 line.erase(0, begin);
665 String::size_type end(line.find_first_of(" "));
666 String sval(line, 0, end);
667 DT_ tval((DT_)atof(sval.c_str()));
668
669 *pval = tval;
670 ++pval;
671 }
672 this->move(std::move(tmp));
673 break;
674 }
675 case FileMode::fm_exp:
676 {
677 this->clear();
678 this->_scalar_index.push_back(0);
679
680 std::vector<DT_> data;
681
682 while (! file.eof())
683 {
684 std::string line;
685 std::getline(file, line);
686 if (line.find("#", 0) < line.npos)
687 continue;
688 if (file.eof())
689 break;
690
691 std::string n_z_s;
692
693 std::string::size_type first_digit(line.find_first_not_of(" "));
694 line.erase(0, first_digit);
695 std::string::size_type eol(line.length());
696 for (std::string::size_type i(0); i < eol; ++i)
697 {
698 n_z_s.append(1, line[i]);
699 }
700
701 DT_ n_z((DT_)atof(n_z_s.c_str()));
702
703 data.push_back(n_z);
704 }
705
706 _size() = Index(data.size()) / Index(BlockSize_);
707 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(Index(data.size())));
708 this->_elements_size.push_back(Index(data.size()));
709 MemoryPool::template copy<DT_>(this->_elements.at(0), &data[0], Index(data.size()));
710 break;
711 }
712 case FileMode::fm_dvb:
714 {
715 this->clear();
716
717 this->template _deserialize<double, std::uint64_t>(FileMode::fm_dvb, file);
718 break;
719 }
720 default:
721 XABORTM("Filemode not supported!");
722 }
723 }
724
731 void write_out(FileMode mode, const String& filename) const
732 {
733 std::ios_base::openmode bin = std::ofstream::out | std::ofstream::binary;
734 if (mode == FileMode::fm_mtx || mode == FileMode::fm_exp)
735 bin = std::ofstream::out;
736 std::ofstream file;
737 char* buff = nullptr;
738 if(mode == FileMode::fm_mtx)
739 {
740 buff = new char[LAFEM::FileOutStreamBufferSize];
741 file.rdbuf()->pubsetbuf(buff, LAFEM::FileOutStreamBufferSize);
742 }
743 file.open(filename.c_str(), bin);
744 if(! file.is_open())
745 XABORTM("Unable to open Matrix file " + filename);
746 write_out(mode, file);
747 file.close();
748 delete[] buff;
749 }
750
757 void write_out(FileMode mode, std::ostream & file) const
758 {
759 switch (mode)
760 {
761 case FileMode::fm_mtx:
762 {
764 temp.convert(*this);
765
766 const Index tsize(temp.template size<Perspective::pod>());
767 file << "%%MatrixMarket matrix array real general\n";
768 file << tsize << " " << 1 << "\n";
769
770 const DT_ * pval(temp.template elements<Perspective::pod>());
771 for (Index i(0); i < tsize; ++i, ++pval)
772 {
773 file << stringify_fp_sci(*pval) << "\n";
774 }
775 break;
776 }
777 case FileMode::fm_exp:
778 {
779 DT_ * temp = MemoryPool::template allocate_memory<DT_>((this->size<Perspective::pod>()));
780 MemoryPool::template copy<DT_>(temp, this->template elements<Perspective::pod>(), this->size<Perspective::pod>());
781
782 for (Index i(0); i < this->size<Perspective::pod>(); ++i)
783 {
784 file << stringify_fp_sci(temp[i]) << "\n";
785 }
786
788 break;
789 }
790 case FileMode::fm_dvb:
792 this->template _serialize<double, std::uint64_t>(FileMode::fm_dvb, file);
793 break;
794 default:
795 XABORTM("Filemode not supported!");
796 }
797 }
798
801
808 void axpy(
809 const DenseVectorBlocked & x,
810 const DT_ alpha = DT_(1))
811 {
812 XASSERTM(x.size() == this->size(), "Vector size does not match!");
813
814 FEAT_KERNEL_MARKER_START("DV_axpy");
815
816 TimeStamp ts_start;
817
818 Statistics::add_flops(this->size<Perspective::pod>() * 2);
819 Arch::Axpy::value(elements<Perspective::pod>(), alpha, x.template elements<Perspective::pod>(), this->size<Perspective::pod>());
820
821 FEAT_KERNEL_MARKER_STOP("DV_axpy");
822 TimeStamp ts_stop;
823 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
824 }
833 const DenseVectorBlocked & x,
834 const ValueType alpha)
835 {
836 XASSERTM(x.size() == this->size(), "Vector size does not match!");
837
838 FEAT_KERNEL_MARKER_START("DV_axpy");
839
840 TimeStamp ts_start;
841
842 Statistics::add_flops(this->size<Perspective::pod>() * 2);
843 Arch::Axpy::value_blocked(elements<Perspective::native>(), alpha, x.template elements<Perspective::native>(), this->size<Perspective::native>());
844
845 FEAT_KERNEL_MARKER_STOP("DV_axpy");
846 TimeStamp ts_stop;
847 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
848 }
849
857 {
858 XASSERTM(this->size() == x.size(), "Vector size does not match!");
859 XASSERTM(this->size() == y.size(), "Vector size does not match!");
860
861 TimeStamp ts_start;
862
863 Arch::ComponentProduct::value(elements<Perspective::pod>(), x.template elements<Perspective::pod>(), y.template elements<Perspective::pod>(), this->size<Perspective::pod>());
864 Statistics::add_flops(this->size<Perspective::pod>());
865
866 TimeStamp ts_stop;
867 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
868 }
869
876 void component_copy(const DenseVector<DT_, IT_>& x, const int block_)
877 {
878 XASSERTM(block_ >= 0, "Block index has to be a positive integer!");
879 XASSERTM(Index(block_) < this->size(), "Block index is too big!");
880 XASSERTM(this->size() == x.size(), "Vector size does not match!");
881 TimeStamp ts_start;
882
883 Arch::ComponentCopy::value(elements<Perspective::pod>(), x.template elements<Perspective::pod>(), BlockSize_, block_, this->size<Perspective::native>());
884 Statistics::add_flops(this->size<Perspective::pod>());
885
886 TimeStamp ts_stop;
887 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
888 }
889
896 void component_copy_to(DenseVector<DT_, IT_>& x, const int block_) const
897 {
898 XASSERTM(block_ >= 0, "Block index has to be a positive integer!");
899 XASSERTM(Index(block_) < this->size(), "Block index is too big!");
900 XASSERTM(this->size() == x.size(), "Vector size does not match!");
901 TimeStamp ts_start;
902
903 Arch::ComponentCopy::value_to(elements<Perspective::pod>(), x.template elements<Perspective::pod>(), BlockSize_, block_, this->size<Perspective::native>());
904 Statistics::add_flops(this->size<Perspective::pod>());
905
906 TimeStamp ts_stop;
907 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
908 }
909
919 void component_invert(const DenseVectorBlocked & x, const DT_ alpha = DT_(1))
920 {
921 XASSERTM(this->size() == x.size(), "Vector size does not match!");
922
923 TimeStamp ts_start;
924
925 Arch::ComponentInvert::value(this->template elements<Perspective::pod>(), x.template elements<Perspective::pod>(), alpha, this->size<Perspective::pod>());
926 Statistics::add_flops(this->size<Perspective::pod>());
927
928 TimeStamp ts_stop;
929 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
930 }
931
938 void scale(const DenseVectorBlocked & x, const DT_ alpha)
939 {
940 XASSERTM(x.size() == this->size(), "Vector size does not match!");
941
942 TimeStamp ts_start;
943
944 Arch::Scale::value(elements<Perspective::pod>(), x.template elements<Perspective::pod>(), alpha, this->size<Perspective::pod>());
945 Statistics::add_flops(this->size<Perspective::pod>());
946
947 TimeStamp ts_stop;
948 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
949 }
950
957 void scale_blocked(const DenseVectorBlocked & x, const ValueType alpha)
958 {
959 XASSERTM(x.size() == this->size(), "Vector size does not match!");
960
961 TimeStamp ts_start;
962
963 Arch::Scale::value_blocked(elements<Perspective::native>(), x.template elements<Perspective::native>(), alpha, this->size<Perspective::native>());
964 Statistics::add_flops(this->size<Perspective::pod>());
965
966 TimeStamp ts_stop;
967 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
968 }
969
980 {
981 XASSERTM(x.template size<Perspective::pod>() == this->template size<Perspective::pod>(), "Vector size does not match!");
982 XASSERTM(y.template size<Perspective::pod>() == this->template size<Perspective::pod>(), "Vector size does not match!");
983
984 TimeStamp ts_start;
985
986 Statistics::add_flops(this->template size<Perspective::pod>() * 3);
987 DataType result = Arch::TripleDotProduct::value(this->template elements<Perspective::pod>(), x.template elements<Perspective::pod>(), y.template elements<Perspective::pod>(), this->template size<Perspective::pod>());
988
989 TimeStamp ts_stop;
990 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
991
992 return result;
993 }
994
1005 {
1006 XASSERTM(x.size() == this->size(), "Vector size does not match!");
1007 XASSERTM(y.size() == this->size(), "Vector size does not match!");
1008
1009 TimeStamp ts_start;
1010
1011 Statistics::add_flops(this->template size<Perspective::pod>() * 3);
1012 ValueType result = Arch::TripleDotProduct::value_blocked(elements<Perspective::native>(), x.template elements<Perspective::native>(), y.template elements<Perspective::native>(), this->size<Perspective::native>());
1013
1014 TimeStamp ts_stop;
1015 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1016
1017 return result;
1018 }
1019
1028 {
1029 XASSERTM(x.size() == this->size(), "Vector size does not match!");
1030
1031 TimeStamp ts_start;
1032
1033 Statistics::add_flops(this->size<Perspective::pod>() * 2);
1034 DataType result = Arch::DotProduct::value(elements<Perspective::pod>(), x.template elements<Perspective::pod>(), this->size<Perspective::pod>());
1035
1036 TimeStamp ts_stop;
1037 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1038
1039 return result;
1040 }
1041
1050 {
1051 XASSERTM(x.size() == this->size(), "Vector size does not match!");
1052
1053 TimeStamp ts_start;
1054
1055 Statistics::add_flops(this->size<Perspective::pod>() * 2);
1056 ValueType result = Arch::DotProduct::value_blocked(elements<Perspective::native>(), x.template elements<Perspective::native>(), this->size<Perspective::native>());
1057
1058 TimeStamp ts_stop;
1059 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1060
1061 return result;
1062 }
1063
1069 DT_ norm2() const
1070 {
1071 TimeStamp ts_start;
1072
1073 Statistics::add_flops(this->size<Perspective::pod>() * 2);
1074 DataType result = Arch::Norm2::value(elements<Perspective::pod>(), this->size<Perspective::pod>());
1075
1076 TimeStamp ts_stop;
1077 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1078
1079 return result;
1080 }
1081
1088 {
1089 TimeStamp ts_start;
1090
1091 Statistics::add_flops(this->size<Perspective::pod>() * 2);
1092 ValueType result = Arch::Norm2::value_blocked(elements<Perspective::native>(), this->size<Perspective::native>());
1093
1094 TimeStamp ts_stop;
1095 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1096
1097 return result;
1098 }
1099
1105 DT_ norm2sqr() const
1106 {
1107 // fallback
1108 return Math::sqr(this->norm2());
1109 }
1110
1116 ValueType norm2sqr_blocked() const
1117 {
1118 TimeStamp ts_start;
1119
1120 Statistics::add_flops(this->size<Perspective::pod>() * 2);
1121 ValueType result = Arch::Norm2Sqr::value_blocked(elements<Perspective::native>(), this->size<Perspective::native>());
1122
1123 TimeStamp ts_stop;
1124 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1125
1126 return result;
1127 }
1128
1135 {
1136 TimeStamp ts_start;
1137
1138 Index max_abs_index = Arch::MaxAbsIndex::value(this->template elements<Perspective::pod>(), this->template size<Perspective::pod>());
1139 ASSERT(max_abs_index < this->template size<Perspective::pod>());
1140 DT_ result;
1141 MemoryPool::template copy<DT_>(&result, this->template elements<Perspective::pod>() + max_abs_index, 1);
1142 result = Math::abs(result);
1143
1144 TimeStamp ts_stop;
1145 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1146
1147 return result;
1148 }
1149
1156 {
1157 TimeStamp ts_start;
1158
1159 ValueType result = Arch::MaxAbsIndex::value_blocked(this->template elements<Perspective::native>(), this->template size<Perspective::native>());
1160
1161 TimeStamp ts_stop;
1162 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1163
1164 return result;
1165 }
1166
1173 {
1174 TimeStamp ts_start;
1175
1176 Index min_abs_index = Arch::MinAbsIndex::value(this->template elements<Perspective::pod>(), this->template size<Perspective::pod>());
1177 ASSERT(min_abs_index < this->template size<Perspective::pod>());
1178 DT_ result;
1179 MemoryPool::template copy<DT_>(&result, this->template elements<Perspective::pod>() + min_abs_index, 1);
1180 result = Math::abs(result);
1181
1182 TimeStamp ts_stop;
1183 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1184
1185 return result;
1186 }
1187
1194 {
1195 TimeStamp ts_start;
1196
1197 ValueType result = Arch::MinAbsIndex::value_blocked(this->template elements<Perspective::native>(), this->template size<Perspective::native>());
1198
1199 TimeStamp ts_stop;
1200 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1201
1202 return result;
1203 }
1204
1210 DT_ max_element() const
1211 {
1212 TimeStamp ts_start;
1213
1214 Index max_index = Arch::MaxIndex::value(this->template elements<Perspective::pod>(), this->template size<Perspective::pod>());
1215 ASSERT(max_index < this->template size<Perspective::pod>());
1216 DT_ result;
1217 MemoryPool::template copy<DT_>(&result, this->template elements<Perspective::pod>() + max_index, 1);
1218
1219 TimeStamp ts_stop;
1220 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1221
1222 return result;
1223 }
1224
1231 {
1232 TimeStamp ts_start;
1233
1234 ValueType result = Arch::MaxIndex::value_blocked(this->template elements<Perspective::native>(), this->template size<Perspective::native>());
1235
1236 TimeStamp ts_stop;
1237 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1238
1239 return result;
1240 }
1241
1247 DT_ min_element() const
1248 {
1249 TimeStamp ts_start;
1250
1251 Index min_index = Arch::MinIndex::value(this->template elements<Perspective::pod>(), this->template size<Perspective::pod>());
1252 ASSERT(min_index < this->template size<Perspective::pod>());
1253 DT_ result;
1254 MemoryPool::template copy<DT_>(&result, this->template elements<Perspective::pod>() + min_index, 1);
1255
1256 TimeStamp ts_stop;
1257 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1258
1259 return result;
1260 }
1261
1268 {
1269 TimeStamp ts_start;
1270
1271 ValueType result = Arch::MinIndex::value_blocked(this->template elements<Perspective::native>(), this->template size<Perspective::native>());
1272
1273 TimeStamp ts_stop;
1274 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1275
1276 return result;
1277 }
1278
1286 {
1287 XASSERTM(x.used_elements() == this->used_elements(), "Nonzero count does not match!");
1288 TimeStamp ts_start;
1289
1290 DataType max_rel_diff = Arch::MaxRelDiff::value(this->template elements<Perspective::pod>(), x.template elements<Perspective::pod>(), this->template size<Perspective::pod>());
1291
1292 TimeStamp ts_stop;
1293 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
1294
1295 return max_rel_diff;
1296 }
1297
1306 bool same_layout(const DenseVectorBlocked& x) const
1307 {
1308 if (this->size() == 0 && x.size() == 0 && this->get_elements().size() == 0 && x.get_elements().size() == 0)
1309 return true;
1310 if (this->size() != x.size())
1311 return false;
1312 if (this->get_elements().size() != x.get_elements().size())
1313 return false;
1314 if (this->get_indices().size() != x.get_indices().size())
1315 return false;
1316
1317 return true;
1318 }
1319
1321
1324 {
1325 if (perm.size() == 0)
1326 return;
1327
1328 XASSERTM(perm.size() == this->size(), "Container size does not match permutation size");
1329
1330 perm.apply(elements<Perspective::native>());
1331 }
1332
1335 void set_vec(DT_ * const pval_set) const
1336 {
1337 MemoryPool::copy(pval_set, this->template elements<Perspective::pod>(), this->size<Perspective::pod>());
1338 }
1339
1341 void set_vec_inv(const DT_ * const pval_set)
1342 {
1343 MemoryPool::copy(this->template elements<Perspective::pod>(), pval_set, this->size<Perspective::pod>());
1344 }
1346
1347
1354 friend std::ostream & operator<<(std::ostream & lhs, const DenseVectorBlocked & b)
1355 {
1356 lhs << "[";
1357 for (Index i(0); i < b.size(); ++i)
1358 {
1360 for (int j(0); j < BlockSize_; ++j)
1361 lhs << " " << stringify(t[j]);
1362 }
1363 lhs << "]";
1364
1365 return lhs;
1366 }
1367
1377 template<typename DT2_, typename IT2_>
1379 {
1380 XASSERTM(this->size() == normal_vector.size(), "Sizes do not match");
1381 XASSERTM(this->size() == projected_vector.size(), "Target size do not match");
1382
1383 for(Index i = 0; i < this->size(); ++i)
1384 {
1385 projected_vector(i, Tiny::project_onto(this->operator()(i), normal_vector(i)));
1386 }
1387 }
1388 }; // class DenseVectorBlocked<...>
1389
1390 } // namespace LAFEM
1391} // namespace FEAT
#define ASSERT(expr)
Debug-Assertion macro definition.
Definition: assertion.hpp:229
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
Index size() const
returns the size of the permutation
void apply(Tx_ *x, bool invert=false) const
Applies In-Situ permutation.
Container base class.
Definition: container.hpp:220
const std::vector< IT_ * > & get_indices() const
Returns a list of all Index arrays.
Definition: container.hpp:1078
bool _foreign_memory
do we use memory that we did not allocate, nor are we allowed to free it - this mostly holds true,...
Definition: container.hpp:238
std::vector< DT_ * > _elements
List of pointers to all datatype dependent arrays.
Definition: container.hpp:226
Index used_elements() const
Returns the number of effective stored elements.
Definition: container.hpp:1155
const std::vector< DT_ * > & get_elements() const
Returns a list of all data arrays.
Definition: container.hpp:1068
std::vector< Index > _elements_size
List of corresponding datatype array sizes.
Definition: container.hpp:230
Index size() const
Returns the containers size.
Definition: container.hpp:1136
void assign(const Container< DT2_, IT2_ > &other)
Assignment operation.
Definition: container.hpp:280
std::vector< IT_ * > _indices
List of pointers to all IT_ dependent arrays.
Definition: container.hpp:228
void clone(const Container &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
Definition: container.hpp:902
void move(Container &&other)
Assignment move operation.
Definition: container.hpp:989
virtual void clear()
Free all allocated arrays.
Definition: container.hpp:875
void format(DT_ value=DT_(0))
Reset all elements of the container to a given value or zero if missing.
Definition: container.hpp:851
std::vector< Index > _scalar_index
List of scalars with datatype index.
Definition: container.hpp:234
Gather-Axpy operation for DenseVectorBlocked.
Scatter-Axpy operation for DenseVectorBlocked.
Blocked Dense data vector class template.
void read_from(FileMode mode, std::istream &file)
Read in vector from stream.
DT_ max_abs_element() const
Retrieve the absolute maximum value of this vector.
DenseVectorBlocked(std::vector< char > input)
Constructor.
void convert(const DenseVectorBlocked< DT2_, IT2_, BlockSize_ > &other)
Conversion method.
static constexpr int BlockSize
Our size of a single block.
static String name()
Returns a descriptive string.
ValueType dot_blocked(const DenseVectorBlocked &x) const
Calculate .
DenseVectorBlocked(DenseVectorBlocked &&other)
Move Constructor.
ValueType min_abs_element_blocked() const
Retrieve the absolute minimum value of this vector.
void project_onto(DenseVectorBlocked< DT_, IT_, BlockSize_ > &projected_vector, const LAFEM::DenseVectorBlocked< DT2_, IT2_, BlockSize_ > &normal_vector) const
Projects this vector onto a another one.
DenseVectorBlocked(Random &rng, Index size_in, DataType min, DataType max)
Constructor.
void axpy(const DenseVectorBlocked &x, const DT_ alpha=DT_(1))
Calculate .
void permute(Adjacency::Permutation &perm)
Permutate vector according to the given Permutation.
void write_out(FileMode mode, const String &filename) const
Write out vector to file.
void copy(const DenseVectorBlocked &x, bool full=false)
Performs .
void convert(const DenseVector< DT2_, IT2_ > &other)
Conversion method.
void read_from(FileMode mode, const String &filename)
Read in vector from file.
DenseVectorBlocked(Index size_in)
Constructor.
ValueType max_element_blocked() const
Retrieve the maximum value of this vector.
void component_product(const DenseVectorBlocked &x, const DenseVectorBlocked &y)
Calculate .
auto elements() const -> const typename Intern::DenseVectorBlockedPerspectiveHelper< DT_, BlockSize_, perspective_ >::Type *
Retrieve a pointer to the data array.
bool same_layout(const DenseVectorBlocked &x) const
Checks if the structural layout of this vector matches that of another vector. This excludes comparis...
void scale(const DenseVectorBlocked &x, const DT_ alpha)
Calculate .
DenseVectorBlocked(Index size_in, DT_ *data)
Constructor.
DataType dot(const DenseVectorBlocked &x) const
Calculate .
DT_ norm2() const
Calculates and returns the euclid norm of this vector.
ValueType min_element_blocked() const
Retrieve the minimum value of this vector.
DenseVectorBlocked(FileMode mode, const String &filename)
Constructor.
void clone(const DenseVectorBlocked< DT2_, IT2_, BlockSize_ > &other, CloneMode clone_mode=CloneMode::Deep)
Clone operation.
DenseVectorBlocked & operator=(DenseVectorBlocked &&other)
Assignment move operator.
DT_ max_element() const
Retrieve the maximum value of this vector.
Index size() const
The number of elements.
DT_ max_rel_diff(const DenseVectorBlocked &x) const
Retrieve the maximum relative difference of this vector and another one y.max_rel_diff(x) returns .
ValueType norm2_blocked() const
Calculates and returns the euclid norm of this vector.
void component_copy_to(DenseVector< DT_, IT_ > &x, const int block_) const
Copies the elements of a specific block of this blocked vector into a dense vector.
Tiny::Vector< DT_, BlockSize_ > ValueType
Our value type.
DT_ min_abs_element() const
Retrieve the absolute minimum value of this vector.
void operator()(Index index, const Tiny::Vector< DT_, BlockSize_ > &value)
Set specific vector element.
void deserialize(std::vector< char > input)
Deserialization of complete container entity.
auto elements() -> typename Intern::DenseVectorBlockedPerspectiveHelper< DT_, BlockSize_, perspective_ >::Type *
void component_invert(const DenseVectorBlocked &x, const DT_ alpha=DT_(1))
Performs .
DT_ min_element() const
Retrieve the minimum value of this vector.
DataType triple_dot(const DenseVectorBlocked &x, const DenseVectorBlocked &y) const
Calculate .
friend std::ostream & operator<<(std::ostream &lhs, const DenseVectorBlocked &b)
DenseVectorBlocked streaming operator.
DenseVectorBlocked clone(CloneMode clone_mode=CloneMode::Deep) const
Clone operation.
void component_copy(const DenseVector< DT_, IT_ > &x, const int block_)
Copies the elements of a dense vector into a specific block of this blocked vector.
DenseVectorBlocked(FileMode mode, std::istream &file)
Constructor.
ValueType max_abs_element_blocked() const
Retrieve the absolute maximum value of this vector.
void scale_blocked(const DenseVectorBlocked &x, const ValueType alpha)
Calculate .
std::vector< char > serialize(const LAFEM::SerialConfig &config=LAFEM::SerialConfig()) const
Serialization of complete container entity.
DenseVectorBlocked(const DenseVectorBlocked &dv_in, Index size_in, Index offset_in)
Constructor.
ValueType norm2sqr_blocked() const
Calculates and returns the squared euclid norm of this vector.
const Tiny::Vector< DT_, BlockSize_ > operator()(Index index) const
Retrieve specific vector element.
ValueType triple_dot_blocked(const DenseVectorBlocked &x, const DenseVectorBlocked &y) const
Calculate .
void write_out(FileMode mode, std::ostream &file) const
Write out vector to file.
DT_ norm2sqr() const
Calculates and returns the squared euclid norm of this vector.
DenseVectorBlocked(Index size_in, DT_ value)
Constructor.
void axpy_blocked(const DenseVectorBlocked &x, const ValueType alpha)
Calculate .
DenseVectorBlocked(const DenseVector< DT_, IT_ > &other)
Constructor.
Dense data vector class template.
Config class for serialize parameter.
Definition: container.hpp:47
static void copy(DT_ *dest, const DT_ *src, const Index count)
Copy memory area from src to dest.
static void set_memory(DT_ *address, const DT_ val, const Index count=1)
set memory to specific value
static void release_memory(void *address)
release memory or decrease reference counter
static void increase_memory(void *address)
increase memory counter
Pseudo-Random Number Generator.
Definition: random.hpp:54
static void add_flops(Index flops)
Add an amount of flops to the global flop counter.
Definition: statistics.hpp:206
String class implementation.
Definition: string.hpp:46
Time stamp class.
Definition: time_stamp.hpp:54
double elapsed(const TimeStamp &before) const
Calculates the time elapsed between two time stamps.
Definition: time_stamp.hpp:100
Tiny Vector class template.
constexpr std::size_t FileOutStreamBufferSize
OutStreamBufferSize.
Definition: base.hpp:124
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
T_ sqr(T_ x)
Returns the square of a value.
Definition: math.hpp:95
Type
bitmask for zfp header
Definition: pack.hpp:81
CUDA_HOST Vector< T_, dim_ > project_onto(const Vector< T_, dim_ > &x, const Vector< T_, dim_ > &y)
Calculates the projected vector.
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
String stringify_fp_sci(DataType_ value, int precision=0, int width=0, bool sign=false)
Prints a floating point value to a string in scientific notation.
Definition: string.hpp:1088
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.