* Destructor, deallocates memory. Made virtual to allow for derived classes
* to behave properly.
*/
- virtual ~Vector ();
+ virtual ~Vector () = default;
/**
* This function does nothing but exists for compatibility with the parallel
/**
* Pointer to the array of elements of this vector.
+ *
+ * Because we allocate these arrays via Utilities::System::posix_memalign,
+ * we need to use a custom deleter for this object that does not call
+ * <code>delete[]</code>, but instead calls @p free().
*/
- Number *values;
+ std::unique_ptr<Number[], decltype(&free)> values;
/**
* For parallel loops with TBB, this member variable stores the affinity
* allocated memory is determined by @p max_vec_size .
*/
void allocate();
-
- /**
- * Deallocate @p values.
- */
- void deallocate();
};
/*@}*/
:
vec_size(0),
max_vec_size(0),
- values(nullptr)
+ values(nullptr, &free)
{
reinit(0);
}
:
vec_size (0),
max_vec_size (0),
- values (nullptr)
+ values (nullptr, &free)
{
// allocate memory. do not initialize it, as we will copy over to it in a
// second
:
vec_size(0),
max_vec_size(0),
- values(nullptr)
+ values(nullptr, &free)
{
reinit (n, false);
}
-template <typename Number>
-inline
-Vector<Number>::~Vector ()
-{
- if (values)
- {
- deallocate();
- values = nullptr;
- }
-}
-
-
-
template <typename Number>
inline
std::size_t Vector<Number>::size () const
typename Vector<Number>::iterator
Vector<Number>::begin ()
{
- return values;
+ return values.get();
}
typename Vector<Number>::const_iterator
Vector<Number>::begin () const
{
- return values;
+ return values.get();
}
typename Vector<Number>::iterator
Vector<Number>::end ()
{
- return values + vec_size;
+ return values.get() + vec_size;
}
typename Vector<Number>::const_iterator
Vector<Number>::end () const
{
- return values + vec_size;
+ return values.get() + vec_size;
}
{
Assert (indices.size() == values.size(),
ExcDimensionMismatch(indices.size(), values.size()));
- add (indices.size(), indices.data(), values.values);
+ add (indices.size(), indices.data(), values.values.get());
}
ar &static_cast<const Subscriptor &>(*this);
ar &vec_size &max_vec_size ;
- ar &boost::serialization::make_array(values, max_vec_size);
+ ar &boost::serialization::make_array(values.get(), max_vec_size);
}
Vector<Number>::load (Archive &ar, const unsigned int)
{
// get rid of previous content
- deallocate();
+ values.reset();
// the load stuff again from the archive
ar &static_cast<Subscriptor &>(*this);
ar &vec_size &max_vec_size ;
allocate();
- ar &boost::serialization::make_array(values, max_vec_size);
+ ar &boost::serialization::make_array(values.get(), max_vec_size);
}
#endif
Subscriptor(),
vec_size(v.size()),
max_vec_size(v.size()),
- values(nullptr)
+ values(nullptr, &free)
{
if (vec_size != 0)
{
Subscriptor(std::move(v)),
vec_size(v.vec_size),
max_vec_size(v.max_vec_size),
- values(v.values),
+ values(std::move(v.values)),
thread_loop_partitioner(std::move(v.thread_loop_partitioner))
{
v.vec_size = 0;
Subscriptor(),
vec_size(v.size()),
max_vec_size(v.size()),
- values(nullptr)
+ values(nullptr, &free)
{
if (vec_size != 0)
{
Subscriptor(),
vec_size(0),
max_vec_size(0),
- values(nullptr)
+ values(nullptr, &free)
{
if (v.size() != 0)
{
Subscriptor(),
vec_size(v.size()),
max_vec_size(v.size()),
- values(nullptr)
+ values(nullptr, &free)
{
if (vec_size != 0)
{
if (vec_size>0)
{
- dealii::internal::VectorOperations::Vector_copy<Number,Number> copier(v.values, values);
+ dealii::internal::VectorOperations::Vector_copy<Number,Number> copier(v.values.get(), values.get());
internal::VectorOperations::parallel_for(copier,0,vec_size,thread_loop_partitioner);
}
{
Subscriptor::operator=(std::move(v));
- if (values) deallocate();
-
vec_size = v.vec_size;
max_vec_size = v.max_vec_size;
- values = v.values;
+ values = std::move(v.values);
thread_loop_partitioner = std::move(v.thread_loop_partitioner);
v.vec_size = 0;
v.max_vec_size = 0;
- v.values = nullptr;
return *this;
}
if (vec_size != v.vec_size)
reinit (v, true);
- dealii::internal::VectorOperations::Vector_copy<Number,Number2> copier(v.values, values);
+ dealii::internal::VectorOperations::Vector_copy<Number,Number2> copier(v.values.get(), values.get());
internal::VectorOperations::parallel_for(copier,0,vec_size,thread_loop_partitioner);
return *this;
{
if (n==0)
{
- if (values) deallocate();
- values = nullptr;
+ values.reset();
max_vec_size = vec_size = 0;
thread_loop_partitioner.reset(new parallel::internal::TBBPartitioner());
return;
- };
+ }
if (n>max_vec_size)
{
- if (values) deallocate();
max_vec_size = n;
allocate();
- };
+ }
if (vec_size != n)
{
if (v.vec_size==0)
{
- if (values) deallocate();
- values = nullptr;
+ values.reset();
max_vec_size = vec_size = 0;
return;
- };
+ }
if (v.vec_size>max_vec_size)
{
- if (values) deallocate();
max_vec_size = v.vec_size;
allocate();
- };
+ }
vec_size = v.vec_size;
if (omit_zeroing_entries == false)
*this = Number();
if (vec_size>0)
{
- internal::VectorOperations::Vector_set<Number> setter(s, values);
+ internal::VectorOperations::Vector_set<Number> setter(s, values.get());
internal::VectorOperations::parallel_for(setter,0,vec_size,thread_loop_partitioner);
}
Assert (vec_size!=0, ExcEmptyObject());
- internal::VectorOperations::Vectorization_multiply_factor<Number> vector_multiply(values, factor);
+ internal::VectorOperations::Vectorization_multiply_factor<Number> vector_multiply(values.get(), factor);
internal::VectorOperations::parallel_for(vector_multiply,0,vec_size,thread_loop_partitioner);
Assert (vec_size!=0, ExcEmptyObject());
Assert (vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
- internal::VectorOperations::Vectorization_add_av<Number> vector_add_av(values, v.values, a);
+ internal::VectorOperations::Vectorization_add_av<Number> vector_add_av(values.get(), v.values.get(), a);
internal::VectorOperations::parallel_for(vector_add_av,0,vec_size,thread_loop_partitioner);
}
Assert (vec_size!=0, ExcEmptyObject());
Assert (vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
- internal::VectorOperations::Vectorization_sadd_xav<Number> vector_sadd_xav(values, v.values, a, x);
+ internal::VectorOperations::Vectorization_sadd_xav<Number> vector_sadd_xav(values.get(), v.values.get(), a, x);
internal::VectorOperations::parallel_for(vector_sadd_xav,0,vec_size,thread_loop_partitioner);
}
ExcDimensionMismatch(vec_size, v.size()));
Number sum;
- internal::VectorOperations::Dot<Number,Number2> dot(values, v.values);
+ internal::VectorOperations::Dot<Number,Number2> dot(values.get(), v.values.get());
internal::VectorOperations::parallel_reduce (dot, 0, vec_size, sum, thread_loop_partitioner);
AssertIsFinite(sum);
Assert (vec_size!=0, ExcEmptyObject());
real_type sum;
- internal::VectorOperations::Norm2<Number,real_type> norm2(values);
+ internal::VectorOperations::Norm2<Number,real_type> norm2(values.get());
internal::VectorOperations::parallel_reduce (norm2, 0, vec_size, sum, thread_loop_partitioner);
AssertIsFinite(sum);
Assert (vec_size!=0, ExcEmptyObject());
Number sum;
- internal::VectorOperations::MeanValue<Number> mean(values);
+ internal::VectorOperations::MeanValue<Number> mean(values.get());
internal::VectorOperations::parallel_reduce (mean, 0, vec_size, sum, thread_loop_partitioner);
return sum / real_type(size());
Assert (vec_size!=0, ExcEmptyObject());
real_type sum;
- internal::VectorOperations::Norm1<Number, real_type> norm1(values);
+ internal::VectorOperations::Norm1<Number, real_type> norm1(values.get());
internal::VectorOperations::parallel_reduce (norm1, 0, vec_size, sum, thread_loop_partitioner);
return sum;
Assert (vec_size!=0, ExcEmptyObject());
real_type norm_square;
- internal::VectorOperations::Norm2<Number, real_type> norm2(values);
+ internal::VectorOperations::Norm2<Number, real_type> norm2(values.get());
internal::VectorOperations::parallel_reduce (norm2, 0, vec_size, norm_square,
thread_loop_partitioner);
if (numbers::is_finite(norm_square) &&
return l2_norm();
real_type sum;
- internal::VectorOperations::NormP<Number, real_type> normp(values, p);
+ internal::VectorOperations::NormP<Number, real_type> normp(values.get(), p);
internal::VectorOperations::parallel_reduce (normp, 0, vec_size, sum, thread_loop_partitioner);
if (numbers::is_finite(sum) && sum >= std::numeric_limits<real_type>::min())
AssertDimension (vec_size, W.size());
Number sum;
- internal::VectorOperations::AddAndDot<Number> adder(this->values, V.values, W.values, a);
+ internal::VectorOperations::AddAndDot<Number> adder(this->values.get(), V.values.get(), W.values.get(), a);
internal::VectorOperations::parallel_reduce (adder, 0, vec_size, sum, thread_loop_partitioner);
AssertIsFinite(sum);
Assert (vec_size!=0, ExcEmptyObject());
Assert (vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
- internal::VectorOperations::Vectorization_add_v<Number> vector_add(values, v.values);
+ internal::VectorOperations::Vectorization_add_v<Number> vector_add(values.get(), v.values.get());
internal::VectorOperations::parallel_for(vector_add,0,vec_size,thread_loop_partitioner);
return *this;
}
Assert (vec_size!=0, ExcEmptyObject());
Assert (vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
- internal::VectorOperations::Vectorization_subtract_v<Number> vector_subtract(values, v.values);
+ internal::VectorOperations::Vectorization_subtract_v<Number> vector_subtract(values.get(), v.values.get());
internal::VectorOperations::parallel_for(vector_subtract,0,vec_size,thread_loop_partitioner);
return *this;
{
Assert (vec_size!=0, ExcEmptyObject());
- internal::VectorOperations::Vectorization_add_factor<Number> vector_add(values, v);
+ internal::VectorOperations::Vectorization_add_factor<Number> vector_add(values.get(), v);
internal::VectorOperations::parallel_for(vector_add,0,vec_size,thread_loop_partitioner);
}
Assert (vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
Assert (vec_size == w.vec_size, ExcDimensionMismatch(vec_size, w.vec_size));
- internal::VectorOperations::Vectorization_add_avpbw<Number> vector_add(values, v.values, w.values, a, b);
+ internal::VectorOperations::Vectorization_add_avpbw<Number> vector_add(values.get(), v.values.get(), w.values.get(), a, b);
internal::VectorOperations::parallel_for(vector_add,0,vec_size,thread_loop_partitioner);
}
Assert (vec_size!=0, ExcEmptyObject());
Assert (vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
- internal::VectorOperations::Vectorization_sadd_xv<Number> vector_sadd(values, v.values, x);
+ internal::VectorOperations::Vectorization_sadd_xv<Number> vector_sadd(values.get(), v.values.get(), x);
internal::VectorOperations::parallel_for(vector_sadd,0,vec_size,thread_loop_partitioner);
}
Assert (vec_size!=0, ExcEmptyObject());
Assert (vec_size == s.vec_size, ExcDimensionMismatch(vec_size, s.vec_size));
- internal::VectorOperations::Vectorization_scale<Number> vector_scale(values, s.values);
+ internal::VectorOperations::Vectorization_scale<Number> vector_scale(values.get(), s.values.get());
internal::VectorOperations::parallel_for(vector_scale,0,vec_size,thread_loop_partitioner);
}
Assert (vec_size!=0, ExcEmptyObject());
Assert (vec_size == u.vec_size, ExcDimensionMismatch(vec_size, u.vec_size));
- internal::VectorOperations::Vectorization_equ_au<Number> vector_equ(values, u.values, a);
+ internal::VectorOperations::Vectorization_equ_au<Number> vector_equ(values.get(), u.values.get(), a);
internal::VectorOperations::parallel_for(vector_equ,0,vec_size,thread_loop_partitioner);
}
// we overwrite them anyway
reinit (a.size(), true);
- internal::VectorOperations::Vectorization_ratio<Number> vector_ratio(values, a.values, b.values);
+ internal::VectorOperations::Vectorization_ratio<Number> vector_ratio(values.get(), a.values.get(), b.values.get());
internal::VectorOperations::parallel_for(vector_ratio,0,vec_size,thread_loop_partitioner);
}
void
Vector<Number>::allocate()
{
- // make sure that we don't create a memory leak
- Assert (values == nullptr, ExcInternalError());
-
- // then allocate memory with the proper alignment requirements of 64 bytes
- Utilities::System::posix_memalign ((void **)&values, 64, sizeof(Number)*max_vec_size);
+ // allocate memory with the proper alignment requirements of 64 bytes
+ Number *new_values;
+ Utilities::System::posix_memalign ((void **)&new_values, 64, sizeof(Number)*max_vec_size);
+ values.reset (new_values);
}
-template <typename Number>
-void
-Vector<Number>::deallocate()
-{
- free(values);
- values = nullptr;
-}
-
DEAL_II_NAMESPACE_CLOSE
#endif
AssertDimension(v.size(), this->n_cols());
AssertDimension(w.size(), this->n_rows());
- gemv("N", &mm, &nn, &alpha, &this->values[0], &mm, v.values, &one, &beta, w.values, &one);
+ gemv("N", &mm, &nn, &alpha, &this->values[0], &mm, v.values.get(), &one, &beta, w.values.get(), &one);
break;
}
case svd:
AssertDimension(w.size(), this->n_rows());
// Compute V^T v
work.resize(std::max(mm,nn));
- gemv("N", &nn, &nn, &alpha, &svd_vt->values[0], &nn, v.values, &one, &null, work.data(), &one);
+ gemv("N", &nn, &nn, &alpha, &svd_vt->values[0], &nn, v.values.get(), &one, &null, work.data(), &one);
// Multiply by singular values
for (size_type i=0; i<wr.size(); ++i)
work[i] *= wr[i];
// Multiply with U
- gemv("N", &mm, &mm, &alpha, &svd_u->values[0], &mm, work.data(), &one, &beta, w.values, &one);
+ gemv("N", &mm, &mm, &alpha, &svd_u->values[0], &mm, work.data(), &one, &beta, w.values.get(), &one);
break;
}
case inverse_svd:
AssertDimension(v.size(), this->n_rows());
// Compute U^T v
work.resize(std::max(mm,nn));
- gemv("T", &mm, &mm, &alpha, &svd_u->values[0], &mm, v.values, &one, &null, work.data(), &one);
+ gemv("T", &mm, &mm, &alpha, &svd_u->values[0], &mm, v.values.get(), &one, &null, work.data(), &one);
// Multiply by singular values
for (size_type i=0; i<wr.size(); ++i)
work[i] *= wr[i];
// Multiply with V
- gemv("T", &nn, &nn, &alpha, &svd_vt->values[0], &nn, work.data(), &one, &beta, w.values, &one);
+ gemv("T", &nn, &nn, &alpha, &svd_vt->values[0], &nn, work.data(), &one, &beta, w.values.get(), &one);
break;
}
default:
AssertDimension(w.size(), this->n_cols());
AssertDimension(v.size(), this->n_rows());
- gemv("T", &mm, &nn, &alpha, &this->values[0], &mm, v.values, &one, &beta, w.values, &one);
+ gemv("T", &mm, &nn, &alpha, &this->values[0], &mm, v.values.get(), &one, &beta, w.values.get(), &one);
break;
}
case svd:
// Compute U^T v
work.resize(std::max(mm,nn));
- gemv("T", &mm, &mm, &alpha, &svd_u->values[0], &mm, v.values, &one, &null, work.data(), &one);
+ gemv("T", &mm, &mm, &alpha, &svd_u->values[0], &mm, v.values.get(), &one, &null, work.data(), &one);
// Multiply by singular values
for (size_type i=0; i<wr.size(); ++i)
work[i] *= wr[i];
// Multiply with V
- gemv("T", &nn, &nn, &alpha, &svd_vt->values[0], &nn, work.data(), &one, &beta, w.values, &one);
+ gemv("T", &nn, &nn, &alpha, &svd_vt->values[0], &nn, work.data(), &one, &beta, w.values.get(), &one);
break;
}
case inverse_svd:
// Compute V^T v
work.resize(std::max(mm,nn));
- gemv("N", &nn, &nn, &alpha, &svd_vt->values[0], &nn, v.values, &one, &null, work.data(), &one);
+ gemv("N", &nn, &nn, &alpha, &svd_vt->values[0], &nn, v.values.get(), &one, &null, work.data(), &one);
// Multiply by singular values
for (size_type i=0; i<wr.size(); ++i)
work[i] *= wr[i];
// Multiply with U
- gemv("N", &mm, &mm, &alpha, &svd_u->values[0], &mm, work.data(), &one, &beta, w.values, &one);
+ gemv("N", &mm, &mm, &alpha, &svd_u->values[0], &mm, work.data(), &one, &beta, w.values.get(), &one);
break;
}
default: