Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 26 additions & 29 deletions src/pcms/capi/client.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "client.h"
#include "pcms.h"
#include "pcms/field/field_factory.h"
#include "pcms/field/function_space/xgc.h"
#include "pcms/field/data/xgc.h"
#include "pcms/field/layout/xgc.h"
Expand All @@ -23,11 +24,11 @@ namespace detail
template <typename T>
struct XGCFieldRegistration
{
XGCFunctionSpace function_space;
XGCFieldFactory function_space;
MPI_Comm plane_comm;
Rank1View<T, HostMemorySpace> data;

XGCFieldRegistration(XGCFunctionSpace fs, MPI_Comm comm,
XGCFieldRegistration(XGCFieldFactory fs, MPI_Comm comm,
Rank1View<T, HostMemorySpace> d)
: function_space(std::move(fs)), plane_comm(comm), data(d)
{
Expand All @@ -37,22 +38,22 @@ struct XGCFieldRegistration
struct DummyFieldRegistration
{};

class EmptyFunctionSpace : public FunctionSpace
class EmptyFieldFactory : public FieldFactory
{
public:
EmptyFunctionSpace() : layout_(std::make_shared<EmptyFieldLayout>()) {}
explicit EmptyFieldFactory(std::string layout_name = "")
{
auto layout = std::make_shared<EmptyFieldLayout>();
layout->SetName(std::move(layout_name));
layout_ = layout;
}

[[nodiscard]] std::shared_ptr<const FieldLayout> GetLayout()
const noexcept override
{
return layout_;
}

[[nodiscard]] CoordinateSystem GetCoordinateSystem() const noexcept override
{
return CoordinateSystem::Cartesian;
}

protected:
[[nodiscard]] FieldVariant CreateFieldImpl(
Type value_type, FieldMetadata metadata) const override
Expand All @@ -75,25 +76,19 @@ class EmptyFunctionSpace : public FunctionSpace
PCMS_ALWAYS_ASSERT(fd != nullptr);
if (dynamic_cast<const SimpleFieldData<T>*>(fd.get()) == nullptr) {
throw pcms_error(
"EmptyFunctionSpace::CreateField: requires SimpleFieldData");
"EmptyFieldFactory::CreateField: requires SimpleFieldData");
}
if (fd->GetDOFHolderDataHost().size() !=
detail::ExpectedFlatFieldDataSize(*layout_)) {
throw pcms_error(
"EmptyFunctionSpace::CreateField: field data size does not match "
"EmptyFieldFactory::CreateField: field data size does not match "
"layout");
}
return WrapField<T>(layout_, std::forward<decltype(fd)>(fd));
},
std::move(data));
}

[[nodiscard]] PointEvaluatorVariant CreatePointEvaluatorImpl(
Type /*value_type*/, const EvaluationRequest& /*request*/) const override
{
throw pcms_error("EmptyFunctionSpace does not support point evaluation");
}

private:
std::shared_ptr<const EmptyFieldLayout> layout_;
};
Expand Down Expand Up @@ -130,29 +125,31 @@ ClientState::HandleVariant RegisterField(
Application& app, std::string name,
const detail::XGCFieldRegistration<T>& registration, bool participates)
{
// The layout's coupling identity is the field name
// not the arbitrary adapter name given at creation.
registration.function_space.SetLayoutName(name);
auto field = registration.function_space.template CreateField<T>(
std::make_unique<XGCFieldData<T>>(
registration.function_space.GetXGCLayout(), FieldMetadata{},
registration.data));
app.AddLayout(name, registration.function_space.GetLayout(), participates);
std::move(name), std::make_unique<XGCFieldData<T>>(
registration.function_space.GetXGCLayout(),
FieldMetadata{}, registration.data));
std::unique_ptr<FieldSerializer<T>> serializer =
std::make_unique<XGCFieldSerializer<T>>(registration.plane_comm,
participates);
return ClientState::HandleVariant{app.AddField(
std::move(name), std::move(field), std::move(serializer), participates)};
return ClientState::HandleVariant{
app.AddField(std::move(field), std::move(serializer), participates)};
}

