Visible to Intel only — GUID: GUID-5D83E50F-29C4-492F-9A97-FB554CF66588
Visible to Intel only — GUID: GUID-5D83E50F-29C4-492F-9A97-FB554CF66588
Memory-Mapped (MM) Agent Kernel Invocation Interface
The compiler generates an invocation interface for your SYCL* kernel that you can use to control the kernel and pass in kernel arguments.
By default, the Intel® oneAPI DPC++/C++ Compiler generates a memory-mapped (MM) agent interface to control the kernel and pass in the kernel arguments.
Examples of MM Agent Kernel Invocation Interfaces
#include <sycl/sycl.hpp> using namespace sycl; struct MyFunctorIP { int *input_a, *input_b, *input_c; int n; void operator()() const { for (int i = 0; i < n; i++) { input_c[i] = input_a[i] + input_b[i]; } } }; ... q.single_task(MyFunctorIP{functor_input_A, functor_input_B, functor_input_C, kN}).wait();
#include <sycl/sycl.hpp> using namespace sycl; class MyLambdaIP; ... q.single_task<MyLambdaIP>([=] { for (int i = 0; i < n; i++) { lambda_input_C[i] = lambda_input_A[i] + lambda_input_B[i]; } }).wait();
Register Map Layout
Byte Address | Read/Write | Description |
---|---|---|
0x00 | Read only | 64-bit status register |
0x08 | Write only | 64-bit start register |
0x10 | reserved | |
0x18 | ||
0x20 | ||
0x28 | ||
0x30 | Read only | finish counter |
0x38 | reserved | |
0x40 | ||
0x48 | ||
0x50 | ||
0x58 | ||
0x60 | ||
0x68 | ||
0x70 | ||
0x78 | ||
0x80 | Write only | kernel arguments and pipes that use protocol_name::avalon_mm or protocol_name::avalon_mm_uses_ready |
0x88 | Write only | |
… | Write only |
Byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Description | reserved | CSR Address Map Version* | kernel_status Bits |
The CSR address map version might change when you update the Intel® oneAPI DPC++/C++ Compiler. If the CSR address map version changes, review the generated CSR structure and any code that you that depends on the CSR structure.
Bit | 15 | 14 | 13:5 | 4 | 3 | 2 | 1 | 0 |
Description | started | valid_in | reserved | unstall | stalled | busy | done | reserved |
Bit | 63:1 | 0 |
Description | reserved | start |
Register Map Header File
The compiler generates a header file that provides the addresses of various registers in the agent memory map. A top-level header file named register_map_offsets.hpp is created in the .prj/include directory for each device image that you can include if you are interfacing with the SYCL* device image.
An additional header is generated for each of your kernels within the .prj directory. Each kernel has a <kernel_name>_register_map.hpp file associated with it. The file is located in the .prj/include/kernel_headers directory .
The register_map_offsets.hpp header file includes these <kernel_name>_register_map.hpp files and defines the address offsets for each kernel.
In most cases, include only the register_map_offsets.hpp file directly. However, you might still need to refer to the individual kernel <kernel_name>_register_map.hpp files for the macro definitions that you need to use in your application.
/* Status register contains all the control bits to control kernel execution */ /*****************************************************************************/ /* Memory Map Summary */ /*****************************************************************************/ /* Address | Access | Register | Argument | Description --------|--------|--------------|-----------------------|---------------------- 0x0 | R/W | reg0[63:0] | Status[63:0] | Read/Write the status | | | | bits that are | | | | described below --------|--------|--------------|-----------------------|---------------------- 0x8 | R/W | reg1[31:0] | Start[31:0] | Write 1 to initiate | | | | a kernel start --------|--------|--------------|-----------------------|---------------------- 0x30 | R | reg6[31:0] | FinishCounter[31:0] | Read to get number of | | reg6[63:32] | FinishCounter[31:0] | kernel finishes, note | | | | that this register | | | | clears on read --------|--------|--------------|-----------------------|---------------------- 0x80 | W | reg16[63:0] | arg_input_a[63:0] | --------|--------|--------------|-----------------------|---------------------- 0x88 | R/W | reg17[63:0] | arg_input_b[63:0] | --------|--------|--------------|-----------------------|---------------------- 0x90 | R/W | reg18[63:0] | arg_input_c[63:0] | --------|--------|--------------|-----------------------|---------------------- 0x98 | R/W | reg19[31:0] | arg_n[31:0] | */ /**************************************************************************/ /* Register Address Macros */ /**************************************************************************/ /* Status Register Bit Offsets (Bits) */ /* Note: Bits In Status Registers Are Marked As Read-Only or Read-Write Please Do Not Write To Read-Only Bits */ #define KERNEL_REGISTER_MAP_DONE_OFFSET (1) // Read-only #define KERNEL_REGISTER_MAP_BUSY_OFFSET (2) // Read-only #define KERNEL_REGISTER_MAP_STALLED_OFFSET (3) // Read-only #define KERNEL_REGISTER_MAP_UNSTALL_OFFSET (4) // Read-write #define KERNEL_REGISTER_MAP_VALID_IN_OFFSET (14) // Read-only #define KERNEL_REGISTER_MAP_STARTED_OFFSET (15) // Read-only /* Status Register Bit Masks (Bits) */ #define KERNEL_REGISTER_MAP_DONE_MASK (0x2) #define KERNEL_REGISTER_MAP_BUSY_MASK (0x4) #define KERNEL_REGISTER_MAP_STALLED_MASK (0x8) #define KERNEL_REGISTER_MAP_UNSTALL_MASK (0x10) #define KERNEL_REGISTER_MAP_VALID_IN_MASK (0x4000) #define KERNEL_REGISTER_MAP_STARTED_MASK (0x8000)
The register_map_interface macro
Deprecated: The register_map_interface macro is deprecated and might be removed in a future release. Use the memory-mapped (MM) agent interface provided by default when you do not specify any kernel properties, as described earlier in this section.
While the default option for kernels are agent kernels, there is a register_map_interface macro to explicitly mark a function as an agent kernel. This is shown in the following example:
#include <sycl/sycl.hpp>
#include <sycl/ext/intel/prototype/interfaces.hpp>
using namespace sycl;
struct MyIP {
int *input_a, *input_b, *input_c;
int n;
register_map_interface void operator()() const {
for (int i = 0; i < n; i++) {
input_c[i] = input_a[i] + input_b[i];
}
}
};