HPX - High Performance ParalleX

PrevUpHomeNext
Using HPX with pkg-config
How to Build HPX Applications with pkg-config
How to Build HPX Components with pkg-config

After you are done installing HPX, you should be able to build the following program. It prints Hello HPX World! on the locality you run it on.

// Including 'hpx/hpx_main.hpp' instead of the usual 'hpx/hpx_init.hpp' enables 
// to use the plain C-main below as the direct main HPX entry point.
#include <hpx/hpx_main.hpp>
#include <hpx/include/iostreams.hpp>

int main()
{
    // Say hello to the world!
    hpx::cout << "Hello World!\n" << hpx::flush;
    return 0;
}

Copy the text of this program into a file called hello_world.cpp.

Now, in the directory where you put hello_world.cpp, issue the following commands (where $HPX_LOCATION is the build directory or CMAKE_INSTALL_PREFIX you used while building HPX):

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

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

[Note] Note

HPX libraries have different names in debug and release mode. If you want to link against a debug HPX library, you need to use the _debug suffix for the pkg-config name. That means 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.

[Important] Important

If the HPX libraries are in a path that is not found by the dynamic linker. You need to add the path $HPX_LOCATION/lib to your linker search path (for example LD_LIBRARY_PATH on Linux)

To test the program, type:

./hello_world

which should print Hello World! and exit.

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();
    HPX_DEFINE_COMPONENT_ACTION(hello_world, invoke);
};

}

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&)
{
    {
        // Create a single instance of the component on this locality.
        examples::hello_world client =
            examples::hello_world::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 build directory or 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

HPX libraries have different names in debug and release mode. If you want to link against a debug HPX library, you need to use the _debug suffix for the pkg-config name. That means 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.

[Important] Important

If the HPX libraries are in a path that is not found by the dynamic linker. You need to add the path $HPX_LOCATION/lib to your linker search path (for example LD_LIBRARY_PATH on Linux)

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 -L${HOME}/my_hpx_libs -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