Skip to content

Part 1. One core · lesson 6 of 42

6. A result

A result is one 32-bit number that a core sends back to Python together with its report that a command is done. This lesson relies on lesson 4, Hello, core and lesson 5, Commands.

Why a result

So far the only thing Python learned from a command was that it was done. Almost every real program needs more: the answer. The result is the smallest answer there is: one number, with nothing to set up. Later lessons move whole arrays; this one moves one number.

The general form

In writer.cpp, before return true;:

writer.result(VALUE);

In Python, in the call of submit, and after wait:

handle = run.submit(0, group=(FIRST, COUNT), result=True)
event = run.wait(handle, timeout=SECONDS)
event.result
  • VALUE is an unsigned 32-bit number: a constant or any C++ expression that gives a uint32_t. It is what the core hands back.
  • result=True tells the cores that this command wants a result. Without it, the number is not sent, even if the kernel sets it.
  • event.result is the number, in Python, as an ordinary int.

One line at a time

writer.run([&](const km_command_t& command) {
    writer.result(42);
    return true;
});

writer.result(42) stores 42 as this core's answer to this command. It is writer that has it, not reader or compute: writer.cpp is the kernel that reports to the card that the command is done, so it is the one that can attach a number to the report. The functions of reader.cpp and compute.cpp cannot.

handle = run.submit(0, group=(0, 1), result=True)

The same submit as before, with result=True.

The one new part of the line.
print(f"the core answered {event.result}")

event.result is the 42 that the kernel gave.

The whole program

"""A result: the core sends one number back with its report."""

from pathlib import Path

import komorebi as km

HERE = Path(__file__).resolve().parent

program = km.Program("a_result", kernels=HERE / "kernels")

with km.Session() as session:
    run = session.load(program)
    handle = run.submit(0, group=(0, 1), result=True)
    event = run.wait(handle, timeout=10.0)
    run.stop()
    print(f"the core answered {event.result}")
    assert event.result == 42
// The writer kernel: it answers every command with the number 42.
#include "komorebi/device/km_worker.hpp"

void kernel_main() {
    km::Writer writer;
    writer.run([&](const km_command_t& command) {
        writer.result(42);
        return true;
    });
}

reader.cpp and compute.cpp are the same empty ones as before.

the core answered 42

The kernel computed nothing here: 42 is a constant. What matters is the path it took. It was set on a core of the card, in C++, and it came out of event.result in Python. The next lesson sends numbers the other way.

Common mistakes

  • Forgetting result=True. The command works and the event arrives, but event.result is None.
  • Reading event.microseconds of a command that asked for a result. The card sends the result in the place where it would send the time, so event.microseconds is not a time then. For a time, use a command without result=True.
  • Setting the result in reader.cpp or the compute kernel. Only writer.cpp has result.

Next: lesson 7, Arguments sends numbers the other way, from Python into the kernel.