Private Memory

Private memory is the region of system memory that is only accessible by a processing element within an OpenCL™ device. This memory space can be read from and written to by a single work item.

For devices using an FPGA, the physical mapping of the OpenCL memory model is the following:
  • Host memory is any memory connected to the host processor only.
  • Global and constant memories are any memory that is connected to the FPGA. These are usually memory chips that are physically connected to the FPGA. The host processor has access to these memory banks through infrastructure in the FPGA base device.
  • Local memory is memory inside of the FPGA. This memory is typically implemented using block RAM elements in the FPGA fabric.
  • Private memory is memory inside of the FPGA. This memory is typically implemented using registers in the FPGA fabric in order to minimize latency to the compute data path in the processing element.
  • You can share data between Linux devices using the Xilinx OpenCL API Extensions, xclGetMemObjectFd and xclGetMemObjectFromFd.
    static cl_int xclGetMemObjectFd(cl_mem mem, int* fd) /* returned fd */
    • API clGetMemObjectFd returns a file pointer to which other OS processes can write. This pointer is used to transfer input data to a cl_mem object using clGetMemObjectFromFd.
      static cl_int xclGetMemObjectFromFd(cl_context context, /
      cl_device_id device, cl_mem_flags flags, int fd, cl_mem* mem) /* returned cl_mem */
    • API xclGetMemObjectFromFd returns a cl_mem object which is used to write data to a device associated the file pointer. The following example shows how this is used:
    int main(int argc, char** argv) 
    {int xilinx_bo_fd[NumOfBuffers];cl_mem buffer[NumOfBuffers];
    ...
    // Create buffers on Device
    for(size_t i = 0; i < NumOfBuffers; i++) {
     buffer[i] = clCreateBuffer(world.context,
     //CL_MEM_READ_WRITE, // | CL_MEM_EXT_PTR_XILINX,
    CL_MEM_READ_WRITE,
    BufferSize,
    NULL,
     &err);
      }
    // Transfrers buffers to device
    err = clEnqueueMigrateMemObjects(world.command_queue,
    NumOfBuffers,
    buffer,
    CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED,
    0,
    NULL,
    NULL);
    clFinish(world.command_queue);
    ...
     // Associate device buffer to file descriptor
    for(size_t i = 0; i < NumOfBuffers; i++) {
    err = xclGetMemObjectFd(buffer[i], &xilinx_bo_fd[i]);
    if(err != CL_SUCCESS) {
    printf("Error: xclGetMemObjectFd failed. Buffer #: %i\n", i);
    return -1;
     }
        }
    printf("Good: Got FD of all buffers\n");
    ...
    // Transfer data from cl_mem object to file descriptor 
    for(size_t i = 0; i < NumOfBuffers; i++) {
    err = xclGetMemObjectFromFd(world.context, world.device_id, 0,xilinx_bo_fd[i], &imported_buffer[i]);
    if(err != CL_SUCCESS) {
    printf("Error: xclGetMemObjectFromFd failed. Buffer #: %i\n", i);
     return -1;
     }
       }
    printf("Good: Got all buffers from FDs\n");
    ...
    ... // Run kernel and process data
      }