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

Adding hpx::components::component and hpx::components::component_base #1825

Merged
merged 1 commit into from
Oct 29, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ set(documentation_dependencies
"${PROJECT_SOURCE_DIR}/examples/quickstart/hello_world.cpp"
"${PROJECT_SOURCE_DIR}/examples/quickstart/simplest_hello_world.cpp"
"${PROJECT_SOURCE_DIR}/examples/quickstart/error_handling.cpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/accumulators/server/managed_accumulator.hpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/accumulators/stubs/managed_accumulator.hpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/accumulators/managed_accumulator.hpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/accumulators/managed_accumulator.cpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/managed_accumulator_client.cpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/server/accumulator.hpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/stubs/accumulator.hpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/accumulator.hpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/accumulator.cpp"
"${PROJECT_SOURCE_DIR}/examples/accumulator/accumulator_client.cpp"
"${PROJECT_SOURCE_DIR}/examples/hello_world_component/hello_world_component.hpp"
"${PROJECT_SOURCE_DIR}/examples/hello_world_component/hello_world_component.cpp"
"${PROJECT_SOURCE_DIR}/examples/performance_counters/simplest_performance_counter.cpp"
Expand Down
2 changes: 1 addition & 1 deletion docs/namespace_func/threads.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace hpx::threads
static threads::thread* allocate_clone(threads::thread const&)
static void deallocate_clone(threads::thread const *)

class thread : public components::managed_component<detail::thread,thread>
class thread : public components::component<detail::thread,thread>
thread()
thread(thread_init_data const&,thread_pool&,thread_state_enum)
thread(BOOST_RV_REF(thread_init_data),thread_pool&,thread_state_enum)
Expand Down
113 changes: 51 additions & 62 deletions docs/tutorial/examples.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ function that is to be wrapped and the name of the action that you are
creating.

This picture should now start making sense. The function `fibonacci()` is
wrapped in an action `fibonacci_action`, which was run synchronously but
wrapped in an action `fibonacci_action`, which was run synchronously but
created asynchronous work, then returns a `boost::uint64_t`
representing the result of the function `fibonacci()`. Now, lets look at the
function `fibonacci()`:
Expand Down Expand Up @@ -333,9 +333,7 @@ component actions.

Components are globally named, meaning that a component action can be called
remotely (e.g. from another machine). There are two accumulator examples in
__hpx__; managed_accumulator and simple_accumulator (we will talk more about the
differences between the two later). This tutorial will examine the
managed_accumulator variant.
__hpx__; accumulator.

In the __fibonacci_example__ and the
__hello_world_example__, we introduced plain actions, which wrapped global
Expand All @@ -362,19 +360,19 @@ accumulator instance.
[teletype]

The source code for this example can be found here:
[hpx_link examples/accumulator/managed_accumulator_client.cpp..managed_accumulator_client.cpp].
[hpx_link examples/accumulator/accumulator_client.cpp..accumulator_client.cpp].

To compile this program, go to your __hpx__ build directory (see __getting_started__
for information on configuring and building __hpx__) and enter:

``
make examples.accumulator.managed_accumulator
make examples.accumulator.accumulator
``

To run the program type:

``
./bin/managed_accumulator_client
./bin/accumulator_client
``

Once the program starts running, it will print the following prompt and then
Expand All @@ -400,12 +398,12 @@ wait for input. An example session is given below:

[c++]

Now, let's take a look at the source code of the managed_accumulator example. This
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 exposes
an __hpx__ component) and a client application which uses the library. This
walkthrough will cover the __hpx__ component library. The code for the client
application can be found here:
[hpx_link examples/accumulator/managed_accumulator_client.cpp..managed_accumulator_client.cpp].
[hpx_link examples/accumulator/accumulator_client.cpp..accumulator_client.cpp].

An __hpx__ component is represented by three C++ classes:

Expand All @@ -417,86 +415,77 @@ An __hpx__ component is represented by three C++ classes:
Typically, these three classes all have the same name, but stubs and server
classes usually live in different sub-namespaces (`server` and `stubs`
respectively). For example, the full names of the three classes in
managed_accumulator are:
accumulator are:

* `examples::server::managed_accumulator` (server class)
* `examples::stubs::managed_accumulator` (stubs class)
* `examples::managed_accumulator` (client class)
* `examples::server::accumulator` (server class)
* `examples::stubs::accumulator` (stubs class)
* `examples::accumulator` (client class)

[heading The Server Class]

The following code is from:
[hpx_link examples/accumulator/accumulators/server/managed_accumulator.hpp..server/managed_accumulator.hpp].
[hpx_link examples/accumulator/accumulators/server/accumulator.hpp..server/accumulator.hpp].

All __hpx__ component server classes must inherit publicly from an __hpx__ component
base class. There are currently two component base classes:
All __hpx__ component server classes must inherit publicly from the __hpx__ component
base class: [classref hpx::components::component_base]`<>`

* [classref hpx::components::managed_component_base]`<>` - Managed components are components
which are allocated in bulk by __hpx__. Managed components are more efficient if
you are creating a large number (e.g. hundreds or more per machine) of
component instances.
* [classref hpx::components::simple_component_base]`<>` - Simple components are components
which are allocated individually by __hpx__. Simple components are more efficient
if you are creating a small number (e.g. only a handful per machine) of
component instances.

The managed_accumulator component inherits from [classref hpx::components::locking_hock]`<>`.
The accumulator component inherits from [classref hpx::components::locking_hock]`<>`.
This allows the runtime system to ensure that all action invocations are
serialized. That means that the system ensures that no two actions are invoked
at the same time on a given component instance. This makes the component thread
safe and no additional locking has to be implemented by the user. Moreover,
managed_accumulator component is a managed component, because it also inherits
from [classref hpx::components::managed_component_base]`<>` (the template
accumulator component is a component, because it also inherits
from [classref hpx::components::component_base]`<>` (the template
argument passed to locking_hook is used as its base class). The following
snippet shows the corresponding code:

[import ../../examples/accumulator/accumulators/server/managed_accumulator.hpp]
[managed_accumulator_server_inherit]
[import ../../examples/accumulator/accumulators/server/accumulator.hpp]
[accumulator_server_inherit]

Our accumulator class will need a data member to store its value in, so let's
declare a data member:

[managed_accumulator_server_data_member]
[accumulator_server_data_member]

The constructor for this class simply initializes `value_` to 0:

[managed_accumulator_server_ctor]
[accumulator_server_ctor]

Next, let's look at the three methods of this component that we will be exposing
as component actions:

[managed_accumulator_methods]
[accumulator_methods]

Here are the action types. These types wrap the methods we're exposing. The
wrapping technique is very similar to the one used in the __fibonacci_example__
and the __hello_world_example__:

[managed_accumulator_action_types]
[accumulator_action_types]

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

[managed_accumulator_registration_declarations]
[accumulator_registration_declarations]

[note The code above must be placed in the global namespace.]

The rest of the registration code is in
[hpx_link examples/accumulator/accumulators/managed_accumulator.cpp..managed_accumulator.cpp].
[hpx_link examples/accumulator/accumulators/accumulator.cpp..accumulator.cpp].

[import ../../examples/accumulator/accumulators/managed_accumulator.cpp]
[managed_accumulator_registration_definitions]
[import ../../examples/accumulator/accumulators/accumulator.cpp]
[accumulator_registration_definitions]

[note The code above must be placed in the global namespace.]

[heading The Stubs Class]

The following code is from
[hpx_link examples/accumulator/accumulators/stubs/managed_accumulator.hpp..stubs/managed_accumulator.hpp].
[hpx_link examples/accumulator/accumulators/stubs/accumulator.hpp..stubs/accumulator.hpp].

All stubs classes must inherit from the stubs base class, [classref hpx::components::stub_base]`<>`:

[import ../../examples/accumulator/accumulators/stubs/managed_accumulator.hpp]
[managed_accumulator_stubs_inherit]
[import ../../examples/accumulator/accumulators/stubs/accumulator.hpp]
[accumulator_stubs_inherit]

The stubs class contains helper functions which invoke actions on component
instances. There are a few different ways of invoking actions:
Expand All @@ -507,22 +496,22 @@ instances. There are a few different ways of invoking actions:
the action, we forget about it completely and continue with our computation.
We use [funcref hpx::applier::apply]`<>()` instead of
[funcref hpx::async]`<>()` to invoke an action in a non-blocking fashion.
Here's an example from the managed_accumulator stubs class:
Here's an example from the accumulator stubs class:

[managed_accumulator_stubs_reset_non_blocking]
[accumulator_stubs_reset_non_blocking]

* [*Asynchronous]: Futures, as demonstrated in __fibonacci_example__ and the
__hello_world_example__, enable asynchronous action invocation. Here's an
example from the managed_accumulator stubs class:
example from the accumulator stubs class:

[managed_accumulator_stubs_query_async]
[accumulator_stubs_query_async]

* [*Synchronous]: To invoke an action in a fully synchronous manner, we can
simply call [classref hpx::async]`<>().get()` (e.g., create a future and
immediately wait on it to be ready). Here's an example from the
managed_accumulator stubs class:
accumulator stubs class:

[managed_accumulator_stubs_add_sync]
[accumulator_stubs_add_sync]

[classref hpx::naming::id_type] is a type which represents a global identifier
in __hpx__. This is the type that is returned by [funcref hpx::find_here]`()`. This
Expand All @@ -531,13 +520,13 @@ type specifies the target of an action.
[heading The Client Class]

The following code is from
[hpx_link examples/accumulator/accumulators/managed_accumulator.hpp..managed_accumulator.hpp].
[hpx_link examples/accumulator/accumulators/accumulator.hpp..accumulator.hpp].

The client class is the primary interface to a component instance. Client classes
are used to create components:

``
examples::managed_accumulator c;
examples::accumulator c;
c.create(hpx::find_here()); // Create a component on this machine.
``

Expand All @@ -550,20 +539,20 @@ and to invoke component actions:
Clients, like stubs and servers, need to inherit from a base class, this time,
[classref hpx::components::client_base]`<>`:

[import ../../examples/accumulator/accumulators/managed_accumulator.hpp]
[managed_accumulator_client_inherit]
[import ../../examples/accumulator/accumulators/accumulator.hpp]
[accumulator_client_inherit]

For readability, we typedef the base class like so:

[managed_accumulator_base_type]
[accumulator_base_type]

Here are examples of how to expose actions through a client class:

[managed_accumulator_client_reset_non_blocking]
[accumulator_client_reset_non_blocking]

[managed_accumulator_client_query_async]
[accumulator_client_query_async]

[managed_accumulator_client_add_sync]
[accumulator_client_add_sync]

Note that `this->gid_` references a data member of the
[classref hpx::components::client_base]`<>` base class.
Expand Down Expand Up @@ -665,13 +654,13 @@ first place our principal and rate into shares futures by passing the variables
In this way [classref hpx::shared_future]`<double> principal` and `rate`
will be initialized to `init_principal` and `init_rate` when
[classref hpx::make_ready_future]`<double>` returns a future containing
those inital values. These shared futures then enter the for loop and are
passed to `interest`. Next `principal` and `interest` are passed to the
reassignment of `principal` using a [classref dataflow]. A dataflow will
those inital values. These shared futures then enter the for loop and are
passed to `interest`. Next `principal` and `interest` are passed to the
reassignment of `principal` using a [classref dataflow]. A dataflow will
first wait for it's arguments to be ready before launching any callbacks,
so `add` in this case will not begin until both `principal` and `interest` are ready.
This loop continues for each compound period that must be calculated. To
see how `interest` and `principal` are calculated in the loop let us look
This loop continues for each compound period that must be calculated. To
see how `interest` and `principal` are calculated in the loop let us look
at `calc_action` and `add_action`:

[interest_calc_add_action]
Expand All @@ -684,8 +673,8 @@ following statement:
``

This statement calls [memberref hpx::future::get]`()` on the shared future prinipcal
which had it's value calculated by our for loop. The program will wait here until the
entire dataflow tree has been calculated and the value assigned to result. The program
which had it's value calculated by our for loop. The program will wait here until the
entire dataflow tree has been calculated and the value assigned to result. The program
then prints out the final value of the investment and the amount of interest made by subtracting
the final value of the investment from the initial value of the investment.

Expand Down
10 changes: 10 additions & 0 deletions docs/whats_new.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ to the master branch commits since the last release.

[heading General Changes]

* We are moving into the direction of unifying managed and simple components. As
such, the classes [classref hpx::components::component] and
[classref hpx::components::component_base] have been added which currently just
forward to the currently existing simple component facilities. The examples
have been converted to only use those two classes.
* Added integration with the [@https://circleci.com/gh/STEllAR-GROUP/hpx CircleCI]
hosted continuous integration service. This gives us constant and immediate
feedback on the health of our master branch.
Expand Down Expand Up @@ -77,6 +82,11 @@ to the master branch commits since the last release.

[heading Breaking Changes]

* We are moving into the direction of unifying managed and simple components. In
order to stop exposing the old facilities, all examples have been converted to
use the new classes. The breaking change in this release is that performance
counters are now a [classref hpx::components::component_base] instead of
[classref hpx::components::managed_component_base].
* We removed the support for stackless threads. It turned out that there was no
performance benefit when using stackless threads. As such, we decided to clean
up our codebase. This feature was not documented.
Expand Down
4 changes: 2 additions & 2 deletions examples/1d_stencil/1d_stencil_5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ std::ostream& operator<<(std::ostream& os, partition_data const& c)
// component which allows for it to be created and accessed remotely through
// a global address (hpx::id_type).
struct partition_server
: hpx::components::simple_component_base<partition_server>
: hpx::components::component_base<partition_server>
{
// construct new instances
partition_server() {}
Expand Down Expand Up @@ -135,7 +135,7 @@ struct partition_server
//
// HPX_REGISTER_COMPONENT() exposes the component creation
// through hpx::new_<>().
typedef hpx::components::simple_component<partition_server> partition_server_type;
typedef hpx::components::component<partition_server> partition_server_type;
HPX_REGISTER_COMPONENT(partition_server_type, partition_server);

// HPX_REGISTER_ACTION() exposes the component member function for remote
Expand Down
4 changes: 2 additions & 2 deletions examples/1d_stencil/1d_stencil_6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ std::ostream& operator<<(std::ostream& os, partition_data const& c)
// component which allows for it to be created and accessed remotely through
// a global address (hpx::id_type).
struct partition_server
: hpx::components::simple_component_base<partition_server>
: hpx::components::component_base<partition_server>
{
enum partition_type
{
Expand Down Expand Up @@ -185,7 +185,7 @@ struct partition_server
//
// HPX_REGISTER_COMPONENT() exposes the component creation
// through hpx::new_<>().
typedef hpx::components::simple_component<partition_server> partition_server_type;
typedef hpx::components::component<partition_server> partition_server_type;
HPX_REGISTER_COMPONENT(partition_server_type, partition_server);

// HPX_REGISTER_ACTION() exposes the component member function for remote
Expand Down
4 changes: 2 additions & 2 deletions examples/1d_stencil/1d_stencil_7.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ std::ostream& operator<<(std::ostream& os, partition_data const& c)
// component which allows for it to be created and accessed remotely through
// a global address (hpx::id_type).
struct partition_server
: hpx::components::simple_component_base<partition_server>
: hpx::components::component_base<partition_server>
{
enum partition_type
{
Expand Down Expand Up @@ -185,7 +185,7 @@ struct partition_server
//
// HPX_REGISTER_COMPONENT() exposes the component creation
// through hpx::new_<>().
typedef hpx::components::simple_component<partition_server> partition_server_type;
typedef hpx::components::component<partition_server> partition_server_type;
HPX_REGISTER_COMPONENT(partition_server_type, partition_server);

// HPX_REGISTER_ACTION() exposes the component member function for remote
Expand Down