Skip to content

Commit 8fc002b

Browse files
committed
Make overlap masking generic and drop XGC-specific overlap handling
1 parent e14ae4a commit 8fc002b

24 files changed

Lines changed: 781 additions & 695 deletions

‎.gitattributes‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SWIG output regenerated from client.i; collapsed in GitHub diffs
2+
src/pcms/fortranapi/client_wrap.c linguist-generated
3+
src/pcms/fortranapi/pcms.f90 linguist-generated

‎src/pcms/capi/client.cpp‎

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,9 @@ ClientState::HandleVariant RegisterField(
129129
// not the arbitrary adapter name given at creation.
130130
registration.function_space.SetLayoutName(name);
131131
auto field = registration.function_space.template CreateField<T>(
132-
std::move(name),
133-
std::make_unique<XGCFieldData<T>>(
134-
registration.function_space.GetXGCLayout(), ValueBasis{},
135-
registration.data, registration.plane_comm));
132+
std::move(name), std::make_unique<XGCFieldData<T>>(
133+
registration.function_space.GetXGCLayout(), ValueBasis{},
134+
registration.data, registration.plane_comm));
136135
return ClientState::HandleVariant{
137136
app.AddField(std::move(field), participates)};
138137
}
@@ -184,6 +183,18 @@ void pcms_destroy_reverse_classification(PcmsReverseClassificationHandle rc)
184183
delete reinterpret_cast<pcms::ReverseClassificationVertex*>(rc.pointer);
185184
}
186185

