// Resize the underlying array on the host or on the device
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
struct la_parallel_vector_templates_functions
{
- static_assert(
- std::is_same<MemorySpace, ::dealii::MemorySpace::Host>::value ||
- std::is_same<MemorySpace, ::dealii::MemorySpace::CUDA>::value,
- "MemorySpace should be Host or CUDA");
+ static_assert(std::is_same<MemorySpaceType, MemorySpace::Host>::value ||
+ std::is_same<MemorySpaceType, MemorySpace::CUDA>::value,
+ "MemorySpace should be Host or CUDA");
static void
- resize_val(const types::global_dof_index /*new_alloc_size*/,
- types::global_dof_index & /*allocated_size*/,
- ::dealii::MemorySpace::MemorySpaceData<Number, MemorySpace>
- & /*data*/)
+ resize_val(
+ const types::global_dof_index /*new_alloc_size*/,
+ types::global_dof_index & /*allocated_size*/,
+ ::dealii::MemorySpace::MemorySpaceData<Number, MemorySpaceType>
+ & /*data*/)
{}
static void
const std::shared_ptr<const ::dealii::Utilities::MPI::Partitioner> &
/*communication_pattern*/,
const IndexSet & /*locally_owned_elem*/,
- ::dealii::MemorySpace::MemorySpaceData<Number, MemorySpace>
+ ::dealii::MemorySpace::MemorySpaceData<Number, MemorySpaceType>
& /*data*/)
{}
template <typename RealType>
static void
linfty_norm_local(
- const ::dealii::MemorySpace::MemorySpaceData<Number, MemorySpace>
+ const ::dealii::MemorySpace::MemorySpaceData<Number, MemorySpaceType>
& /*data*/,
const unsigned int /*size*/,
RealType & /*max*/)
} // namespace internal
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::clear_mpi_requests()
+ Vector<Number, MemorySpaceType>::clear_mpi_requests()
{
#ifdef DEAL_II_WITH_MPI
for (size_type j = 0; j < compress_requests.size(); j++)
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::resize_val(const size_type new_alloc_size)
+ Vector<Number, MemorySpaceType>::resize_val(const size_type new_alloc_size)
{
- internal::la_parallel_vector_templates_functions<Number, MemorySpace>::
- resize_val(new_alloc_size, allocated_size, data);
+ internal::la_parallel_vector_templates_functions<
+ Number,
+ MemorySpaceType>::resize_val(new_alloc_size, allocated_size, data);
thread_loop_partitioner =
std::make_shared<::dealii::parallel::internal::TBBPartitioner>();
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::reinit(const size_type size,
- const bool omit_zeroing_entries)
+ Vector<Number, MemorySpaceType>::reinit(const size_type size,
+ const bool omit_zeroing_entries)
{
clear_mpi_requests();
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
template <typename Number2>
void
- Vector<Number, MemorySpace>::reinit(const Vector<Number2, MemorySpace> &v,
- const bool omit_zeroing_entries)
+ Vector<Number, MemorySpaceType>::reinit(
+ const Vector<Number2, MemorySpaceType> &v,
+ const bool omit_zeroing_entries)
{
clear_mpi_requests();
Assert(v.partitioner.get() != nullptr, ExcNotInitialized());
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::reinit(const IndexSet &locally_owned_indices,
- const IndexSet &ghost_indices,
- const MPI_Comm communicator)
+ Vector<Number, MemorySpaceType>::reinit(
+ const IndexSet &locally_owned_indices,
+ const IndexSet &ghost_indices,
+ const MPI_Comm communicator)
{
// set up parallel partitioner with index sets and communicator
std::shared_ptr<const Utilities::MPI::Partitioner> new_partitioner(
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::reinit(const IndexSet &locally_owned_indices,
- const MPI_Comm communicator)
+ Vector<Number, MemorySpaceType>::reinit(
+ const IndexSet &locally_owned_indices,
+ const MPI_Comm communicator)
{
// set up parallel partitioner with index sets and communicator
std::shared_ptr<const Utilities::MPI::Partitioner> new_partitioner(
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::reinit(
+ Vector<Number, MemorySpaceType>::reinit(
const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner_in)
{
clear_mpi_requests();
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace>::Vector()
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType>::Vector()
: partitioner(new Utilities::MPI::Partitioner())
, allocated_size(0)
{
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace>::Vector(const Vector<Number, MemorySpace> &v)
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType>::Vector(
+ const Vector<Number, MemorySpaceType> &v)
: Subscriptor()
, allocated_size(0)
, vector_is_ghosted(false)
if (this_size > 0)
{
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::copy(
+ functions<Number, Number, MemorySpaceType>::copy(
thread_loop_partitioner, partitioner->local_size(), v.data, data);
}
}
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace>::Vector(const IndexSet &local_range,
- const IndexSet &ghost_indices,
- const MPI_Comm communicator)
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType>::Vector(const IndexSet &local_range,
+ const IndexSet &ghost_indices,
+ const MPI_Comm communicator)
: allocated_size(0)
, vector_is_ghosted(false)
{
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace>::Vector(const IndexSet &local_range,
- const MPI_Comm communicator)
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType>::Vector(const IndexSet &local_range,
+ const MPI_Comm communicator)
: allocated_size(0)
, vector_is_ghosted(false)
{
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace>::Vector(const size_type size)
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType>::Vector(const size_type size)
: allocated_size(0)
, vector_is_ghosted(false)
{
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace>::Vector(
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType>::Vector(
const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
: allocated_size(0)
, vector_is_ghosted(false)
- template <typename Number, typename MemorySpace>
- inline Vector<Number, MemorySpace>::~Vector()
+ template <typename Number, typename MemorySpaceType>
+ inline Vector<Number, MemorySpaceType>::~Vector()
{
try
{
- template <typename Number, typename MemorySpace>
- inline Vector<Number, MemorySpace> &
- Vector<Number, MemorySpace>::operator=(const Vector<Number, MemorySpace> &c)
+ template <typename Number, typename MemorySpaceType>
+ inline Vector<Number, MemorySpaceType> &
+ Vector<Number, MemorySpaceType>::
+ operator=(const Vector<Number, MemorySpaceType> &c)
{
#ifdef _MSC_VER
return this->operator=<Number>(c);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
template <typename Number2>
- inline Vector<Number, MemorySpace> &
- Vector<Number, MemorySpace>::
- operator=(const Vector<Number2, MemorySpace> &c)
+ inline Vector<Number, MemorySpaceType> &
+ Vector<Number, MemorySpaceType>::
+ operator=(const Vector<Number2, MemorySpaceType> &c)
{
Assert(c.partitioner.get() != nullptr, ExcNotInitialized());
if (this_size > 0)
{
dealii::internal::VectorOperations::
- functions<Number, Number2, MemorySpace>::copy(
+ functions<Number, Number2, MemorySpaceType>::copy(
thread_loop_partitioner, this_size, c.data, data);
}
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
template <typename Number2>
void
- Vector<Number, MemorySpace>::copy_locally_owned_data_from(
- const Vector<Number2, MemorySpace> &src)
+ Vector<Number, MemorySpaceType>::copy_locally_owned_data_from(
+ const Vector<Number2, MemorySpaceType> &src)
{
AssertDimension(partitioner->local_size(), src.partitioner->local_size());
if (partitioner->local_size() > 0)
{
dealii::internal::VectorOperations::
- functions<Number, Number2, MemorySpace>::copy(
+ functions<Number, Number2, MemorySpaceType>::copy(
thread_loop_partitioner,
partitioner->local_size(),
src.data,
}
} // namespace petsc_helpers
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace> &
- Vector<Number, MemorySpace>::
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType> &
+ Vector<Number, MemorySpaceType>::
operator=(const PETScWrappers::MPI::Vector &petsc_vec)
{
// TODO: We would like to use the same compact infrastructure as for the
#ifdef DEAL_II_WITH_TRILINOS
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace> &
- Vector<Number, MemorySpace>::
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType> &
+ Vector<Number, MemorySpaceType>::
operator=(const TrilinosWrappers::MPI::Vector &trilinos_vec)
{
# ifdef DEAL_II_WITH_MPI
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::compress(
+ Vector<Number, MemorySpaceType>::compress(
::dealii::VectorOperation::values operation)
{
compress_start(0, operation);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::update_ghost_values() const
+ Vector<Number, MemorySpaceType>::update_ghost_values() const
{
update_ghost_values_start();
update_ghost_values_finish();
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::zero_out_ghosts() const
+ Vector<Number, MemorySpaceType>::zero_out_ghosts() const
{
if (data.values != nullptr)
std::fill_n(data.values.get() + partitioner->local_size(),
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::compress_start(
+ Vector<Number, MemorySpaceType>::compress_start(
const unsigned int counter,
::dealii::VectorOperation::values operation)
{
std::lock_guard<std::mutex> lock(mutex);
// allocate import_data in case it is not set up yet
- if (import_data.values == nullptr && partitioner->n_import_indices() > 0)
+ if (partitioner->n_import_indices() > 0)
{
- Number *new_val;
- Utilities::System::posix_memalign((void **)&new_val,
- 64,
- sizeof(Number) *
- partitioner->n_import_indices());
- import_data.values.reset(new_val);
+# if defined(DEAL_II_COMPILER_CUDA_AWARE) && \
+ defined(DEAL_II_WITH_CUDA_AWARE_MPI)
+ Assert(
+ (std::is_same<MemorySpaceType, dealii::MemorySpace::CUDA>::value),
+ ExcMessage(
+ "Using MemorySpace::CUDA only allowed if the code is compiled with a CUDA compiler!"));
+ if (import_data.values_dev == nullptr)
+ import_data.values_dev.reset(
+ Utilities::CUDA::allocate_device_data<Number>(
+ partitioner->n_import_indices()));
+# else
+# ifdef DEAL_II_WITH_CUDA_AWARE_MPI
+ static_assert(
+ std::is_same<MemorySpaceType, dealii::MemorySpace::Host>::value,
+ "This code path should only be compiled for CUDA-aware-MPI for MemorySpace::Host!");
+# endif
+ if (import_data.values == nullptr)
+ {
+ Number *new_val;
+ Utilities::System::posix_memalign(
+ (void **)&new_val,
+ 64,
+ sizeof(Number) * partitioner->n_import_indices());
+ import_data.values.reset(new_val);
+ }
+# endif
}
-# ifdef DEAL_II_COMPILER_CUDA_AWARE
- // TODO: for now move the data to the host and then move it back to the
+# if defined DEAL_II_COMPILER_CUDA_AWARE && \
+ !defined(DEAL_II_WITH_CUDA_AWARE_MPI)
+ // Move the data to the host and then move it back to the
// the device. We use values to store the elements because the function
// uses a view of the array and thus we need the data on the host to
// outlive the scope of the function.
- if (std::is_same<MemorySpace, ::dealii::MemorySpace::CUDA>::value)
- {
- Number *new_val;
- Utilities::System::posix_memalign((void **)&new_val,
- 64,
- sizeof(Number) * allocated_size);
- data.values.reset(new_val);
-
- cudaError_t cuda_error_code =
- cudaMemcpy(data.values.get(),
- data.values_dev.get(),
- allocated_size * sizeof(Number),
- cudaMemcpyDeviceToHost);
- AssertCuda(cuda_error_code);
- }
+ Number *new_val;
+ Utilities::System::posix_memalign((void **)&new_val,
+ 64,
+ sizeof(Number) * allocated_size);
+
+ data.values.reset(new_val);
+
+ cudaError_t cuda_error_code = cudaMemcpy(data.values.get(),
+ data.values_dev.get(),
+ allocated_size * sizeof(Number),
+ cudaMemcpyDeviceToHost);
+ AssertCuda(cuda_error_code);
# endif
+
+# if !(defined(DEAL_II_COMPILER_CUDA_AWARE) && \
+ defined(DEAL_II_WITH_CUDA_AWARE_MPI))
partitioner->import_from_ghosted_array_start(
operation,
counter,
ArrayView<Number>(import_data.values.get(),
partitioner->n_import_indices()),
compress_requests);
+# else
+ partitioner->import_from_ghosted_array_start(
+ operation,
+ counter,
+ ArrayView<Number>(data.values_dev.get() + partitioner->local_size(),
+ partitioner->n_ghost_indices()),
+ ArrayView<Number>(import_data.values_dev.get(),
+ partitioner->n_import_indices()),
+ compress_requests);
+# endif
#endif
}
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::compress_finish(
+ Vector<Number, MemorySpaceType>::compress_finish(
::dealii::VectorOperation::values operation)
{
#ifdef DEAL_II_WITH_MPI
// make this function thread safe
std::lock_guard<std::mutex> lock(mutex);
-
+# if !(defined(DEAL_II_COMPILER_CUDA_AWARE) && \
+ defined(DEAL_II_WITH_CUDA_AWARE_MPI))
Assert(partitioner->n_import_indices() == 0 ||
import_data.values != nullptr,
ExcNotInitialized());
- partitioner->import_from_ghosted_array_finish(
+ partitioner->import_from_ghosted_array_finish<Number, MemorySpace::Host>(
operation,
ArrayView<const Number>(import_data.values.get(),
partitioner->n_import_indices()),
ArrayView<Number>(data.values.get() + partitioner->local_size(),
partitioner->n_ghost_indices()),
compress_requests);
+# else
+ Assert(partitioner->n_import_indices() == 0 ||
+ import_data.values_dev != nullptr,
+ ExcNotInitialized());
+ partitioner->import_from_ghosted_array_finish<Number, MemorySpace::CUDA>(
+ operation,
+ ArrayView<const Number>(import_data.values_dev.get(),
+ partitioner->n_import_indices()),
+ ArrayView<Number>(data.values_dev.get(), partitioner->local_size()),
+ ArrayView<Number>(data.values_dev.get() + partitioner->local_size(),
+ partitioner->n_ghost_indices()),
+ compress_requests);
+# endif
-# ifdef DEAL_II_COMPILER_CUDA_AWARE
- // TODO For now, the communication is done on the host, so we need to
+# if defined DEAL_II_COMPILER_CUDA_AWARE && \
+ !defined DEAL_II_WITH_CUDA_AWARE_MPI
+ // The communication is done on the host, so we need to
// move the data back to the device.
- if (std::is_same<MemorySpace, ::dealii::MemorySpace::CUDA>::value)
+ if (std::is_same<MemorySpaceType, MemorySpace::CUDA>::value)
{
cudaError_t cuda_error_code =
cudaMemcpy(data.values_dev.get(),
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::update_ghost_values_start(
+ Vector<Number, MemorySpaceType>::update_ghost_values_start(
const unsigned int counter) const
{
#ifdef DEAL_II_WITH_MPI
std::lock_guard<std::mutex> lock(mutex);
// allocate import_data in case it is not set up yet
- if (import_data == nullptr && partitioner->n_import_indices() > 0)
- import_data =
- std_cxx14::make_unique<Number[]>(partitioner->n_import_indices());
+ if (partitioner->n_import_indices() > 0)
+ {
+# if defined(DEAL_II_COMPILER_CUDA_AWARE) && \
+ defined(DEAL_II_WITH_CUDA_AWARE_MPI)
+ Assert(
+ (std::is_same<MemorySpaceType, dealii::MemorySpace::CUDA>::value),
+ ExcMessage(
+ "Using MemorySpace::CUDA only allowed if the code is compiled with a CUDA compiler!"));
+ if (import_data.values_dev == nullptr)
+ import_data.values_dev.reset(
+ Utilities::CUDA::allocate_device_data<Number>(
+ partitioner->n_import_indices()));
+# else
+# ifdef DEAL_II_WITH_CUDA_AWARE_MPI
+ static_assert(
+ std::is_same<MemorySpaceType, dealii::MemorySpace::Host>::value,
+ "This code path should only be compiled for CUDA-aware-MPI for MemorySpace::Host!");
+# endif
+ if (import_data.values == nullptr)
+ {
+ Number *new_val;
+ Utilities::System::posix_memalign(
+ (void **)&new_val,
+ 64,
+ sizeof(Number) * partitioner->n_import_indices());
+ import_data.values.reset(new_val);
+ }
+# endif
+ }
-# ifdef DEAL_II_COMPILER_CUDA_AWARE
- // TODO: for now move the data to the host and then move it back to the
+# if defined DEAL_II_COMPILER_CUDA_AWARE && \
+ !defined(DEAL_II_WITH_CUDA_AWARE_MPI)
+ // Move the data to the host and then move it back to the
// the device. We use values to store the elements because the function
// uses a view of the array and thus we need the data on the host to
// outlive the scope of the function.
- if (std::is_same<MemorySpace, ::dealii::MemorySpace::CUDA>::value)
- {
- Number *new_val;
- Utilities::System::posix_memalign((void **)&new_val,
- 64,
- sizeof(Number) * allocated_size);
-
- data.values.reset(new_val);
-
- cudaError_t cuda_error_code =
- cudaMemcpy(data.values.get(),
- data.values_dev.get(),
- allocated_size * sizeof(Number),
- cudaMemcpyDeviceToHost);
- AssertCuda(cuda_error_code);
- }
+ Number *new_val;
+ Utilities::System::posix_memalign((void **)&new_val,
+ 64,
+ sizeof(Number) * allocated_size);
+
+ data.values.reset(new_val);
+
+ cudaError_t cuda_error_code = cudaMemcpy(data.values.get(),
+ data.values_dev.get(),
+ allocated_size * sizeof(Number),
+ cudaMemcpyDeviceToHost);
+ AssertCuda(cuda_error_code);
# endif
- partitioner->export_to_ghosted_array_start(
+# if !(defined(DEAL_II_COMPILER_CUDA_AWARE) && \
+ defined(DEAL_II_WITH_CUDA_AWARE_MPI))
+ partitioner->export_to_ghosted_array_start<Number, MemorySpaceType>(
counter,
ArrayView<const Number>(data.values.get(), partitioner->local_size()),
- ArrayView<Number>(import_data.get(), partitioner->n_import_indices()),
+ ArrayView<Number>(import_data.values.get(),
+ partitioner->n_import_indices()),
ArrayView<Number>(data.values.get() + partitioner->local_size(),
partitioner->n_ghost_indices()),
update_ghost_values_requests);
+# else
+ partitioner->export_to_ghosted_array_start<Number, MemorySpaceType>(
+ counter,
+ ArrayView<const Number>(data.values_dev.get(),
+ partitioner->local_size()),
+ ArrayView<Number>(import_data.values_dev.get(),
+ partitioner->n_import_indices()),
+ ArrayView<Number>(data.values_dev.get() + partitioner->local_size(),
+ partitioner->n_ghost_indices()),
+ update_ghost_values_requests);
+# endif
#else
(void)counter;
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::update_ghost_values_finish() const
+ Vector<Number, MemorySpaceType>::update_ghost_values_finish() const
{
#ifdef DEAL_II_WITH_MPI
// wait for both sends and receives to complete, even though only
// make this function thread safe
std::lock_guard<std::mutex> lock(mutex);
+# if !(defined(DEAL_II_COMPILER_CUDA_AWARE) && \
+ defined(DEAL_II_WITH_CUDA_AWARE_MPI))
partitioner->export_to_ghosted_array_finish(
ArrayView<Number>(data.values.get() + partitioner->local_size(),
partitioner->n_ghost_indices()),
update_ghost_values_requests);
+# else
+ partitioner->export_to_ghosted_array_finish(
+ ArrayView<Number>(data.values_dev.get() + partitioner->local_size(),
+ partitioner->n_ghost_indices()),
+ update_ghost_values_requests);
+# endif
}
-# ifdef DEAL_II_COMPILER_CUDA_AWARE
- // TODO For now, the communication is done on the host, so we need to
+
+# if defined DEAL_II_COMPILER_CUDA_AWARE && \
+ !defined DEAL_II_WITH_CUDA_AWARE_MPI
+ // The communication is done on the host, so we need to
// move the data back to the device.
- if (std::is_same<MemorySpace, ::dealii::MemorySpace::CUDA>::value)
+ if (std::is_same<MemorySpaceType, MemorySpace::CUDA>::value)
{
cudaError_t cuda_error_code =
cudaMemcpy(data.values_dev.get() + partitioner->local_size(),
data.values.reset();
}
# endif
+
#endif
vector_is_ghosted = true;
}
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::import(
+ Vector<Number, MemorySpaceType>::import(
const ReadWriteVector<Number> & V,
VectorOperation::values operation,
std::shared_ptr<const CommunicationPatternBase> communication_pattern)
ExcMessage("The communication pattern is not of type "
"Utilities::MPI::Partitioner."));
}
- Vector<Number> tmp_vector(comm_pattern);
+ Vector<Number, ::dealii::MemorySpace::Host> tmp_vector(comm_pattern);
data.copy_to(tmp_vector.begin(), local_size());
data.copy_from(tmp_vector.begin(), local_size());
}
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::swap(Vector<Number, MemorySpace> &v)
+ Vector<Number, MemorySpaceType>::swap(Vector<Number, MemorySpaceType> &v)
{
#ifdef DEAL_II_WITH_MPI
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace> &
- Vector<Number, MemorySpace>::operator=(const Number s)
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType> &
+ Vector<Number, MemorySpaceType>::operator=(const Number s)
{
const size_type this_size = local_size();
if (this_size > 0)
{
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::set(thread_loop_partitioner,
- this_size,
- s,
- data);
+ functions<Number, Number, MemorySpaceType>::set(
+ thread_loop_partitioner, this_size, s, data);
}
// if we call Vector::operator=0, we want to zero out all the entries
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::reinit(const VectorSpaceVector<Number> &V,
- const bool omit_zeroing_entries)
+ Vector<Number, MemorySpaceType>::reinit(const VectorSpaceVector<Number> &V,
+ const bool omit_zeroing_entries)
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert(dynamic_cast<const VectorType *>(&V) != nullptr,
ExcVectorTypeNotCompatible());
const VectorType &down_V = dynamic_cast<const VectorType &>(V);
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace> &
- Vector<Number, MemorySpace>::operator+=(const VectorSpaceVector<Number> &vv)
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType> &
+ Vector<Number, MemorySpaceType>::
+ operator+=(const VectorSpaceVector<Number> &vv)
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert(dynamic_cast<const VectorType *>(&vv) != nullptr,
ExcVectorTypeNotCompatible());
const VectorType &v = dynamic_cast<const VectorType &>(vv);
AssertDimension(local_size(), v.local_size());
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::add_vector(
+ functions<Number, Number, MemorySpaceType>::add_vector(
thread_loop_partitioner, partitioner->local_size(), v.data, data);
if (vector_is_ghosted)
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace> &
- Vector<Number, MemorySpace>::operator-=(const VectorSpaceVector<Number> &vv)
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType> &
+ Vector<Number, MemorySpaceType>::
+ operator-=(const VectorSpaceVector<Number> &vv)
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert(dynamic_cast<const VectorType *>(&vv) != nullptr,
ExcVectorTypeNotCompatible());
const VectorType &v = dynamic_cast<const VectorType &>(vv);
AssertDimension(local_size(), v.local_size());
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::subtract_vector(
+ functions<Number, Number, MemorySpaceType>::subtract_vector(
thread_loop_partitioner, partitioner->local_size(), v.data, data);
if (vector_is_ghosted)
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::add(const Number a)
+ Vector<Number, MemorySpaceType>::add(const Number a)
{
AssertIsFinite(a);
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::add_factor(
+ functions<Number, Number, MemorySpaceType>::add_factor(
thread_loop_partitioner, partitioner->local_size(), a, data);
if (vector_is_ghosted)
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::add_local(const Number a,
- const VectorSpaceVector<Number> &vv)
+ Vector<Number, MemorySpaceType>::add_local(
+ const Number a,
+ const VectorSpaceVector<Number> &vv)
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert(dynamic_cast<const VectorType *>(&vv) != nullptr,
ExcVectorTypeNotCompatible());
const VectorType &v = dynamic_cast<const VectorType &>(vv);
return;
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::add_av(
+ functions<Number, Number, MemorySpaceType>::add_av(
thread_loop_partitioner, partitioner->local_size(), a, v.data, data);
}
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::add(const Number a,
- const VectorSpaceVector<Number> &vv)
+ Vector<Number, MemorySpaceType>::add(const Number a,
+ const VectorSpaceVector<Number> &vv)
{
add_local(a, vv);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::add(const Number a,
- const VectorSpaceVector<Number> &vv,
- const Number b,
- const VectorSpaceVector<Number> &ww)
+ Vector<Number, MemorySpaceType>::add(const Number a,
+ const VectorSpaceVector<Number> &vv,
+ const Number b,
+ const VectorSpaceVector<Number> &ww)
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert(dynamic_cast<const VectorType *>(&vv) != nullptr,
ExcVectorTypeNotCompatible());
const VectorType &v = dynamic_cast<const VectorType &>(vv);
AssertDimension(local_size(), w.local_size());
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::add_avpbw(
+ functions<Number, Number, MemorySpaceType>::add_avpbw(
thread_loop_partitioner,
partitioner->local_size(),
a,
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::add(const std::vector<size_type> &indices,
- const std::vector<Number> & values)
+ Vector<Number, MemorySpaceType>::add(const std::vector<size_type> &indices,
+ const std::vector<Number> & values)
{
for (std::size_t i = 0; i < indices.size(); ++i)
{
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::sadd(const Number x,
- const Vector<Number, MemorySpace> &v)
+ Vector<Number, MemorySpaceType>::sadd(
+ const Number x,
+ const Vector<Number, MemorySpaceType> &v)
{
AssertIsFinite(x);
AssertDimension(local_size(), v.local_size());
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::sadd_xv(
+ functions<Number, Number, MemorySpaceType>::sadd_xv(
thread_loop_partitioner, partitioner->local_size(), x, v.data, data);
if (vector_is_ghosted)
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::sadd_local(const Number x,
- const Number a,
- const VectorSpaceVector<Number> &vv)
+ Vector<Number, MemorySpaceType>::sadd_local(
+ const Number x,
+ const Number a,
+ const VectorSpaceVector<Number> &vv)
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert((dynamic_cast<const VectorType *>(&vv) != nullptr),
ExcVectorTypeNotCompatible());
const VectorType &v = dynamic_cast<const VectorType &>(vv);
AssertDimension(local_size(), v.local_size());
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::sadd_xav(
+ functions<Number, Number, MemorySpaceType>::sadd_xav(
thread_loop_partitioner,
partitioner->local_size(),
x,
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::sadd(const Number x,
- const Number a,
- const VectorSpaceVector<Number> &vv)
+ Vector<Number, MemorySpaceType>::sadd(const Number x,
+ const Number a,
+ const VectorSpaceVector<Number> &vv)
{
sadd_local(x, a, vv);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::sadd(const Number x,
- const Number a,
- const Vector<Number, MemorySpace> &v,
- const Number b,
- const Vector<Number, MemorySpace> &w)
+ Vector<Number, MemorySpaceType>::sadd(
+ const Number x,
+ const Number a,
+ const Vector<Number, MemorySpaceType> &v,
+ const Number b,
+ const Vector<Number, MemorySpaceType> &w)
{
AssertIsFinite(x);
AssertIsFinite(a);
AssertDimension(local_size(), w.local_size());
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::sadd_xavbw(
+ functions<Number, Number, MemorySpaceType>::sadd_xavbw(
thread_loop_partitioner,
partitioner->local_size(),
x,
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace> &
- Vector<Number, MemorySpace>::operator*=(const Number factor)
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType> &
+ Vector<Number, MemorySpaceType>::operator*=(const Number factor)
{
AssertIsFinite(factor);
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::multiply_factor(
+ functions<Number, Number, MemorySpaceType>::multiply_factor(
thread_loop_partitioner, partitioner->local_size(), factor, data);
if (vector_is_ghosted)
- template <typename Number, typename MemorySpace>
- Vector<Number, MemorySpace> &
- Vector<Number, MemorySpace>::operator/=(const Number factor)
+ template <typename Number, typename MemorySpaceType>
+ Vector<Number, MemorySpaceType> &
+ Vector<Number, MemorySpaceType>::operator/=(const Number factor)
{
operator*=(static_cast<Number>(1.) / factor);
return *this;
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::scale(const VectorSpaceVector<Number> &vv)
+ Vector<Number, MemorySpaceType>::scale(const VectorSpaceVector<Number> &vv)
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert(dynamic_cast<const VectorType *>(&vv) != nullptr,
ExcVectorTypeNotCompatible());
const VectorType &v = dynamic_cast<const VectorType &>(vv);
AssertDimension(local_size(), v.local_size());
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::scale(thread_loop_partitioner,
- local_size(),
- v.data,
- data);
+ functions<Number, Number, MemorySpaceType>::scale(
+ thread_loop_partitioner, local_size(), v.data, data);
if (vector_is_ghosted)
update_ghost_values();
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::equ(const Number a,
- const VectorSpaceVector<Number> &vv)
+ Vector<Number, MemorySpaceType>::equ(const Number a,
+ const VectorSpaceVector<Number> &vv)
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert(dynamic_cast<const VectorType *>(&vv) != nullptr,
ExcVectorTypeNotCompatible());
const VectorType &v = dynamic_cast<const VectorType &>(vv);
AssertDimension(local_size(), v.local_size());
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::equ_au(
+ functions<Number, Number, MemorySpaceType>::equ_au(
thread_loop_partitioner, partitioner->local_size(), a, v.data, data);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::equ(const Number a,
- const Vector<Number, MemorySpace> &v,
- const Number b,
- const Vector<Number, MemorySpace> &w)
+ Vector<Number, MemorySpaceType>::equ(
+ const Number a,
+ const Vector<Number, MemorySpaceType> &v,
+ const Number b,
+ const Vector<Number, MemorySpaceType> &w)
{
AssertIsFinite(a);
AssertIsFinite(b);
AssertDimension(local_size(), w.local_size());
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::equ_aubv(
+ functions<Number, Number, MemorySpaceType>::equ_aubv(
thread_loop_partitioner,
partitioner->local_size(),
a,
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
bool
- Vector<Number, MemorySpace>::all_zero() const
+ Vector<Number, MemorySpaceType>::all_zero() const
{
return (linfty_norm() == 0) ? true : false;
}
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
template <typename Number2>
Number
- Vector<Number, MemorySpace>::inner_product_local(
- const Vector<Number2, MemorySpace> &v) const
+ Vector<Number, MemorySpaceType>::inner_product_local(
+ const Vector<Number2, MemorySpaceType> &v) const
{
if (PointerComparison::equal(this, &v))
return norm_sqr_local();
AssertDimension(partitioner->local_size(), v.partitioner->local_size());
return dealii::internal::VectorOperations::
- functions<Number, Number2, MemorySpace>::dot(thread_loop_partitioner,
- partitioner->local_size(),
- v.data,
- data);
+ functions<Number, Number2, MemorySpaceType>::dot(
+ thread_loop_partitioner, partitioner->local_size(), v.data, data);
}
- template <typename Number, typename MemorySpace>
- Number Vector<Number, MemorySpace>::
+ template <typename Number, typename MemorySpaceType>
+ Number Vector<Number, MemorySpaceType>::
operator*(const VectorSpaceVector<Number> &vv) const
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert((dynamic_cast<const VectorType *>(&vv) != nullptr),
ExcVectorTypeNotCompatible());
const VectorType &v = dynamic_cast<const VectorType &>(vv);
- template <typename Number, typename MemorySpace>
- typename Vector<Number, MemorySpace>::real_type
- Vector<Number, MemorySpace>::norm_sqr_local() const
+ template <typename Number, typename MemorySpaceType>
+ typename Vector<Number, MemorySpaceType>::real_type
+ Vector<Number, MemorySpaceType>::norm_sqr_local() const
{
real_type sum;
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::norm_2(
+ functions<Number, Number, MemorySpaceType>::norm_2(
thread_loop_partitioner, partitioner->local_size(), sum, data);
AssertIsFinite(sum);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
Number
- Vector<Number, MemorySpace>::mean_value_local() const
+ Vector<Number, MemorySpaceType>::mean_value_local() const
{
Assert(size() != 0, ExcEmptyObject());
return Number();
Number sum = ::dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::mean_value(
+ functions<Number, Number, MemorySpaceType>::mean_value(
thread_loop_partitioner, partitioner->local_size(), data);
return sum / real_type(partitioner->local_size());
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
Number
- Vector<Number, MemorySpace>::mean_value() const
+ Vector<Number, MemorySpaceType>::mean_value() const
{
Number local_result = mean_value_local();
if (partitioner->n_mpi_processes() > 1)
- template <typename Number, typename MemorySpace>
- typename Vector<Number, MemorySpace>::real_type
- Vector<Number, MemorySpace>::l1_norm_local() const
+ template <typename Number, typename MemorySpaceType>
+ typename Vector<Number, MemorySpaceType>::real_type
+ Vector<Number, MemorySpaceType>::l1_norm_local() const
{
real_type sum;
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::norm_1(
+ functions<Number, Number, MemorySpaceType>::norm_1(
thread_loop_partitioner, partitioner->local_size(), sum, data);
return sum;
- template <typename Number, typename MemorySpace>
- typename Vector<Number, MemorySpace>::real_type
- Vector<Number, MemorySpace>::l1_norm() const
+ template <typename Number, typename MemorySpaceType>
+ typename Vector<Number, MemorySpaceType>::real_type
+ Vector<Number, MemorySpaceType>::l1_norm() const
{
real_type local_result = l1_norm_local();
if (partitioner->n_mpi_processes() > 1)
- template <typename Number, typename MemorySpace>
- typename Vector<Number, MemorySpace>::real_type
- Vector<Number, MemorySpace>::norm_sqr() const
+ template <typename Number, typename MemorySpaceType>
+ typename Vector<Number, MemorySpaceType>::real_type
+ Vector<Number, MemorySpaceType>::norm_sqr() const
{
real_type local_result = norm_sqr_local();
if (partitioner->n_mpi_processes() > 1)
- template <typename Number, typename MemorySpace>
- typename Vector<Number, MemorySpace>::real_type
- Vector<Number, MemorySpace>::l2_norm() const
+ template <typename Number, typename MemorySpaceType>
+ typename Vector<Number, MemorySpaceType>::real_type
+ Vector<Number, MemorySpaceType>::l2_norm() const
{
return std::sqrt(norm_sqr());
}
- template <typename Number, typename MemorySpace>
- typename Vector<Number, MemorySpace>::real_type
- Vector<Number, MemorySpace>::lp_norm_local(const real_type p) const
+ template <typename Number, typename MemorySpaceType>
+ typename Vector<Number, MemorySpaceType>::real_type
+ Vector<Number, MemorySpaceType>::lp_norm_local(const real_type p) const
{
real_type sum = 0.;
dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::norm_p(
+ functions<Number, Number, MemorySpaceType>::norm_p(
thread_loop_partitioner, partitioner->local_size(), sum, p, data);
return std::pow(sum, 1. / p);
- template <typename Number, typename MemorySpace>
- typename Vector<Number, MemorySpace>::real_type
- Vector<Number, MemorySpace>::lp_norm(const real_type p) const
+ template <typename Number, typename MemorySpaceType>
+ typename Vector<Number, MemorySpaceType>::real_type
+ Vector<Number, MemorySpaceType>::lp_norm(const real_type p) const
{
const real_type local_result = lp_norm_local(p);
if (partitioner->n_mpi_processes() > 1)
- template <typename Number, typename MemorySpace>
- typename Vector<Number, MemorySpace>::real_type
- Vector<Number, MemorySpace>::linfty_norm_local() const
+ template <typename Number, typename MemorySpaceType>
+ typename Vector<Number, MemorySpaceType>::real_type
+ Vector<Number, MemorySpaceType>::linfty_norm_local() const
{
real_type max = 0.;
const size_type local_size = partitioner->local_size();
- internal::la_parallel_vector_templates_functions<Number, MemorySpace>::
- linfty_norm_local(data, local_size, max);
+ internal::la_parallel_vector_templates_functions<
+ Number,
+ MemorySpaceType>::linfty_norm_local(data, local_size, max);
return max;
}
- template <typename Number, typename MemorySpace>
- inline typename Vector<Number, MemorySpace>::real_type
- Vector<Number, MemorySpace>::linfty_norm() const
+ template <typename Number, typename MemorySpaceType>
+ inline typename Vector<Number, MemorySpaceType>::real_type
+ Vector<Number, MemorySpaceType>::linfty_norm() const
{
const real_type local_result = linfty_norm_local();
if (partitioner->n_mpi_processes() > 1)
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
Number
- Vector<Number, MemorySpace>::add_and_dot_local(
- const Number a,
- const Vector<Number, MemorySpace> &v,
- const Vector<Number, MemorySpace> &w)
+ Vector<Number, MemorySpaceType>::add_and_dot_local(
+ const Number a,
+ const Vector<Number, MemorySpaceType> &v,
+ const Vector<Number, MemorySpaceType> &w)
{
const size_type vec_size = partitioner->local_size();
AssertDimension(vec_size, v.local_size());
AssertDimension(vec_size, w.local_size());
Number sum = dealii::internal::VectorOperations::
- functions<Number, Number, MemorySpace>::add_and_dot(
+ functions<Number, Number, MemorySpaceType>::add_and_dot(
thread_loop_partitioner, vec_size, a, v.data, w.data, data);
AssertIsFinite(sum);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
Number
- Vector<Number, MemorySpace>::add_and_dot(
+ Vector<Number, MemorySpaceType>::add_and_dot(
const Number a,
const VectorSpaceVector<Number> &vv,
const VectorSpaceVector<Number> &ww)
{
// Downcast. Throws an exception if invalid.
- using VectorType = Vector<Number, MemorySpace>;
+ using VectorType = Vector<Number, MemorySpaceType>;
Assert((dynamic_cast<const VectorType *>(&vv) != nullptr),
ExcVectorTypeNotCompatible());
const VectorType &v = dynamic_cast<const VectorType &>(vv);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
inline bool
- Vector<Number, MemorySpace>::partitioners_are_compatible(
+ Vector<Number, MemorySpaceType>::partitioners_are_compatible(
const Utilities::MPI::Partitioner &part) const
{
return partitioner->is_compatible(part);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
inline bool
- Vector<Number, MemorySpace>::partitioners_are_globally_compatible(
+ Vector<Number, MemorySpaceType>::partitioners_are_globally_compatible(
const Utilities::MPI::Partitioner &part) const
{
return partitioner->is_globally_compatible(part);
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
std::size_t
- Vector<Number, MemorySpace>::memory_consumption() const
+ Vector<Number, MemorySpaceType>::memory_consumption() const
{
std::size_t memory = sizeof(*this);
memory += sizeof(Number) * static_cast<std::size_t>(allocated_size);
if (partitioner.use_count() > 0)
memory +=
partitioner->memory_consumption() / partitioner.use_count() + 1;
- if (import_data != nullptr)
+ if (import_data.values != nullptr || import_data.values_dev != nullptr)
memory += (static_cast<std::size_t>(partitioner->n_import_indices()) *
sizeof(Number));
return memory;
- template <typename Number, typename MemorySpace>
+ template <typename Number, typename MemorySpaceType>
void
- Vector<Number, MemorySpace>::print(std::ostream & out,
- const unsigned int precision,
- const bool scientific,
- const bool across) const
+ Vector<Number, MemorySpaceType>::print(std::ostream & out,
+ const unsigned int precision,
+ const bool scientific,
+ const bool across) const
{
Assert(partitioner.get() != nullptr, ExcInternalError());
AssertThrow(out, ExcIO());
out.precision(old_precision);
}
- } // namespace distributed
-} // namespace LinearAlgebra
+ } // end of namespace distributed
+} // end of namespace LinearAlgebra
DEAL_II_NAMESPACE_CLOSE