5 #ifndef FML_CPU_CPUVEC_H
6 #define FML_CPU_CPUVEC_H
16 #include "../_internals/arraytools/src/arraytools.hpp"
18 #include "../_internals/omp.hh"
19 #include "../_internals/print.hh"
20 #include "../_internals/univec.hh"
36 cpuvec(T *data, len_t
size,
bool free_on_destruct=
false);
42 void inherit(T *data, len_t
size,
bool free_on_destruct=
false);
45 void print(uint8_t ndigits=4,
bool add_final_blank=
true)
const;
53 void subset(
const len_t start,
const len_t stop,
const bool interior=
true);
55 void scale(
const T s);
63 T
get(
const len_t i)
const;
64 void set(
const len_t i,
const T v);
72 bool free_on_destruct()
const {
return this->free_data;};
73 void dont_free_on_destruct() {this->free_data=
false;};
77 void check_params(len_t
size);
102 this->free_data =
true;
119 template <
typename T>
125 this->free_data =
true;
130 const size_t len = (size_t) size *
sizeof(T);
131 this->data = (T*) std::malloc(len);
132 if (this->data == NULL)
133 throw std::bad_alloc();
150 template <
typename T>
158 this->free_data = free_on_destruct;
163 template <
typename T>
166 this->_size = x.size();
167 this->data = x.data_ptr();
169 this->free_data = x.free_on_destruct();
170 x.dont_free_on_destruct();
175 template <
typename T>
178 this->_size = x.size();
179 this->data.resize(this->_size);
181 size_t len = (size_t) this->_size *
sizeof(T);
182 std::memcpy(this->data, x.data_ptr(), len);
184 this->free_data =
true;
189 template <
typename T>
209 template <
typename T>
219 else if (this->_size == size)
222 const size_t len = (size_t) size *
sizeof(T);
225 if (this->_size == 0)
226 realloc_ptr = malloc(len);
228 realloc_ptr = realloc(this->data, len);
230 if (realloc_ptr == NULL)
231 throw std::bad_alloc();
233 this->data = (T*) realloc_ptr;
251 template <
typename T>
261 this->free_data = free_on_destruct;
267 template <
typename T>
272 const size_t len = (size_t) this->_size *
sizeof(T);
273 memcpy(cpy.
data_ptr(), this->data, len);
288 template <
typename T>
291 for (len_t i=0; i<this->_size; i++)
292 this->printval(this->data[i], ndigits);
294 fml::print::putchar(
'\n');
296 fml::print::putchar(
'\n');
302 template <
typename T>
305 fml::print::printf(
"# cpuvec");
306 fml::print::printf(
" %d", this->_size);
307 fml::print::printf(
" type=%s",
typeid(T).name());
308 fml::print::printf(
"\n");
316 template <
typename T>
319 const size_t len = (size_t) this->_size *
sizeof(T);
320 memset(this->data, 0, len);
330 template <
typename T>
333 #pragma omp parallel for simd if(this->_size > fml::omp::OMP_MIN_SIZE)
334 for (len_t i=0; i<this->_size; i++)
346 template <
typename T>
350 T stop = (T) (this->_size);
351 this->fill_linspace(start, stop);
354 template <
typename REAL>
358 this->fill_val(start);
361 const REAL v = (stop-start)/((REAL) this->_size - 1);
363 #pragma omp parallel for simd if(this->_size > fml::omp::OMP_MIN_SIZE)
364 for (len_t i=0; i<this->_size; i++)
365 this->data[i] = v*((REAL) i) + start;
373 this->fill_val(start);
376 const float v = (stop-start)/((
float) this->_size - 1);
378 #pragma omp parallel for simd if(this->_size > fml::omp::OMP_MIN_SIZE)
379 for (len_t i=0; i<this->_size; i++)
380 this->data[i] = (
int) roundf(v*((
float) i) + start);
386 template <
typename REAL>
389 len_t size_new = interior ? stop-start : this->_size - (stop-start);
390 size_t len = size_new *
sizeof(REAL);
391 REAL *data_new = (REAL*) malloc(len);
392 if (data_new == NULL)
393 throw std::bad_alloc();
396 std::memcpy(data_new, this->data + start, len);
399 len_t n = std::max(start-1, 0);
400 std::memcpy(data_new, this->data, n*
sizeof(REAL));
401 if (stop < this->_size)
403 n = this->_size-stop;
404 std::memcpy(data_new, this->data + stop, n*
sizeof(REAL));
408 std::free(this->data);
409 this->data = data_new;
410 this->_size = size_new;
420 template <
typename T>
423 #pragma omp parallel for simd if(this->_size > fml::omp::OMP_MIN_SIZE)
424 for (len_t i=0; i<this->_size; i++)
435 template <
typename T>
438 #pragma omp parallel for simd if(this->_size > fml::omp::OMP_MIN_SIZE)
439 for (len_t i=0; i<this->_size; i++)
440 this->data[i] = std::pow(this->data[i], p);
446 template <
typename T>
449 len_t j = this->_size - 1;
451 for (len_t i=0; i<this->_size/2; i++)
453 const T tmp = this->data[i];
454 this->data[i] = this->data[j];
463 template <
typename T>
468 #pragma omp parallel for simd if(this->_size > fml::omp::OMP_MIN_SIZE) reduction(+:s)
469 for (len_t i=0; i<this->_size; i++)
478 template <
typename T>
481 T mx = this->data[0];
483 #pragma omp parallel for simd if(this->_size > fml::omp::OMP_MIN_SIZE) reduction(max:mx)
484 for (len_t i=1; i<this->_size; i++)
486 if (mx < this->data[i])
496 template <
typename T>
499 T mn = this->data[0];
501 #pragma omp parallel for simd if(this->_size > fml::omp::OMP_MIN_SIZE) reduction(min:mn)
502 for (len_t i=1; i<this->_size; i++)
504 if (mn < this->data[i])
523 template <
typename T>
526 this->check_index(i);
527 return this->data[i];
539 template <
typename T>
542 this->check_index(i);
556 template <
typename T>
559 if (this->_size != x.
size())
561 else if (this->data == x.
data_ptr())
565 for (len_t i=0; i<this->_size; i++)
567 const T a = this->data[i];
569 if (!arraytools::fltcmp::eq(a, b))
582 template <
typename T>
585 return !(*
this == x);
596 template <
typename T>
599 this->_size = x.
size();
602 this->free_data = x.free_on_destruct();
603 x.dont_free_on_destruct();
608 template <
typename T>
611 this->_size = x.
size();
614 this->free_data =
false;
625 template <
typename T>
628 if (this->free_data && this->data)
630 std::free(this->data);
637 template <
typename REAL>
641 throw std::runtime_error(
"invalid dimensions");