inline ClientState::HandleVariant RegisterField(
Application& app, std::string name, const detail::DummyFieldRegistration&,
bool participates)
{
auto function_space = detail::EmptyFunctionSpace{};
app.AddLayout(name, function_space.GetLayout(), participates);
auto field = function_space.CreateField<int>(FieldMetadata{});
auto function_space = detail::EmptyFieldFactory{name};
auto field =
function_space.CreateField<int>(std::move(name), FieldMetadata{});
std::unique_ptr<FieldSerializer<int>> serializer =
std::make_unique<FieldSerializer<int>>();
return ClientState::HandleVariant{app.AddField(
std::move(name), std::move(field), std::move(serializer), participates)};
return ClientState::HandleVariant{
app.AddField(std::move(field), std::move(serializer), participates)};
}

} // namespace pcms
Expand Down Expand Up @@ -251,7 +248,7 @@ void pcms_create_xgc_field_adapter_t(
{
PCMS_ALWAYS_ASSERT((size > 0) ? (data != nullptr) : true);
auto function_space =
pcms::XGCFunctionSpace(reverse_classification, in_overlap, size);
pcms::XGCFieldFactory(reverse_classification, in_overlap, size);
pcms::Rank1View<T, pcms::HostMemorySpace> data_view(
reinterpret_cast<T*>(data), size);
field_adapter.emplace<pcms::detail::XGCFieldRegistration<T>>(
Expand Down
45 changes: 17 additions & 28 deletions src/pcms/coupler/coupler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,23 @@
namespace pcms
{

FieldLayoutCommunicator& Application::GetLayoutCommunicator(
const FieldLayout& layout)
FieldLayoutCommunicator& Application::GetOrCreateLayoutCommunicator(
const FieldLayout& layout, bool participates)
{
PCMS_FUNCTION_TIMER;
auto it = field_layout_communicators_.find(&layout);
const std::string& name = layout.GetName();
if (name.empty()) {
throw pcms_error(
"Application: the field's layout has no name; name it at construction "
"(From*(..., layout_name)) before registering it with a coupler");
}

// Fields whose layouts share a name share one GID-exchange communicator.
auto it = field_layout_communicators_.find(name);
if (it != field_layout_communicators_.end()) {
return *it->second;
} else {
throw pcms_error("Field added with unregistered layout. Call AddLayout() "
"before AddField().");
}
}

const FieldLayout& Application::AddLayout(
std::string name, std::shared_ptr<const FieldLayout> layout,
bool participates)
{
return AddLayout(std::move(name), std::move(layout),
std::make_unique<GenericFieldExchangePlanner>(),
participates);
}

const FieldLayout& Application::AddLayout(
std::string name, std::shared_ptr<const FieldLayout> layout,
std::unique_ptr<FieldExchangePlanner> planner, bool participates)
{
MPI_Comm mpi_comm_subset = MPI_COMM_NULL;
bool own_mpi_comm = false;
PCMS_ALWAYS_ASSERT((mpi_comm_ == MPI_COMM_NULL) ? (!participates) : true);
Expand All @@ -39,21 +30,19 @@ const FieldLayout& Application::AddLayout(
&mpi_comm_subset);
own_mpi_comm = true;
}
layouts_.push_back(std::move(layout));
const FieldLayout& layout_ref = *layouts_.back();

// Check if there's an overlap mask for this layout
const OverlapMask* overlap_mask = nullptr;
auto mask_it = layout_overlap_masks_.find(name);
if (mask_it != layout_overlap_masks_.end()) {
overlap_mask = mask_it->second.get();
}

field_layout_communicators_.emplace(
&layout_ref, std::make_unique<FieldLayoutCommunicator>(
name, mpi_comm_subset, redev_, channel_, layout_ref,
std::move(planner), own_mpi_comm, overlap_mask));
return layout_ref;
auto [it2, inserted] = field_layout_communicators_.emplace(
name, std::make_unique<FieldLayoutCommunicator>(
name, mpi_comm_subset, redev_, channel_, layout,
std::make_unique<GenericFieldExchangePlanner>(), own_mpi_comm,
overlap_mask));
return *it2->second;
}

void Application::SetLayoutOverlapMask(
Expand Down
Loading