Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pack/Unpack data for user-data #1224

Open
wants to merge 78 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
96ff4b5
Started data_handler
Davknapp Aug 15, 2024
a5f70f3
progress data_handler
Davknapp Aug 15, 2024
cea2b11
Use a base-class
Davknapp Aug 19, 2024
993c979
restructuring
Davknapp Aug 19, 2024
a03b01e
Working version for enlarged int
Davknapp Aug 19, 2024
6ee7851
Fix communication error
Davknapp Aug 20, 2024
df3abdf
Add documentation
Davknapp Aug 20, 2024
c985b9e
Move single-pack implementation into seperate files.
Davknapp Aug 20, 2024
eff194f
Merge branch 'main' into user_data-interface
Davknapp Aug 20, 2024
3d63d86
Split tests into packing-tests and a send_recv-test
Davknapp Aug 20, 2024
05e4984
code simplification
Davknapp Aug 20, 2024
d28dc55
Documentation
Davknapp Aug 20, 2024
5376ef7
documentation
Davknapp Aug 20, 2024
0c233a2
fix memory leak
Davknapp Aug 20, 2024
770c60a
Merge branch 'main' into user_data-interface
Davknapp Aug 21, 2024
8c76526
Merge branch 'main' into user_data-interface
Davknapp Aug 23, 2024
d37eca1
Fix non-mpi configuration
Davknapp Aug 23, 2024
16edf34
Merge branch 'main' into user_data-interface
Davknapp Aug 23, 2024
060e173
Add allgather
Davknapp Aug 23, 2024
00e19b4
improve interface by better naming-scheme
Davknapp Aug 23, 2024
ed9eb01
Merge remote-tracking branch 'origin/user_data-interface' into user_d…
Davknapp Aug 23, 2024
e640c3e
remove Enable-Mpi-Makros around allgather
Davknapp Aug 23, 2024
e4d2413
add mpi_guards, because sc_MPI_PACKED is not an implemented Datatype
Davknapp Aug 23, 2024
8d667c9
Merge branch 'main' into user_data-interface
Davknapp Aug 23, 2024
1a9ecca
Implementation of a different approach to data handling
Davknapp Aug 29, 2024
92b6de6
move comments, bugfix
Davknapp Aug 29, 2024
f66ca3d
simplify code
Davknapp Aug 29, 2024
a3b1b71
Start implementing tree dependant data
Davknapp Sep 3, 2024
f225fc4
Merge remote-tracking branch 'origin/main' into data_handler_diff_app…
Davknapp Sep 5, 2024
43a4cb0
fix tree-data-handling
Davknapp Sep 6, 2024
369c691
Merge pull request #1244 from DLR-AMR/data_handler_diff_approach
Davknapp Sep 6, 2024
f21bba4
Add pseudo-trees
Davknapp Sep 6, 2024
d37ba59
Merge branch 'main' into user_data-interface
Davknapp Sep 6, 2024
00bfae6
Encapsulate test
Davknapp Sep 6, 2024
fb549c8
Clean-up
Davknapp Sep 6, 2024
d3ca0bb
Merge remote-tracking branch 'origin/user_data-interface' into user_d…
Davknapp Sep 6, 2024
7bf372e
Clean-up
Davknapp Sep 6, 2024
bbd680c
use recv_from only if MPI is enabled
Davknapp Sep 6, 2024
7100f81
remove for-loop
Davknapp Sep 6, 2024
f2a524f
Merge branch 'main' into user_data-interface
Davknapp Sep 9, 2024
c45ac31
start working on memory-leak that occurs when running in parallel
Davknapp Sep 9, 2024
d425aac
Merge remote-tracking branch 'origin/main' into user_data-interface
Davknapp Sep 9, 2024
d04ef8e
Merge branch 'user_data-interface' of github.com:DLR-AMR/t8code into …
Davknapp Sep 9, 2024
9ab1fe4
Use void* instead of std::vector<char> for buffer
Davknapp Sep 11, 2024
1cae747
dirty commit
Davknapp Sep 23, 2024
77a6c47
Merge branch 'main' into user_data-interface
Davknapp Sep 26, 2024
21b0820
Merge
Davknapp Sep 26, 2024
af26edf
Fix memory leak in serial
Davknapp Sep 26, 2024
b5fcd22
fix memory leak
Davknapp Sep 27, 2024
cfbf37c
add documentation
Davknapp Sep 27, 2024
49cf6ab
started to implement different behaviour depending on type
Davknapp Sep 27, 2024
b0bc6ec
Provide implementation for unique_ptr
Davknapp Sep 27, 2024
de2b97f
improve for pointer-type
Davknapp Sep 27, 2024
5bc3983
minor improvements
Davknapp Sep 27, 2024
def4cbb
minor optimization
Davknapp Sep 30, 2024
0f60271
avoid copying the vector
Davknapp Sep 30, 2024
67b413d
Simplify data_handler
Davknapp Sep 30, 2024
85d69e5
Optimize pseudo-trees
Davknapp Sep 30, 2024
bc48d36
Merge pull request #1256 from DLR-AMR/Pack-opimization
Davknapp Sep 30, 2024
8d05446
Merge branch 'main' into user_data-interface
Davknapp Sep 30, 2024
1a66765
use shared_ptr
Davknapp Sep 30, 2024
9885468
minor improvements
Davknapp Sep 30, 2024
ffc6a49
documentation
Davknapp Sep 30, 2024
291c0f5
More stl
Davknapp Oct 1, 2024
c36773c
Documentation
Davknapp Oct 1, 2024
4d03763
T -> TType
Davknapp Oct 1, 2024
ad6270c
More documentation
Davknapp Oct 1, 2024
691ae7d
update and document getter function
Davknapp Oct 1, 2024
14e66da
do no double-wrap
Davknapp Oct 1, 2024
8287200
File documentation
Davknapp Oct 1, 2024
56c6046
clean-up
Davknapp Oct 1, 2024
18330e6
Documentation
Davknapp Oct 1, 2024
8132698
proper implementation of enlarged_data
Davknapp Oct 1, 2024
f6dc3fb
fix pedantic errors
Davknapp Oct 1, 2024
b347bd7
Merge branch 'main' into user_data-interface
Davknapp Oct 7, 2024
9090f1a
Merge remote-tracking branch 'origin/main' into user_data-interface
Davknapp Oct 11, 2024
5fc9572
clear memory befor replacing it
Davknapp Oct 11, 2024
e6d1e38
Merge branch 'main' into user_data-interface
Davknapp Oct 16, 2024
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
2 changes: 1 addition & 1 deletion config/t8_vtk.m4
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ T8_ARG_WITH([vtk],
[vtk library (optionally use --with-vtk=<VTK_LIBS>)],
[VTK])