186+
void pcms_set_overlap_mask(PcmsClientHandle client_handle, const char* name,
187+
in_overlap_function in_overlap)
188+
{
189+
auto* app =
190+
reinterpret_cast<pcms::ApplicationComm*>(client_handle.appPointer);
191+
PCMS_ALWAYS_ASSERT(app != nullptr);
192+
PCMS_ALWAYS_ASSERT(in_overlap != nullptr);
193+
// Fields registered through the C API use their name as the layout name.
194+
app->SetLayoutOverlapMask(name,
195+
std::make_unique<pcms::OverlapMask>(in_overlap));
196+
}
197+
187198
PcmsFieldHandle pcms_add_field(PcmsClientHandle client_handle, const char* name,
188199
PcmsFieldAdapterHandle adapter_handle,
189200
int participates)
@@ -248,11 +259,10 @@ template <typename T>
248259
void pcms_create_xgc_field_adapter_t(
249260
const char* /* name */, MPI_Comm comm, void* data, int size,
250261
const pcms::ReverseClassificationVertex& reverse_classification,
251-
in_overlap_function in_overlap, pcms::FieldAdapterVariant& field_adapter)
262+
pcms::FieldAdapterVariant& field_adapter)
252263
{
253264
PCMS_ALWAYS_ASSERT((size > 0) ? (data != nullptr) : true);
254-
auto function_space =
255-
pcms::XGCFieldFactory(reverse_classification, in_overlap, size);
265+
auto function_space = pcms::XGCFieldFactory(reverse_classification, size);
256266
pcms::Rank1View<T, pcms::HostMemorySpace> data_view(
257267
reinterpret_cast<T*>(data), size);
258268
field_adapter.emplace<pcms::detail::XGCFieldRegistration<T>>(
@@ -261,7 +271,7 @@ void pcms_create_xgc_field_adapter_t(
261271

262272
PcmsFieldAdapterHandle pcms_create_xgc_field_adapter(
263273
const char* name, MPI_Comm comm, void* data, int size, PcmsType data_type,
264-
const PcmsReverseClassificationHandle rc, in_overlap_function in_overlap)
274+
const PcmsReverseClassificationHandle rc)
265275
{
266276
auto* field_adapter = new pcms::FieldAdapterVariant{};
267277
PCMS_ALWAYS_ASSERT(rc.pointer != nullptr);
@@ -270,24 +280,20 @@ PcmsFieldAdapterHandle pcms_create_xgc_field_adapter(
270280
PCMS_ALWAYS_ASSERT(reverse_classification != nullptr);
271281
switch (data_type) {
272282
case PCMS_DOUBLE:
273-
pcms_create_xgc_field_adapter_t<double>(name, comm, data, size,
274-
*reverse_classification,
275-
in_overlap, *field_adapter);
283+
pcms_create_xgc_field_adapter_t<double>(
284+
name, comm, data, size, *reverse_classification, *field_adapter);
276285
break;
277286
case PCMS_FLOAT:
278-
pcms_create_xgc_field_adapter_t<float>(name, comm, data, size,
279-
*reverse_classification,
280-
in_overlap, *field_adapter);
287+
pcms_create_xgc_field_adapter_t<float>(
288+
name, comm, data, size, *reverse_classification, *field_adapter);
281289
break;
282290
case PCMS_INT:
283-
pcms_create_xgc_field_adapter_t<int>(name, comm, data, size,
284-
*reverse_classification, in_overlap,
285-
*field_adapter);
291+
pcms_create_xgc_field_adapter_t<int>(
292+
name, comm, data, size, *reverse_classification, *field_adapter);
286293
break;
287294
case PCMS_LONG_INT:
288-
pcms_create_xgc_field_adapter_t<pcms::GO>(name, comm, data, size,
289-
*reverse_classification,
290-
in_overlap, *field_adapter);
295+
pcms_create_xgc_field_adapter_t<pcms::GO>(
296+
name, comm, data, size, *reverse_classification, *field_adapter);
291297
break;
292298
default:
293299
PCMS_ALWAYS_ASSERT(false, MPI_COMM_WORLD,

‎src/pcms/capi/client.h‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,18 @@ void pcms_destroy_reverse_classification(PcmsReverseClassificationHandle);
6565
// likely to be needed for production cases
6666
int pcms_reverse_classification_count_verts(PcmsReverseClassificationHandle);
6767

68+
PcmsFieldAdapterHandle pcms_create_xgc_field_adapter(
69+
const char* name, MPI_Comm plane_comm, void* data, int size,
70+
PcmsType data_type, const PcmsReverseClassificationHandle rc);
71+
6872
// takes in overlap function takes a geometric dimension and a geometric id
6973
// C doesn't have a builtin bool type, so we use int for compatability with C++
7074
typedef int8_t (*in_overlap_function)(int, int);
71-
PcmsFieldAdapterHandle pcms_create_xgc_field_adapter(
72-
const char* name, MPI_Comm plane_comm, void* data, int size,
73-
PcmsType data_type, const PcmsReverseClassificationHandle rc,
74-
in_overlap_function in_overlap);
75+
// Restricts the field registered under `name` to the DOF holders whose
76+
// classification satisfies in_overlap (unclassified holders are passed as
77+
// (-1, -1)).
78+
void pcms_set_overlap_mask(PcmsClientHandle client_handle, const char* name,
79+
in_overlap_function in_overlap);
7580

7681
PcmsFieldAdapterHandle pcms_create_dummy_field_adapter();
7782

‎src/pcms/coupler/coupler.hpp‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ pcms::Field<T>& pcms::ApplicationComm::GetField(const std::string& name)
403403

404404
template <typename T>
405405
void pcms::ApplicationComm::RegisterFieldCommunicator(Field<T>& field_obj,
406-
bool participates)
406+
bool participates)
407407
{
408408
const std::string& name = field_obj.GetName();
409409
if (field_obj.GetData().GetDOFAccess() == nullptr) {
@@ -414,7 +414,8 @@ void pcms::ApplicationComm::RegisterFieldCommunicator(Field<T>& field_obj,
414414
FieldLayoutCommunicator& layout_communicator =
415415
GetOrCreateLayoutCommunicator(field_obj.GetLayout(), participates);
416416
FieldCommunicator2Ptr field_communicator =
417-
std::make_unique<FieldCommunicator<T>>(name, layout_communicator, field_obj);
417+
std::make_unique<FieldCommunicator<T>>(name, layout_communicator,
418+
field_obj);
418419
auto [it, inserted] =
419420
field_communicators_.emplace(name, std::move(field_communicator));
420421
if (!inserted) {

‎src/pcms/coupler/field_communicator.hpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class FieldCommunicator
5353
// receive.
5454
auto data = comm_.Recv(redev::Mode::Synchronous);
5555
serializer_.Deserialize(field_, make_const_array_view(data),
56-
layout_comm_.GetPermutationArray());
56+
layout_comm_.GetPermutationArray());
5757
}
5858

5959
private:

‎src/pcms/coupler/field_layout_communicator.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ void FieldLayoutCommunicator::UpdateLayoutNull()
111111
PCMS_FUNCTION_TIMER;
112112
// This rank exchanges nothing, but it still unpacks on receive (backends
113113
// that keep replicas synchronize them there), so every holder is unmapped.
114-
plan_.permutation =
115-
MakeUnmappedPermutation(static_cast<size_t>(layout_.GetNumOwnedDofHolder()));
114+
plan_.permutation = MakeUnmappedPermutation(
115+
static_cast<size_t>(layout_.GetNumOwnedDofHolder()));
116116
if (redev_.GetProcessType() == redev::ProcessType::Client) {
117117
channel_.BeginSendCommunicationPhase();
118118
channel_.EndSendCommunicationPhase();

‎src/pcms/coupler/field_serializer.h‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ template <typename T>
1818
class FieldSerializer
1919
{
2020
public:
21-
int Serialize(const Field<T>& field,
22-
Rank1View<T, HostMemorySpace> buffer,
23-
Rank1View<const LO, HostMemorySpace> permutation) const
21+
int Serialize(const Field<T>& field, Rank1View<T, HostMemorySpace> buffer,
22+
Rank1View<const LO, HostMemorySpace> permutation) const
2423
{
2524
const auto data = field.GetDOFHolderDataHost().GetValues();
2625
if (buffer.size() > 0) {
@@ -37,9 +36,8 @@ class FieldSerializer
3736
return static_cast<int>(buffer.size());
3837
}
3938

40-
void Deserialize(
41-
Field<T>& field, Rank1View<const T, HostMemorySpace> buffer,
42-
Rank1View<const LO, HostMemorySpace> permutation) const
39+
void Deserialize(Field<T>& field, Rank1View<const T, HostMemorySpace> buffer,
40+
Rank1View<const LO, HostMemorySpace> permutation) const
4341
{
4442
const auto& layout = field.GetLayout();
4543
const LO num_dof = layout.GetNumOwnedDofHolder();

‎src/pcms/coupler/overlap_mask.h‎

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,18 @@ struct OverlapMask
1515
Kokkos::View<bool*, HostMemorySpace> is_overlap_;
1616
std::function<int8_t(int, int)> in_overlap_func_;
1717

18-
// Default constructor: all DOFs are in overlap
18+
// Default constructor: all DOF holders are in overlap
1919
OverlapMask(size_t size) : is_overlap_("overlap_info", size)
2020
{
2121
Kokkos::deep_copy(is_overlap_, true);
2222
}
2323

24-
// Construct from a function that determines overlap based on classification
25-
OverlapMask(size_t size, std::function<int8_t(int, int)> in_overlap)
26-
: is_overlap_("overlap_info", size), in_overlap_func_(std::move(in_overlap))
24+
// Construct from a function that determines overlap from a DOF holder's
25+
// classification (dimension, id). Holders without classification are passed
26+
// as (-1, -1).
27+
explicit OverlapMask(std::function<int8_t(int, int)> in_overlap)
28+
: in_overlap_func_(std::move(in_overlap))
2729
{
28-
Kokkos::deep_copy(is_overlap_, true);
2930
}
3031

3132
// Construct from a precomputed per-DOF-holder host mask (e.g. an MFEM
@@ -56,19 +57,22 @@ struct OverlapMask
5657
}
5758
}
5859

59-
// Get the mask, evaluating the function if needed
60-
Rank1View<const bool, HostMemorySpace> GetMask(
60+
// Get the mask, evaluating the function against the layout if one was given
61+
Kokkos::View<const bool*, HostMemorySpace> GetMask(
6162
const FieldLayout& layout) const
6263
{
63-
if (in_overlap_func_) {
64-
auto class_dims = layout.GetDOFHolderClassificationDimensionsHost();
65-
auto class_ids = layout.GetDOFHolderClassificationIdsHost();
66-
for (size_t i = 0; i < is_overlap_.extent(0); ++i) {
67-
is_overlap_[i] =
68-
static_cast<bool>(in_overlap_func_(class_dims[i], class_ids[i]));
69-
}
64+
if (!in_overlap_func_) {
65+
return is_overlap_;
66+
}
67+
auto class_dims = layout.GetDOFHolderClassificationDimensionsHost();
68+
auto class_ids = layout.GetDOFHolderClassificationIdsHost();
69+
Kokkos::View<bool*, HostMemorySpace> is_overlap("overlap_info",
70+
class_dims.size());
71+
for (size_t i = 0; i < is_overlap.extent(0); ++i) {
72+
is_overlap[i] =
73+
static_cast<bool>(in_overlap_func_(class_dims[i], class_ids[i]));
7074
}
71-
return make_const_array_view(is_overlap_);
75+
return is_overlap;
7276
}
7377
};
7478

‎src/pcms/field/data/mfem.hpp‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ class MFEMVertexFieldData
2222
FieldValueType GetValueType() const override;
2323
const ValueBasis& GetValueBasis() const override;
2424

25-
const DOFAccess<Real>* GetDOFAccess() const noexcept override
26-
{
27-
return this;
28-
}
25+
const DOFAccess<Real>* GetDOFAccess() const noexcept override { return this; }
2926
DOFAccess<Real>* GetDOFAccess() noexcept override { return this; }
3027

3128
Rank2View<const Real, DeviceMemorySpace> GetOwnedValues() const override;

‎src/pcms/field/data/point_cloud.h‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ class PointCloud
1919
FieldValueType GetValueType() const override;
2020
const ValueBasis& GetValueBasis() const override;
2121

22-
const DOFAccess<Real>* GetDOFAccess() const noexcept override
23-
{
24-
return this;
25-
}
22+
const DOFAccess<Real>* GetDOFAccess() const noexcept override { return this; }
2623
DOFAccess<Real>* GetDOFAccess() noexcept override { return this; }
2724

2825
Rank2View<const Real, DeviceMemorySpace> GetOwnedValues() const override;

0 commit comments

Comments
 (0)