Visible to Intel only — GUID: GUID-D4D65B32-60BF-440D-A945-A7C0DB7519FA
Visible to Intel only — GUID: GUID-D4D65B32-60BF-440D-A945-A7C0DB7519FA
Memory-Mapped Interface Unified-Shared-Memory Virtual Address Space
The compiler encodes certain information regarding the virtual address space in the top bits of a 64-bit pointer address as follows:
Bit Range |
Description |
---|---|
40:0 |
Used for addressing within the memory system |
63:41 |
Stores the virtual address space information that is derived from the buffer location |
In some cases, the compiler cannot determine which buffer location a pointer corresponds to and it creates logic in the generated RTL that inspects the top bits of the pointer at runtime to detect the buffer location and route the memory transaction to the correct external memory interface.
You do not need to encode the buffer location information yourself in most cases. Exceptions are outlined in Manual Buffer Location Encoding Use Case.
The compiler automatically generates logic to embed this information from the buffer location specified on the pointer kernel argument in the source file.
Manual Buffer Location Encoding Use Case
If the kernel has at least one kernel argument where the buffer location is specified (annotated argument) and at least one argument where the buffer location is not specified (unannotated argument), then you must embed the buffer location information in the top bits of any unannotated kernel arguments.
Consider the following code example:
// This struct defines the IP that will be generated
struct MyIPComponent{
// struct members are kernel arguments
int* a; // no buffer location specified
mmhost(1, ...) int *b; // buffer location 1
mmhost(2, ...) int *c; // buffer location 2
mmhost(3, ...) int *d; // buffer location 3
// operator()() defines the device/IP code
void operator()() const {
*a *= 2;
*b *= 2;
*c *= 2;
*d *= 2;
}
};
In this example, the compiler does not know what external memory pointer a will point to, so the compiler creates logic to check the top bits of the pointer to determine, at runtime, which buffer location to access. Therefore, you must set those top bits for argument a (but not for the other kernel arguments).
In such cases, if the unannotated pointer argument has a conduit interface then the port is 64 bits wide. And, if the interface is register-map–based, all 64 bits are passed to the kernel.
Simulation Exception
When you simulate your kernel in the OneAPI simulation flow, you do not need to write any host code (even in this use case) to embed information in the pointer bits. The buffer locations are all taken care of by the runtime stack that allocates the pointers in the host code.When the compiler can deduce which buffer location that a pointer argument points to (for example, when there is only one mm_host interface), the compiler embeds the buffer location automatically. Buffer locations need to be specified manually only when your kernels have a mix of annotated and unannotated kernel arguments.
The compiler infers one global memory (with inferred buffer location 0) whenever there is any unannotated pointer kernel argument. In the following code example, because there are only unannotated pointer arguments, the compiler infers only one global memory and so it can embed the correct information in the top bits of the pointer kernel arguments.
// This struct defines the IP that will be generated
struct MyIPComponent{
// struct members are kernel arguments
int* a; // no buffer location specified
int* b; // no buffer location specified
// no other annotated kernel argument is present
// operator()() defines the device/IP code
void operator()() const {
*a = ...
*b = ...
}
};
Determining Virtual Address Space Information
If you need to embed the virtual address space information in the top bits of the pointer kernel arguments because the compiler cannot do so, get the information to embed from the HTML reports:
If you have not already done so, compile your kernel to obtain the HTML reports
Open the HTML reports.
Go to Views > System Viewer
In the left pane, expand System and then expand Global memory
Under Global memory, you see entries for all external memories for your kernel.
Click on a memory to display that memory in the System Viewer pane.
In the System Viewer pane, find the box that represents the memory and click the node inside the box.
This node represents the “interface” of that global memory.
In the Details pane, find the Start Address of the memory.
The top bits of your unannotated pointer argument must match the top bits of this start address if you want the pointer to access this buffer location.
The following screen capture shows an example of determining the top bit of the start address needed to address a buffer location 1.