if test "x$T8_WITH_VTK" != xno ; then
if test "x$T8_WITH_VTK_VERSION_MANUALLY_PROVIDED" != xno ; then
t8_vtk_version=$T8_WITH_VTK_VERSION_MANUALLY_PROVIDED
Expand Down
3 changes: 2 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ libt8_installed_headers_cmesh = \
src/t8_cmesh/t8_cmesh_types.h \
src/t8_cmesh/t8_cmesh_stash.h
libt8_installed_headers_data = \
src/t8_data/t8_shmem.h src/t8_data/t8_containers.h
src/t8_data/t8_shmem.h src/t8_data/t8_containers.h \
src/t8_data/t8_data_handler.hxx
libt8_installed_headers_forest = \
src/t8_forest/t8_forest.h \
src/t8_forest/t8_forest_general.h \
Expand Down
249 changes: 249 additions & 0 deletions src/t8_data/t8_data_handler.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
/*
This file is part of t8code.
t8code is a C library to manage a collection (a forest) of multiple
connected adaptive space-trees of general element classes in parallel.

Copyright (C) 2024 the developers

t8code is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

t8code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with t8code; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

sandro-elsweijer marked this conversation as resolved.
Show resolved Hide resolved
#ifndef T8_DATA_HANDLER_HXX
#define T8_DATA_HANDLER_HXX

#include <t8.h>
#include <vector>
#include <t8_data/t8_data_handler_base.hxx>
#include <algorithm>
#include <memory>
#include <type_traits>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you maybe want to sort them?


class t8_abstract_data_handler {
public:
/**
* Pure virtual function to determine the buffer size.
*
* This function must be implemented by derived classes to calculate
* the size of the buffer required for communication.
*
* \param[in] comm The MPI communicator.
* \return The size of the buffer.
*/
virtual int
buffer_size (sc_MPI_Comm comm)
= 0;

/**
* Packs a vector into a buffer. The vector data will be prefixed with the number of elements in the vector.
*
* This pure virtual function is responsible for packing a vector prefix into the provided buffer.
*
* \param[in, out] buffer A pointer to the buffer where the vector prefix will be packed.
* \param[in] num_bytes The number of bytes to be packed.
* \param[in] pos A reference to an integer representing the current position in the buffer. This will be updated as bytes are packed.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would I need this for?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used to fill the buffer for MPI communication for data structures that are non-trivial and do not lay linear in memory.

* \param[in] comm The MPI communicator used for the operation.
*/
virtual void
pack_vector_prefix (void *buffer, const int num_bytes, int &pos, sc_MPI_Comm comm)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no other way than using a void pointer? Couldn't this be templatized?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because the buffer used by MPI is a void* buffer. We want to pass this buffer to the MPI-function and it expects a void *

