Skip to content

Commit

Permalink
Add components documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
dimitraka committed Jun 30, 2024
1 parent daa1fd5 commit 6fa50b8
Show file tree
Hide file tree
Showing 16 changed files with 312 additions and 22 deletions.
68 changes: 67 additions & 1 deletion docs/sphinx/api/public_distributed_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ Member functions
.. _public_distr_api_header_async:

``hpx/async.hpp``
===================
=================

The header :hpx-header:`libs/full/async_distributed/include,hpx/async.hpp`
includes distributed implementations of :cpp:func:`hpx::async`,
Expand All @@ -204,3 +204,69 @@ Functions
+-------------------------------------------------------+
| :ref:`modules_hpx/async_distributed/dataflow.hpp_api` |
+-------------------------------------------------------+

.. _public_distr_api_header_components:

``hpx/components.hpp``
======================

The header :hpx-header:`libs/full/include/include,hpx/include/components.hpp`
includes the components implementation. A component in `hpx` is a C++ class
which can be created remotely and for which its member functions can be invoked
remotely as well. More information about how components can be defined,
created, and used can be found in :ref:`components`. :ref:`examples_accumulator`
includes examples on the accumulator, template accumulator and template function
accumulator.

Macros
------

.. table:: `hpx` macros of header ``hpx/components.hpp``

+----------------------------------------------+
| Macro |
+==============================================+
| :c:macro:`HPX_DEFINE_COMPONENT_ACTION` |
+----------------------------------------------+
| :c:macro:`HPX_REGISTER_ACTION_DECLARATION` |
+----------------------------------------------+
| :c:macro:`HPX_REGISTER_ACTION` |
+----------------------------------------------+
| :c:macro:`HPX_REGISTER_COMMANDLINE_MODULE` |
+----------------------------------------------+
| :c:macro:`HPX_REGISTER_COMPONENT` |
+----------------------------------------------+
| :c:macro:`HPX_REGISTER_COMPONENT_MODULE` |
+----------------------------------------------+
| :c:macro:`HPX_REGISTER_STARTUP_MODULE` |
+----------------------------------------------+

Classes
-------

.. table:: `hpx` classes of header ``hpx/components.hpp``

+----------------------------------------------------------+
| Class |
+==========================================================+
| :cpp:class:`hpx::components::client` |
+----------------------------------------------------------+
| :cpp:class:`hpx::components::client_base` |
+----------------------------------------------------------+
| :cpp:class:`hpx::components::component` |
+----------------------------------------------------------+
| :cpp:class:`hpx::components::component_base` |
+----------------------------------------------------------+
| :cpp:class:`hpx::components::component_commandline_base` |
+----------------------------------------------------------+

Functions
---------

.. table:: `hpx` functions of header ``hpx/components.hpp``

+----------------------------------------------------------+
| Function |
+==========================================================+
| :cpp:func:`hpx::new_` |
+----------------------------------------------------------+
166 changes: 150 additions & 16 deletions docs/sphinx/examples/accumulator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
Components and actions
======================

The accumulator example demonstrates the use of components. Components are C++
The accumulator examples demonstrate the use of components. Components are C++
classes that expose methods as a type of |hpx| action. These actions are called
component actions.
component actions. There are three examples:
- accumulator
- template accumulator
- template function accumulator

Components are globally named, meaning that a component action can be called
remotely (e.g., from another machine). There are two accumulator examples in
Expand All @@ -31,18 +34,21 @@ Component actions, however, do not target machines. Instead, they target
component instances. The instance may live on the machine that we've invoked the
component action from, or it may live on another machine.

The component in this example exposes three different functions:
The components in these examples expose three different functions:

* ``reset()`` - Resets the accumulator value to 0.
* ``add(arg)`` - Adds ``arg`` to the accumulators value.
* ``query()`` - Queries the value of the accumulator.

This example creates an instance of the accumulator, and then allows the user to
enter commands at a prompt, which subsequently invoke actions on the accumulator
instance.
These examples create an instance of the (template or template function) accumulator,
and then allow the user to enter commands at a prompt, which subsequently invoke actions
on the accumulator instance.

Accumulator
===========

Setup
=====
-----

