Skip to content

Commit

Permalink
Merge pull request #6509 from dimitraka/fix_docs
Browse files Browse the repository at this point in the history
Add components documentation
  • Loading branch information
hkaiser authored Jul 13, 2024
2 parents 7e3e582 + e84404a commit 7d3824d
Show file tree
Hide file tree
Showing 18 changed files with 320 additions and 29 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_` |
+----------------------------------------------------------+
171 changes: 153 additions & 18 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 @@ -242,8 +247,9 @@ There are a few different ways of invoking actions:
:end-before: //]

* **Synchronous**: To invoke an action in a fully synchronous manner, we can
simply call :cpp:func:`hpx::async`\ ``().get()`` (i.e., create a future and
immediately wait on it to be ready). Here's an example from the accumulator
simply call :cpp:func:`hpx::sync` which is semantically equivalent to
:cpp:func:`hpx::async`\ ``().get()`` (i.e., create a future and immediately
wait on it to be ready). Here's an example from the accumulator
client class:

.. literalinclude:: ../../examples/accumulators/accumulator.hpp
Expand All @@ -259,3 +265,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.
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ The ``system`` configuration section
* This is initialized to the base directory the current executable has been
loaded from.

The `|hpx| configuration section
.................................
The |hpx| configuration section
...............................

.. code-block:: ini
Expand Down
6 changes: 3 additions & 3 deletions examples/accumulators/accumulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace examples {
HPX_ASSERT(this->get_id());

typedef server::accumulator::reset_action action_type;
hpx::post<action_type>(this->get_id());
hpx::post(action_type(), this->get_id());
}
//]

Expand All @@ -84,7 +84,7 @@ namespace examples {
HPX_ASSERT(this->get_id());

typedef server::accumulator::add_action action_type;
hpx::post<action_type>(this->get_id(), arg);
hpx::post(action_type(), this->get_id(), arg);
}

/// Add \p arg to the accumulator's value.
Expand Down Expand Up @@ -114,7 +114,7 @@ namespace examples {
HPX_ASSERT(this->get_id());

typedef server::accumulator::query_action action_type;
return hpx::async<action_type>(hpx::launch::async, this->get_id());
return hpx::async(action_type(), this->get_id());
}
//]

Expand Down
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
Loading

0 comments on commit 7d3824d

Please sign in to comment.