Skip to content

Commit

Permalink
Create contiguous helper field
Browse files Browse the repository at this point in the history
  • Loading branch information
tcclevenger committed Oct 4, 2024
1 parent 9daab1a commit c265fb5
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
16 changes: 16 additions & 0 deletions components/eamxx/src/share/field/field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ subfield (const std::string& sf_name, const ekat::units::Units& sf_units,
sf.m_data = m_data;
sf.m_is_read_only = m_is_read_only;

if (not sf.m_header->get_alloc_properties().contiguous() and
not sf.host_and_device_share_memory_space()) {
// If subfield is not contiguous and Host and Device do not
// share a memory space, we must initialize the helper field
// for sync_to functions.
sf.initialize_contiguous_helper_field();
}

return sf;
}

Expand Down Expand Up @@ -178,6 +186,14 @@ Field Field::subfield(const std::string& sf_name,
index_end);
sf.m_data = m_data;

if (not sf.m_header->get_alloc_properties().contiguous() and
not sf.host_and_device_share_memory_space()) {
// If subfield is not contiguous and Host and Device do not
// share a memory space, we must initialize the helper field
// for sync_to functions.
sf.initialize_contiguous_helper_field();
}

return sf;
}

Expand Down
25 changes: 25 additions & 0 deletions components/eamxx/src/share/field/field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,27 @@ class Field {
// Allocate the actual view
void allocate_view ();

// Create contiguous helper field for running sync_to_host
// and sync_to_device with non-contiguous fields
void initialize_contiguous_helper_field () {
EKAT_REQUIRE_MSG(not m_header->get_alloc_properties().contiguous(),
"Error! We should not setup contiguous helper field "
"for an already contiguous field.\n");
EKAT_REQUIRE_MSG(not host_and_device_share_memory_space(),
"Error! We should not setup contiguous helper field for a field "
"when host and device share a memory space.\n");

auto id = m_header->get_identifier();
Field contig(id.alias(name()+std::string("_contiguous")));
contig.allocate_view();

// Sanity check
EKAT_REQUIRE_MSG(contig.get_header().get_alloc_properties().contiguous(),
"Error! Contiguous helper field must be contiguous.\n");

m_contiguous_field = std::make_shared<Field>(contig);
}

inline bool host_and_device_share_memory_space() const {
EKAT_REQUIRE_MSG(is_allocated(),
"Error! Must allocate view before querying "
Expand Down Expand Up @@ -347,6 +368,10 @@ class Field {
// Actual data.
dual_view_t<char*> m_data;

// Field needed for sync host/device in case of non-contiguous
// field when host and device do not share a memory space.
std::shared_ptr<Field> m_contiguous_field;

// Whether this field is read-only. This is given
// mutable keyword since it needs to be turned off/on
// to allow sync_to_host for constant, read-only fields.
Expand Down

0 comments on commit c265fb5

Please sign in to comment.