The source code for this example can be found here:
:download:`accumulator_client.cpp
Expand Down Expand Up @@ -82,7 +88,7 @@ wait for input. An example session is given below:
> quit
Walkthrough
===========
-----------

Now, let's take a look at the source code of the accumulator example. This
example consists of two parts: an |hpx| component library (a library that
Expand All @@ -105,10 +111,10 @@ names of the two classes in accumulator are:
* ``examples::accumulator`` (client class)

The server class
----------------
^^^^^^^^^^^^^^^^

The following code is from: :download:`accumulator.hpp
<../../examples/accumulators/server/accumulator.hpp>`.
The following code is from
:hpx-header:`examples/accumulators,server/accumulator.hpp`.

All |hpx| component server classes must inherit publicly from the |hpx|
component base class: :cpp:class:`hpx::components::component_base`
Expand Down Expand Up @@ -173,23 +179,22 @@ action type registration code:
The code above must be placed in the global namespace.

The rest of the registration code is in
:download:`accumulator.cpp <../../examples/accumulators/accumulator.cpp>`
:hpx-header:`examples/accumulators,accumulator.cpp`

.. literalinclude:: ../../examples/accumulators/accumulator.cpp
:language: c++
:start-after: //[accumulator_registration_definitions
:end-before: //]


.. note::

The code above must be placed in the global namespace.

The client class
----------------
^^^^^^^^^^^^^^^^

The following code is from :download:`accumulator.hpp
<../../examples/accumulators/accumulator.hpp>`.
The following code is from
:hpx-header:`examples/accumulators,accumulator.hpp`

The client class is the primary interface to a component instance. Client classes
are used to create components::
Expand Down Expand Up @@ -259,3 +264,132 @@ accumulator instance.
in |hpx|. This type specifies the target of an action. This is the type that is
returned by :cpp:func:`hpx::find_here` in which case it represents the
:term:`locality` the code is running on.


Template accumulator
====================

Walkthrough
-----------

The server class
^^^^^^^^^^^^^^^^

The following code is from
:hpx-header:`examples/accumulators,server/template_accumulator.hpp`.

Similarly to the accumulator example, the component server class
inherits publicly from :cpp:class:`hpx::components::component_base` and from
:cpp:class:`hpx::components::locking_hook` ensuring thread-safe method invocations.

.. literalinclude:: ../../examples/accumulators/server/template_accumulator.hpp
:language: c++
:start-after: //[template_accumulator_server_inherit
:end-before: //]

The body of the template accumulator class remains mainly the same as the accumulator with
the difference that it uses templates in the data types.

.. literalinclude:: ../../examples/accumulators/server/template_accumulator.hpp
:language: c++
:start-after: //[template_accumulator_server_body_class
:end-before: //]

The last piece of code in the server class header is the declaration of the
action type registration code. `REGISTER_TEMPLATE_ACCUMULATOR_DECLARATION(type)` declares
actions for the specified type, while `REGISTER_TEMPLATE_ACCUMULATOR(type)` registers the
actions and the component for the specified type, using macros to handle boilerplate code.

.. literalinclude:: ../../examples/accumulators/server/template_accumulator.hpp
:language: c++
:start-after: //[template_accumulator_registration_declarations
:end-before: //]

.. note::

The code above must be placed in the global namespace.

Finally, `HPX_REGISTER_COMPONENT_MODULE()` in file
:hpx-header:`examples/accumulators,server/template_accumulator.cpp`
adds the factory registration functionality.

The client class
^^^^^^^^^^^^^^^^

The client class of the template accumulator can be found in
:hpx-header:`examples/accumulators,template_accumulator.hpp` and is very similar to
the client class of the accumulator with the only difference that it uses templates
and hence can work with different types.

Template function accumulator
=============================

Walkthrough
-----------

The server class
^^^^^^^^^^^^^^^^

The following code is from
:hpx-header:`examples/accumulators,server/template_function_accumulator.hpp`.

The component server class inherits publicly from :cpp:class:`hpx::components::component_base`.

.. literalinclude:: ../../examples/accumulators/server/template_function_accumulator.hpp
:language: c++
:start-after: //[template_func_accumulator_server_inherit
:end-before: //]

`typedef hpx::spinlock mutex_type` defines a `mutex_type` as `hpx::spinlock` for thread safety,
while the code that follows exposes the functionality of this component.

.. literalinclude:: ../../examples/accumulators/server/template_function_accumulator.hpp
:language: c++
:start-after: //[template_func_accumulator_server_exposed_func
:end-before: //]


- `reset()`: Resets the accumulator value to `0` in a thread-safe manner using
`std::lock_guard`.
- `add()`: Adds a value to the accumulator, allowing any type `T` that can be cast to double.
- `query()`: Returns the current value of the accumulator in a thread-safe manner.

To define the actions for `reset()` and `query()` we can use the macro `HPX_DEFINE_COMPONENT_ACTION`.
However, actions with template arguments require special type definitions. Therefore, we use
`make_action()` to define `add()`.

.. literalinclude:: ../../examples/accumulators/server/template_function_accumulator.hpp
:language: c++
:start-after: //[template_func_accumulator_server_actions
:end-before: //]

The last piece of code in the server class header is the action registration:

.. literalinclude:: ../../examples/accumulators/server/template_function_accumulator.hpp
:language: c++
:start-after: //[template_func_accumulator_registration_declarations
:end-before: //]

.. note::

The code above must be placed in the global namespace.

The rest of the registration code is in
:hpx-header:`examples/accumulators,accumulator.cpp`

.. literalinclude:: ../../examples/accumulators/template_function_accumulator.cpp
:language: c++
:start-after: //[template_func_accumulator_registration_definitions
:end-before: //]

.. note::

The code above must be placed in the global namespace.

The client class
^^^^^^^^^^^^^^^^

The client class of the template accumulator can be found in
:hpx-header:`examples/accumulators,template_function_accumulator.hpp` and is very similar
to the client class of the accumulator with the only difference that it uses templates
and hence can work with different types.
7 changes: 7 additions & 0 deletions examples/accumulators/server/template_accumulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,15 @@ namespace examples { namespace server {
/// a simple component is created.
///
/// This component exposes 3 different actions: reset, add and query.
//[template_accumulator_server_inherit
template <typename T>
class template_accumulator
: public hpx::components::locking_hook<
hpx::components::component_base<template_accumulator<T>>>
//]
{
public:
//[template_accumulator_server_body_class
typedef T argument_type;

template_accumulator()
Expand Down Expand Up @@ -85,12 +88,15 @@ namespace examples { namespace server {
HPX_DEFINE_COMPONENT_ACTION(template_accumulator, reset)
HPX_DEFINE_COMPONENT_ACTION(template_accumulator, add)
HPX_DEFINE_COMPONENT_ACTION(template_accumulator, query)
//]

private:
argument_type value_;
};
}} // namespace examples::server

//[template_accumulator_registration_declarations

#define REGISTER_TEMPLATE_ACCUMULATOR_DECLARATION(type) \
HPX_REGISTER_ACTION_DECLARATION( \
examples::server::template_accumulator<type>::reset_action, \
Expand Down Expand Up @@ -123,5 +129,6 @@ namespace examples { namespace server {
HPX_PP_CAT(__template_accumulator_, type); \
HPX_REGISTER_COMPONENT(HPX_PP_CAT(__template_accumulator_, type)) \
/**/
//]

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ namespace examples { namespace server {
/// component usually does not require AGAS requests.
///
/// This component exposes 3 different actions: reset, add and query.
//[template_func_accumulator_server_inherit
class template_function_accumulator
: public hpx::components::component_base<template_function_accumulator>
//]
{
private:
typedef hpx::spinlock mutex_type;
Expand All @@ -48,6 +50,7 @@ namespace examples { namespace server {
{
}

//[template_func_accumulator_server_exposed_func
///////////////////////////////////////////////////////////////////////
// Exposed functionality of this component.

Expand Down Expand Up @@ -75,7 +78,9 @@ namespace examples { namespace server {
std::lock_guard<mutex_type> l(mtx_);
return value_;
}
//]

//[template_func_accumulator_server_actions
///////////////////////////////////////////////////////////////////////
// Each of the exposed functions needs to be encapsulated into an
// action type, generating all required boilerplate code for threads,
Expand All @@ -95,19 +100,22 @@ namespace examples { namespace server {
add_action<T>>::type
{
};
//]

private:
mutable mutex_type mtx_;
double value_;
};
}} // namespace examples::server

//[template_func_accumulator_registration_declarations
HPX_REGISTER_ACTION_DECLARATION(
examples::server::template_function_accumulator::reset_action,
managed_accumulator_reset_action)

HPX_REGISTER_ACTION_DECLARATION(
examples::server::template_function_accumulator::query_action,
managed_accumulator_query_action)
//]

#endif
Loading

0 comments on commit 6fa50b8

Please sign in to comment.