Skip to content

Overview

pika is a C++ library that builds on the std::execution (P2300) proposal accepted to C++26 by providing a CPU runtime with user-level threads, as well as integration with CUDA, HIP, and MPI. See Getting started to get started.

Hello, world

Below is a brief overview of what you can do with pika. The majority of the functionality below comes from std::execution. pika adds a high-performance CPU runtime as well as a std::execution scheduler to target the pika runtime. The stdexec repository contains an excellent list of resources for learning more about std::execution itself.

#include <pika/execution.hpp>
#include <pika/init.hpp>
#include <pika/thread.hpp>

#include <fmt/printf.h>

#include <utility>

int main(int argc, char* argv[])
{
    // Most functionality is found in the pika::execution namespace. If pika is
    // built with stdexec, std::execution will also be found in this namespace.
    namespace ex = pika::execution::experimental;
    // Some additional utilities are in pika::this_thread.
    namespace tt = pika::this_thread::experimental;

    // Start the pika runtime.
    pika::start(argc, argv);

    // Create a std::execution scheduler that runs work on the default pika
    // thread pool.
    ex::thread_pool_scheduler sched{};

    // We can schedule work using sched.
    auto snd1 = ex::just(42) | ex::continues_on(sched) | ex::then([](int x) {
        fmt::print(
            "Hello from a pika user-level thread (with id {})!\nx = {}\n",
            pika::this_thread::get_id(), x);
    });

    // The work is started once we call sync_wait.
    tt::sync_wait(std::move(snd1));

    // We can build arbitrary graphs of work using the split and when_all
    // adaptors.
    auto snd2 = ex::just(3.14) | ex::split();
    auto snd3 = ex::continues_on(snd2, sched) |
        ex::then([](double pi) { fmt::print("Is this pi: {}?\n", pi); });
    auto snd4 = ex::when_all(std::move(snd2), ex::just(500.3)) |
        ex::continues_on(sched) |
        ex::then([](double pi, double r) { return pi * r * r; });
    auto result = tt::sync_wait(ex::when_all(std::move(snd3), std::move(snd4)));
    fmt::print("The result is {}\n", result);

    // Tell the runtime that when there are no more tasks in the queues it is ok
    // to stop.
    pika::finalize();

    // Wait for all work to finish and stop the runtime.
    pika::stop();

    return 0;
}

The example above should output something like:

Hello from a pika user-level thread (with id 0x7fec6000c040)!
x = 42
Is this pi: 3.14?
The result is 785942.2826

Getting help

Please report issues on GitHub. General questions can be asked on GitHub discussions.

Users of pika

pika is used in DLA-Future, a distributed linear algebra library used in high-performance computing applications.

If you or a project you know is using pika, let us know with an issue or pull request.

Acknowledgements

pika is a fork of HPX focusing on the single-node use case complemented by minimal MPI support. pika would not exist without all the hard work that has gone into HPX.

The development of pika has been funded by:

Swiss National Supercomputing Centre (CSCS) ETH Zurich Platform for Advanced Scientific Computing (PASC)

Name

Pick your favourite meaning from the following: