HPX - High Performance ParalleX

PrevUpHomeNext

How to Build HPX Components with pkg-config

Let's try a more complex example involving an HPX component. An HPX component is a class which exposes HPX actions. HPX components are compiled into dynamically loaded modules called component libraries. Here's the source code:

hello_world_component.cpp

#include "hello_world_component.hpp"
#include <hpx/include/iostreams.hpp>

namespace examples { namespace server
{

void hello_world::invoke()
{
    hpx::cout << "Hello HPX World!\n" << hpx::flush;
}

}}

HPX_REGISTER_COMPONENT_MODULE();

typedef hpx::components::managed_component<
    examples::server::hello_world
> hello_world_type;

HPX_REGISTER_MINIMAL_COMPONENT_FACTORY(hello_world_type, hello_world);

HPX_REGISTER_ACTION(
    examples::server::hello_world::invoke_action, hello_world_invoke_action);

hello_world_component.hpp

#if !defined(HELLO_WORLD_COMPONENT_HPP)
#define HELLO_WORLD_COMPONENT_HPP

#include <hpx/hpx_fwd.hpp>
#include <hpx/include/actions.hpp>
#include <hpx/include/lcos.hpp>
#include <hpx/include/components.hpp>
#include <hpx/include/serialization.hpp>

namespace examples { namespace server
{

struct HPX_COMPONENT_EXPORT hello_world
  : hpx::components::managed_component_base<hello_world>
{
    void invoke();

    typedef hpx::actions::action0<
        hello_world, &hello_world::invoke
    > invoke_action;
};

}

namespace stubs
{

struct hello_world : hpx::components::stub_base<server::hello_world>
{
    static void invoke(hpx::naming::id_type const& gid)
    {
        hpx::async<server::hello_world::invoke_action>(gid).get();
    }
};

}

struct hello_world
  : hpx::components::client_base<hello_world, stubs::hello_world>
{
    typedef hpx::components::client_base<hello_world, stubs::hello_world>
        base_type;

    void invoke()
    {
        this->base_type::invoke(this->get_gid());
    }
};

}

HPX_REGISTER_ACTION_DECLARATION(
    examples::server::hello_world::invoke_action, hello_world_invoke_action);

#endif // HELLO_WORLD_COMPONENT_HPP

hello_world_client.cpp

#include "hello_world_component.hpp"
#include <hpx/hpx_init.hpp>

int hpx_main(boost::program_options::variables_map&)
{
    {
        examples::hello_world client;

        // Create a single instance of the component on this locality.
        client.create(hpx::find_here());

        // Invoke the components action, which will print "Hello World!".
        client.invoke();
    }

    return hpx::finalize(); // Initiate shutdown of the runtime system.
}

int main(int argc, char* argv[])
{
    // Configure application-specific options.
    boost::program_options::options_description desc_commandline(
        "usage: " HPX_APPLICATION_STRING " [options]");

    return hpx::init(desc_commandline, argc, argv); // Initialize and run HPX.
}

Copy the three source files above into three files (called hello_world_component.cpp, hello_world_component.hpp and hello_world_client.cpp respectively).

Now, in the directory where you put the files, run the following command to build the component library. (where $HPX_LOCATION is the CMAKE_INSTALL_PREFIX you used while building HPX):

$ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$HPX_LOCATION/lib/pkgconfig
$ c++ -o libhello_world.so hello_world_component.cpp `pkg-config --cflags --libs hpx_component` -DHPX_COMPONENT_NAME=hello_world

Now pick a directory in which to install your hpx component libraries. For this example, we'll choose a directory named ''my_hpx_libs''.

$ mkdir ~/my_hpx_libs
$ mv libhello_world.so ~/my_hpx_libs
[Note] Note

If HPX was build in debug mode (cmake -DCMAKE_BUILD_TYPE=Debug) the pkg-config names have to be different. Instead of hpx_application or hpx_component you will have to use hpx_application_debug or hpx_component_debug. Moreover, all referenced HPX components need to have a appended 'd' suffix, e.g. instead of -liostreams you will need to specify -liostreamsd.

In the ~/my_hpx_libs directory you need to create an ini file inside that directory which matches the name of the component (as supplied by -DHPX_COMPONENT_NAME above).

hello_world.ini

[hpx.components.hello_world]
name = hello_world
path = ${HOME}/my_hpx_libs
[Note] Note

For additional details about ini file configuration and HPX, see Loading INI Files

In addition, you'll need this in your home directory:

.hpx.ini

[hpx]
ini_path = $[hpx.ini_path]:${HOME}/my_hpx_libs

Now, to build the application that uses this component (hello_world_client.cpp), we do:

$ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$HPX_LOCATION/lib/pkgconfig
$ c++ -o hello_world_client hello_world_client.cpp `pkg-config --cflags --libs hpx_application` -liostreams -lhello_world
[Important] Important

When using pkg-config with HPX, the pkg-config flags must go after the -o flag.

Finally, you'll need to set your LD_LIBRARY_PATH before you can run the program. To run the program, type:

$ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$HOME/my_hpx_libs"
$ ./hello_world_client

which should print Hello HPX World! and exit.


PrevUpHomeNext