Skip to content

Part 1. One core · lesson 7 of 42

7. Arguments

A command can carry up to ten 32-bit numbers, its arguments, and the kernel reads them as command.a0 to command.a9. This lesson relies on lesson 4, Hello, core and lesson 6, A result.

Why arguments

A kernel that does the same thing every time is not much use. The numbers it works on have to come from somewhere, and the command is the message that arrives at the right moment. Python puts the numbers in the command; the kernel takes them out.

The general form

In Python, in the call of submit:

handle = run.submit(0, group=(0, 1), args=[FIRST, SECOND, ...])

In a kernel, inside the function you give to run:

const uint32_t name = command.a0;
const uint32_t other = command.a1;
  • args=[...] is a list of up to ten whole numbers, from 0 to 4,294,967,295 (32 bits, not negative).
  • command.a0 is the first number of the list, command.a1 the second, and so on to command.a9. They are uint32_t.
  • name is yours. Read each argument once, at the top of the function, into a variable that says what the number is: left, right, count. After that line the rest of the function never writes a0 again. The tutorial does this in every kernel, because a3 means nothing to a reader and first_page does.
  • An argument that you did not send reads as 0.

One line at a time

handle = run.submit(0, group=(0, 1), args=[left, right], result=True)

args=[left, right] puts the two numbers in the command. The program sends the sums of three pairs, one command each, and left and right are the loop's variables.

The first number of the list is argument 0, the second argument 1.
writer.run([&](const km_command_t& command) {
    const uint32_t left = command.a0;
    const uint32_t right = command.a1;
    writer.result(left + right);
    return true;
});

The kernel reads the two numbers into left and right, adds them, and sets the sum as the result (lesson 6, A result). The addition runs on the core, in C++.

The whole program

"""Arguments: numbers go into the kernel with the command; the sum comes back."""

from pathlib import Path

import komorebi as km

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

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

with km.Session() as session:
    run = session.load(program)
    for left, right in [(40, 2), (7, 35), (1000, 2345)]:
        handle = run.submit(0, group=(0, 1), args=[left, right], result=True)
        event = run.wait(handle, timeout=10.0)
        print(f"{left} + {right} = {event.result}")
        assert event.result == left + right
    run.stop()
// The writer kernel: it adds the first two arguments of the command and answers.
#include "komorebi/device/km_worker.hpp"

void kernel_main() {
    km::Writer writer;
    writer.run([&](const km_command_t& command) {
        const uint32_t left = command.a0;
        const uint32_t right = command.a1;
        writer.result(left + right);
        return true;
    });
}

This is the program of lesson 1, What Komorebi is, the one that had not been explained. Its reader.cpp and compute.cpp are the empty ones.

40 + 2 = 42
7 + 35 = 42
1000 + 2345 = 3345

Common mistakes

  • Eleven numbers, or more. submit stops with ValueError: 11 arguments; a command has 10.
  • A negative number, or one above 4,294,967,295. submit stops with ValueError: arguments are 32-bit unsigned words.
  • A number with a fraction. args=[1.5, 0] is not refused: the 1.5 arrives as 1, with no message. Pass whole numbers.
  • A sum that does not fit in 32 bits. The kernel's addition wraps around: with args=[4294967295, 1] the result is 0.

Next: lesson 8, Handlers puts two different pieces of work into one kernel.