= 0;

/**
* Unpacks a vector from a buffer. Expected to be prefixed with the number of elements in the vector.
*
* This pure virtual function is responsible for unpacking a vector prefix from the provided buffer.
*
* \param[in] buffer Pointer to the buffer containing the packed data.
* \param[in] num_bytes The number of bytes in the buffer.
* \param[in] pos Reference to an integer representing the current position in the buffer. This will be updated as data is unpacked.
* \param[in] outcount Reference to an integer where the count of unpacked elements will be stored.
* \param[in] comm The MPI communicator used for the operation.
*/
virtual void
unpack_vector_prefix (const void *buffer, const int num_bytes, int &pos, int &outcount, sc_MPI_Comm comm)
= 0;

/**
* Pure virtual function to send data to a specified destination.
*
* This function is responsible for packing and sending data to a given destination
* with a specific tag using the provided MPI communicator.
*
* \param[in] dest The destination rank to which the data will be sent.
* \param[in] tag The tag associated with the message to be sent.
* \param[in] comm The MPI communicator used for the communication.
* \return An integer indicating the status of the send operation.
*/
virtual int
send (const int dest, const int tag, sc_MPI_Comm comm)
= 0;

/**
* Receives a message from a specified source.
*
* This pure virtual function is responsible for receiving and unpacking a message from a given source
* with a specific tag within the provided MPI communicator. The function will also
* update the status and output count of the received message.
*
* \param[in] source The rank of the source process from which the message is received.
* \param[in] tag The tag of the message to be received.
* \param[in] comm The MPI communicator within which the message is received.
* \param[in] status A pointer to an MPI status object that will be updated with the status of the received message.
* \param[in] outcount A reference to an integer that will be updated with the count of received elements.
* \return An integer indicating the success or failure of the receive operation.
*/
virtual int
recv (const int source, const int tag, sc_MPI_Comm comm, sc_MPI_Status *status, int &outcount)
= 0;

/**
* Pure virtual function to get the type.
*
* This function must be overridden in derived classes to return the type.
*
* \return An integer representing the type.
*/
virtual int
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which integer is for which type? Is there an enum for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is currently more a place-holder than a proper implementation. An enum over all of our types that can be used by this class would be nice.

type ()
= 0;

virtual ~t8_abstract_data_handler () {};
};

