Line data Source code
1 : #include <algorithm> 2 : #include <chrono> 3 : #include <sstream> 4 : #include <string> 5 : #include <thread> 6 : 7 : #include "Module/Stateful/Initializer/Initializer.hpp" 8 : 9 : using namespace spu; 10 : using namespace spu::module; 11 : 12 : template<typename T> 13 122 : Initializer<T>::Initializer(const size_t n_elmts, const size_t ns) 14 : : Stateful() 15 122 : , init_data(this->get_n_frames(), std::vector<T>(n_elmts, 0)) 16 122 : , ns(ns) 17 : { 18 122 : const std::string name = "Initializer"; 19 122 : this->set_name(name); 20 122 : this->set_short_name(name); 21 : 22 122 : if (n_elmts == 0) 23 : { 24 0 : std::stringstream message; 25 0 : message << "'n_elmts' has to be greater than 0."; 26 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str()); 27 0 : } 28 : 29 122 : auto& p = this->create_task("initialize"); 30 122 : auto ps_out = this->template create_socket_out<T>(p, "out", n_elmts); 31 122 : this->create_codelet(p, 32 304806 : [ps_out](Module& m, runtime::Task& t, const size_t frame_id) -> int 33 : { 34 304806 : auto& ini = static_cast<Initializer&>(m); 35 304806 : ini._initialize(t[ps_out].template get_dataptr<T>(), frame_id); 36 309042 : return runtime::status_t::SUCCESS; 37 : }); 38 122 : } 39 : 40 : template<typename T> 41 : Initializer<T>* 42 2549 : Initializer<T>::clone() const 43 : { 44 2549 : auto m = new Initializer(*this); 45 2549 : m->deep_copy(*this); 46 2549 : return m; 47 : } 48 : 49 : template<typename T> 50 : size_t 51 0 : Initializer<T>::get_ns() const 52 : { 53 0 : return this->ns; 54 : } 55 : 56 : template<typename T> 57 : void 58 32 : Initializer<T>::set_ns(const size_t ns) 59 : { 60 32 : this->ns = ns; 61 32 : } 62 : 63 : template<typename T> 64 : const std::vector<std::vector<T>>& 65 0 : Initializer<T>::get_init_data() const 66 : { 67 0 : return this->init_data; 68 : } 69 : 70 : template<typename T> 71 : void 72 0 : Initializer<T>::set_init_data(const std::vector<T>& init_data) 73 : { 74 0 : if (init_data.size() != this->init_data[0].size()) 75 : { 76 0 : std::stringstream message; 77 0 : message << "'init_data.size()' has to be equal to 'this->init_data[0].size()' ('init_data.size()' = " 78 0 : << init_data.size() << ", 'this->init_data[0].size()' = " << this->init_data[0].size() << ")."; 79 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str()); 80 0 : } 81 : 82 0 : for (auto& ini : this->init_data) 83 0 : ini = init_data; 84 0 : } 85 : 86 : template<typename T> 87 : void 88 2548 : Initializer<T>::set_init_data(const std::vector<std::vector<T>>& init_data) 89 : { 90 2548 : if (init_data.size() != this->get_n_frames()) 91 : { 92 0 : std::stringstream message; 93 0 : message << "'init_data.size()' has to be equal to 'this->get_n_frames()' ('init_data.size()' = " 94 0 : << init_data.size() << ", 'this->get_n_frames()' = " << this->get_n_frames() << ")."; 95 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str()); 96 0 : } 97 : 98 26722 : for (size_t f = 0; f < init_data.size(); f++) 99 : { 100 24174 : if (init_data[f].size() != this->init_data[f].size()) 101 : { 102 0 : std::stringstream message; 103 0 : message << "'init_data[f].size()' has to be equal to 'this->init_data[f].size()' ('init_data[f].size()' = " 104 0 : << init_data[f].size() << ", 'this->init_data[f].size()' = " << this->init_data[f].size() 105 0 : << ", 'f' = " << f << ")."; 106 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str()); 107 0 : } 108 24174 : this->init_data[f] = init_data[f]; 109 : } 110 2548 : } 111 : 112 : template<typename T> 113 : void 114 0 : Initializer<T>::set_init_data(const T val) 115 : { 116 0 : for (auto& ini : this->init_data) 117 0 : std::fill(ini.begin(), ini.end(), val); 118 0 : } 119 : 120 : template<typename T> 121 : void 122 3708 : Initializer<T>::set_n_frames(const size_t n_frames) 123 : { 124 3708 : const auto old_n_frames = this->get_n_frames(); 125 3708 : if (old_n_frames != n_frames) 126 : { 127 3708 : Module::set_n_frames(n_frames); 128 : 129 3708 : this->init_data.resize(n_frames); 130 25334 : for (size_t f = old_n_frames; f < n_frames; f++) 131 21626 : this->init_data[f] = this->init_data[0]; 132 : } 133 3708 : } 134 : 135 : template<typename T> 136 : void 137 0 : Initializer<T>::initialize(T* out, const int frame_id, const bool managed_memory) 138 : { 139 0 : (*this)[ini::sck::initialize::out].bind(out); 140 0 : (*this)[ini::tsk::initialize].exec(frame_id, managed_memory); 141 0 : } 142 : 143 : template<typename T> 144 : void 145 304731 : Initializer<T>::_initialize(T* out, const size_t frame_id) 146 : { 147 304731 : std::chrono::time_point<std::chrono::steady_clock> t_start; 148 304731 : if (this->ns) t_start = std::chrono::steady_clock::now(); 149 : 150 304731 : std::copy(this->init_data[frame_id].begin(), this->init_data[frame_id].end(), out); 151 : 152 309175 : if (this->ns) 153 : { 154 6755 : std::chrono::nanoseconds duration = std::chrono::steady_clock::now() - t_start; 155 347171 : while ((size_t)duration.count() < this->ns) // active waiting 156 340412 : duration = std::chrono::steady_clock::now() - t_start; 157 : } 158 309171 : } 159 : 160 : // ==================================================================================== explicit template instantiation 161 : template class spu::module::Initializer<int8_t>; 162 : template class spu::module::Initializer<uint8_t>; 163 : template class spu::module::Initializer<int16_t>; 164 : template class spu::module::Initializer<uint16_t>; 165 : template class spu::module::Initializer<int32_t>; 166 : template class spu::module::Initializer<uint32_t>; 167 : template class spu::module::Initializer<int64_t>; 168 : template class spu::module::Initializer<uint64_t>; 169 : template class spu::module::Initializer<float>; 170 : template class spu::module::Initializer<double>; 171 : // ==================================================================================== explicit template instantiation