## Managing Data
## Learning Objectives * Learn about the USM model for managing data * Learn how to allocate, transfer and free memory using USM. * Learn how to access data in a kernel function
#### Memory Models
* In SYCL the USM (unified shared memory) model can be used to manage data. * Which model you choose can have an effect on how you enqueue kernel functions.
#### CPU and GPU Memory
* A GPU has its own memory, separate to CPU memory. * In order for the GPU to use memory from the CPU, the following actions must take place (either explicitly or implicitly): * Memory allocation on the GPU. * Data migration from the CPU to the allocation on the GPU. * Some computation on the GPU. * Migration of the result back to the CPU.
#### CPU and GPU Memory
* Memory transfers between CPU and GPU are a bottleneck. * We want to minimize these transfers, when possible.
#### USM Allocation Types
* There are different ways USM memory can be allocated: host, device and shared.
| Type | Description | Access host | Access device | Nominal location | |--------|---------------------------------|----------------|----------------|----------------------| | device | device global allocations | ✗ | ✓ | device | | host | host allocations | ✓ | ✓ | host | | shared | Allocations shared between both | ✓ | ✓ | migrates as required |
#### Using USM - Malloc Device

// Allocate memory on device
T *device_ptr = sycl::malloc_device<T>(n, myQueue);

// Copy data to device
myQueue.memcpy(device_ptr, cpu_ptr, n * sizeof(T));

// ...
// Do some computation on device
// ...

// Copy data back to CPU
myQueue.memcpy(result_ptr, device_ptr, n * sizeof(T)).wait();

// Free allocated data
sycl::free(device_ptr, myQueue);
						
* It is important to free memory after it has been used to avoid memory leaks.
#### Using USM - Malloc Shared

// Allocate shared memory
T *shared_ptr = sycl::malloc_shared<T>(n, myQueue);

// Shared memory can be accessed on host as well as device
for (auto i = 0; i < n; ++i)
  shared_ptr[i] = i;

// ...
// Do some computation on device
// ...

// Free allocated data
sycl::free(shared_ptr, myQueue);
						
* Shared memory is accessible on host and device. * Performance of shared memory accesses may be poor depending on platform.
#### operator[]

gpuQueue.submit([&](handler &cgh){
  cgh.single_task<mykernel>([=]{
    out[0] = inA[0] + inB[0];
  });
});
						
* Data can be accessed from within a kernel function by calling `operator[]`. * `operator[]` for USM pointers must take a `size_t`.
## Questions
#### Exercise
Code_Exercises/Managing_Data/source
Implement a SYCL application that adds two variables and returns the result using the USM memory model.