/**
* \class t8_data_handler
* \brief A template class for handling data in a distributed environment.
*
* This class inherits from t8_abstract_data_handler and provides methods for
* packing, unpacking, sending, and receiving data using MPI.
*
* \tparam T The type of data to be handled.
*/
template <typename T>
Davknapp marked this conversation as resolved.
Show resolved Hide resolved
class t8_data_handler: public t8_abstract_data_handler {
public:
t8_data_handler (): single_handler ()
Davknapp marked this conversation as resolved.
Show resolved Hide resolved
{
m_data = nullptr;
}

t8_data_handler (const std::vector<T> &data): m_data (std::make_shared<std::vector<T>> (data)), single_handler ()
Davknapp marked this conversation as resolved.
Show resolved Hide resolved
{
}

void
Davknapp marked this conversation as resolved.
Show resolved Hide resolved
get_data (std::vector<T> &data) const
Davknapp marked this conversation as resolved.
Show resolved Hide resolved
{
if (m_data) {
data = *m_data;
}
}

int
buffer_size (sc_MPI_Comm comm) override
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstring

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is documented in its parent-class

{
int total_size = 0;
const int mpiret = sc_MPI_Pack_size (1, sc_MPI_INT, comm, &total_size);
SC_CHECK_MPI (mpiret);
if (m_data) {
for (const auto &item : *m_data) {
total_size += single_handler.size (item, comm);
}
}
return total_size;
}

void
pack_vector_prefix (void *buffer, const int num_bytes, int &pos, sc_MPI_Comm comm) override
Davknapp marked this conversation as resolved.
Show resolved Hide resolved
{
const int num_data = m_data->size ();
const int mpiret = sc_MPI_Pack (&num_data, 1, sc_MPI_INT, buffer, num_bytes, &pos, comm);
SC_CHECK_MPI (mpiret);

for (const auto &item : *m_data) {
single_handler.pack (item, pos, buffer, num_bytes, comm);
}
}

void
unpack_vector_prefix (const void *buffer, const int num_bytes, int &pos, int &outcount, sc_MPI_Comm comm) override
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstring

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function has documentation in its parent class

{
const int mpiret = sc_MPI_Unpack (buffer, num_bytes, &pos, &outcount, 1, sc_MPI_INT, comm);
SC_CHECK_MPI (mpiret);
T8_ASSERT (outcount >= 0);

if (!m_data) {
m_data = std::make_shared<std::vector<T>> (outcount);
}
else {
m_data->resize (outcount);
}
for (auto &item : *m_data) {
single_handler.unpack (buffer, num_bytes, pos, item, comm);
}
}

int
send (const int dest, const int tag, sc_MPI_Comm comm) override
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstring

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function has documentation in its parent class

{
#if T8_ENABLE_MPI
int pos = 0;
const int num_bytes = buffer_size (comm);
std::vector<char> buffer (num_bytes);
pack_vector_prefix (buffer.data (), num_bytes, pos, comm);

const int mpiret = sc_MPI_Send (buffer.data (), num_bytes, sc_MPI_PACKED, dest, tag, comm);
SC_CHECK_MPI (mpiret);
return mpiret;
#else
t8_infof ("send only available when configured with --enable-mpi\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't the sc wrapper handle this case? The same code should compile with and without MPI

return sc_MPI_ERR_OTHER;
#endif
}

int
recv (const int source, const int tag, sc_MPI_Comm comm, sc_MPI_Status *status, int &outcount) override
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstring

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is documented in its parent-class

{
#if T8_ENABLE_MPI
int pos = 0;
int mpiret = sc_MPI_Probe (source, tag, comm, status);
SC_CHECK_MPI (mpiret);

int num_bytes;
mpiret = sc_MPI_Get_count (status, sc_MPI_PACKED, &num_bytes);
SC_CHECK_MPI (mpiret);
std::vector<char> buffer (num_bytes);

mpiret = sc_MPI_Recv (buffer.data (), num_bytes, sc_MPI_PACKED, source, tag, comm, status);
SC_CHECK_MPI (mpiret);
unpack_vector_prefix (buffer.data (), num_bytes, pos, outcount, comm);
return mpiret;
#else
t8_infof ("recv only available when configured with --enable-mpi\n");
return sc_MPI_ERR_OTHER;
#endif
}

int
type () override
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstring

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is documented in its parent-class

{
return single_handler.type ();
}

private:
std::shared_ptr<std::vector<T>> m_data;
t8_single_data_handler<T> single_handler;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add docstrings for the members as well

};

#endif /* T8_DATA_HANDLER_HXX */
77 changes: 77 additions & 0 deletions src/t8_data/t8_data_handler_base.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this file called _base when the base class is in the other file?

This file is part of t8code.
t8code is a C library to manage a collection (a forest) of multiple
connected adaptive space-trees of general element classes in parallel.

Copyright (C) 2024 the developers

t8code is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

t8code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with t8code; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File description is missing

#ifndef T8_DATA_HANDLER_BASE
#define T8_DATA_HANDLER_BASE

#include <t8.h>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class docstring is missing

template <typename T>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as with the other T

class t8_single_data_handler {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it called t8_single_data_handler? Will there be other implementations?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it used to pack/unpack/handle a single data-item

public:
t8_single_data_handler () {};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring is missing


int
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstring is missing

size (const T &data, sc_MPI_Comm comm);

/**
* Packs the given data into a buffer for communication.
*
* \tparam T The type of the data to be packed.
* \param[in] data The data to be packed.
* \param[in] pos The current position in the buffer where the data should be packed.
* \param[in, out] buffer The buffer where the data will be packed.
* \param[in] num_bytes The number of bytes available in the buffer.
* \param[in] comm The MPI communicator used for communication.
*/
void
pack (const T &data, int &pos, void *buffer, const int num_bytes, sc_MPI_Comm comm);

/**
* Unpacks data from a buffer.
*
* This function unpacks data from a given buffer into the provided data structure.
*
* \tparam T The type of the data to be unpacked.
* \param[in] buffer A pointer to the buffer containing the packed data.
* \param[in] num_bytes The number of bytes in the buffer.
* \param[in] pos A reference to an integer representing the current position in the buffer.
* \param[in, out] data A pointer to the data structure where the unpacked data will be stored.
* \param[in] comm The MPI communicator used for communication.
*/
void
unpack (const void *buffer, const int num_bytes, int &pos, T &data, sc_MPI_Comm comm);

/**
* Returns the type of the data handler.
*
* This function returns the type of the data handler.
*
* \return An integer representing the type.
*/
int
type ();

~t8_single_data_handler () {};
};

#endif /* T8_DATA_HANDLER_BASE */
Loading