Files
TheRock/rocm-systems/projects/clr/opencl/tests/ocltst/module/runtime/OCLSVM.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

577 lines
20 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#include "OCLSVM.h"
#include <stdio.h>
#include <algorithm>
#include <cstdlib>
#ifdef _WIN32
#include <intrin.h>
#include <windows.h>
#endif
#include <iostream>
#define NUM_SIZES 6
#define OCL_CHECK(error) \
if (error != CL_SUCCESS) { \
fprintf(stderr, "OpenCL API invocation failed at %s:%d\n", __FILE__, __LINE__); \
exit(-1); \
}
#define STR(__macro__) #__macro__
#ifdef _WIN32
size_t getTotalSystemMemory() {
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
return status.ullTotalPhys;
}
#endif
template <typename T, unsigned N> static unsigned countOf(const T (&)[N]) { return N; }
const static char* sources[] = {
STR(__kernel void test(__global int* ptr) { ptr[get_global_id(0)] = 0xDEADBEEF; }),
STR(__kernel void test(__global int* ptr, __global int* ptr2) {
ptr[get_global_id(0)] = 0xDEADBEEF;
ptr2[get_global_id(0)] = 0xDEADF00D;
}),
STR(__kernel void test(__global long* ptr) { ptr[get_global_id(0) * 1024] = 0xBAADF00D; }),
STR(__kernel void test(__global ulong* ptr) {
while (ptr) {
*ptr = 0xDEADBEEF;
ptr = *((__global ulong * __global*)(ptr + 1));
}
}),
STR(__kernel void test(__global volatile int* ptr, int numIterations) {
for (int i = 0; i < numIterations; i++) {
// This should be:
// atomic_fetch_add_explicit(ptr, 1, memory_order_relaxed,
// memory_scope_all_svm_devices);
// But using device atomics is mapped to the same ISA and compiles
// in OpenCL 1.2
atomic_inc(ptr);
}
}),
STR(__kernel void test(){
// dummy
}),
STR(__kernel void test(int8 arg0, __global int* arg1, int arg2, __global int* arg3,
__global float* arg4){
// dummy
}),
STR(__kernel void test(__global int* ptr, int to) {
// dummy kernel that takes a long time to complete
for (int i = 0; i < to; ++i) {
// avoid compiler optimizations
if (ptr[get_global_id(0)] != 17) {
ptr[get_global_id(0)]++;
} else {
ptr[get_global_id(0)] += 2;
}
}
}),
STR(__kernel void test(){
// dummy
})};
OCLSVM::OCLSVM() { _numSubTests = countOf(sources); }
OCLSVM::~OCLSVM() {}
void OCLSVM::open(unsigned int test, char* units, double& conversion, unsigned int deviceId) {
OCLTestImp::open(test, units, conversion, deviceId);
CHECK_ERROR(error_, "Error opening test");
_openTest = test;
if (!isOpenClSvmAvailable(devices_[_deviceId])) {
printf("Device does not support any SVM features, skipping...\n");
return;
}
program_ = _wrapper->clCreateProgramWithSource(context_, 1, sources + _openTest, NULL, &error_);
CHECK_ERROR(error_, "clCreateProgramWithSource() failed");
error_ = _wrapper->clBuildProgram(program_, 1, &devices_[deviceId], "-cl-std=CL2.0", NULL, NULL);
CHECK_ERROR(error_, "clBuildProgram() failed");
kernel_ = _wrapper->clCreateKernel(program_, "test", &error_);
CHECK_ERROR(error_, "clCreateKernel() failed");
}
#ifndef CL_VERSION_2_0
// make sure the tests compile in OpenCL <= 1.2
void OCLSVM::runFineGrainedBuffer() {}
void OCLSVM::runFineGrainedSystem() {}
void OCLSVM::runFineGrainedSystemLargeAllocations() {}
void OCLSVM::runLinkedListSearchUsingFineGrainedSystem() {}
void OCLSVM::runPlatformAtomics() {}
void OCLSVM::runEnqueueOperations() {}
void OCLSVM::runSvmArgumentsAreRecognized() {}
void OCLSVM::runSvmCommandsExecutedInOrder() {}
void OCLSVM::runIdentifySvmBuffers() {}
#else
void OCLSVM::runFineGrainedBuffer() {
if (!(svmCaps_ & CL_DEVICE_SVM_FINE_GRAIN_BUFFER)) {
printf(
"Device does not support fined-grained buffer sharing, skipping "
"test...\n");
return;
}
const size_t numElements = 256;
int* ptr = (int*)clSVMAlloc(context_, CL_MEM_READ_WRITE | CL_MEM_SVM_FINE_GRAIN_BUFFER,
numElements * sizeof(int), 0);
CHECK_RESULT(!ptr, "clSVMAlloc() failed");
error_ = clSetKernelArgSVMPointer(kernel_, 0, ptr);
CHECK_ERROR(error_, "clSetKernelArgSVMPointer() failed");
size_t gws[1] = {numElements};
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL, gws, NULL, 0,
NULL, NULL);
CHECK_ERROR(error_, "clEnqueueNDRangeKernel() failed");
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_ERROR(error_, "Queue::finish() failed");
size_t matchingElements = std::count(ptr, ptr + numElements, (int)0xDEADBEEF);
CHECK_RESULT(matchingElements != numElements, "Expected: %zd, found:%zd", numElements,
matchingElements);
clSVMFree(context_, ptr);
}
void OCLSVM::runFineGrainedSystem() {
if (!(svmCaps_ & CL_DEVICE_SVM_FINE_GRAIN_SYSTEM)) {
printf(
"Device does not support fined-grained system sharing, skipping "
"test...\n");
return;
}
const size_t numElements = 256;
int* ptr = new int[numElements];
int* ptr2 = new int[numElements];
error_ = clSetKernelArgSVMPointer(kernel_, 0, ptr);
CHECK_ERROR(error_, "clSetKernelArgSVMPointer() failed");
error_ = clSetKernelArgSVMPointer(kernel_, 1, ptr2);
CHECK_ERROR(error_, "clSetKernelArgSVMPointer() failed");
size_t gws[1] = {numElements};
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL, gws, NULL, 0,
NULL, NULL);
CHECK_ERROR(error_, "clEnqueueNDRangeKernel() failed");
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_ERROR(error_, "Queue::finish() failed");
size_t matchingElements = std::count(ptr, ptr + numElements, (int)0xDEADBEEF);
size_t matchingElements2 = std::count(ptr2, ptr2 + numElements, (int)0xDEADF00D);
CHECK_RESULT(matchingElements + matchingElements2 != 2 * numElements, "Expected: %zd, found:%zd",
numElements * 2, matchingElements + matchingElements2);
delete[] ptr;
delete[] ptr2;
}
void OCLSVM::runFineGrainedSystemLargeAllocations() {
#ifdef _WIN32
if (!(svmCaps_ & CL_DEVICE_SVM_FINE_GRAIN_SYSTEM)) {
printf(
"Device does not support fined-grained system sharing on Lnx, skipping "
"test...\n");
return;
}
// Max allowed multiplier for malloc
size_t allowedMemSize = getTotalSystemMemory() >> 12;
size_t numElements = 256;
char* s = getenv("OCLSVM_MALLOC_GB_SIZE");
char* s2 = getenv("OCLSVM_MEMSET_ALLOC");
for (int j = 1; j <= NUM_SIZES; j++) {
numElements = 131072 * j;
if (s != NULL) numElements = 131072 * atoi(s);
if (numElements > allowedMemSize) break;
void* ptr = malloc(numElements * 1024 * sizeof(uint64_t));
CHECK_ERROR(ptr == NULL, "malloc failure");
if (s2 != NULL) memset(ptr, 0, numElements * 1024 * sizeof(uint64_t));
error_ = clSetKernelArgSVMPointer(kernel_, 0, ptr);
CHECK_ERROR(error_, "clSetKernelArgSVMPointer() failed");
size_t gws[1] = {numElements};
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL, gws, NULL, 0,
NULL, NULL);
CHECK_ERROR(error_, "clEnqueueNDRangeKernel() failed");
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_ERROR(error_, "Queue::finish() failed");
uint64_t* ptr64 = reinterpret_cast<uint64_t*>(ptr);
// Do a check
for (int i = 0; i < numElements; i++) {
if ((int)ptr64[i * 1024] != 0xBAADF00D) {
uint64_t temp = ptr64[i * 1024];
delete[] ptr;
CHECK_RESULT(temp != 0xBAADF00D, "Found: %d, Expected:%d", temp, 0xBAADF00D);
}
}
delete[] ptr;
}
#endif
}
void OCLSVM::runLinkedListSearchUsingFineGrainedSystem() {
if (!(svmCaps_ & CL_DEVICE_SVM_FINE_GRAIN_SYSTEM)) {
printf(
"Device does not support fined-grained system sharing, skipping "
"test...\n");
return;
}
uint64_t input[] = {34, 6, 0, 11, 89, 34, 6, 6, 6, 0xDEADBEEF};
int inputSize = countOf(input);
Node* ptr = NULL;
for (int i = 0; i < inputSize; i++) {
ptr = new Node(input[i], ptr);
}
error_ = clSetKernelArgSVMPointer(kernel_, 0, ptr);
CHECK_ERROR(error_, "clSetKernelArgSVMPointer() failed");
size_t gws[1] = {1};
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL, gws, NULL, 0,
NULL, NULL);
CHECK_ERROR(error_, "clEnqueueNDRangeKernel() failed");
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_ERROR(error_, "Queue::finish() failed");
int matchingElements = 0;
// verify result while deallocating resources at the same time
while (ptr) {
if (ptr->value_ == 0xDEADBEEF) {
matchingElements++;
}
Node* tmp = ptr;
ptr = (Node*)ptr->next_;
delete tmp;
}
CHECK_RESULT(matchingElements != inputSize, "Expected: %d, found:%d", inputSize,
matchingElements);
}
static int atomicIncrement(volatile int* loc) {
#if defined(_MSC_VER)
return _InterlockedIncrement((volatile long*)loc);
#elif defined(__GNUC__)
return __sync_fetch_and_add(loc, 1);
#endif
printf("Atomic increment not supported, aborting...");
std::abort();
return 0;
}
void OCLSVM::runPlatformAtomics() {
if (!(svmCaps_ & CL_DEVICE_SVM_ATOMICS)) {
printf("SVM atomics not supported, skipping test...\n");
return;
}
volatile int* value = (volatile int*)clSVMAlloc(
context_, CL_MEM_SVM_FINE_GRAIN_BUFFER | CL_MEM_SVM_ATOMICS, sizeof(int), 0);
CHECK_RESULT(!value, "clSVMAlloc() failed");
*value = 0;
const int numIterations = 1000000;
error_ = clSetKernelArgSVMPointer(kernel_, 0, (const void*)value);
CHECK_ERROR(error_, "clSetKernelArgSVMPointer() failed");
error_ = clSetKernelArg(kernel_, 1, sizeof(numIterations), &numIterations);
CHECK_ERROR(error_, "clSetKernelArg() failed");
size_t gws[1] = {1};
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL, gws, NULL, 0,
NULL, NULL);
CHECK_ERROR(error_, "clEnqueueNDRangeKernel() failed");
for (int i = 0; i < numIterations; i++) {
atomicIncrement(value);
}
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_ERROR(error_, "Queue::finish() failed");
int expected = numIterations * 2;
CHECK_RESULT(*value != expected, "Expected: %d, found:%d", expected, *value);
clSVMFree(context_, (void*)value);
}
void OCLSVM::runEnqueueOperations() {
size_t numElements = 32;
size_t size = numElements * 4;
int* ptr0 = (int*)clSVMAlloc(context_, 0, size, 0);
CHECK_RESULT(!ptr0, "clSVMAlloc() failed");
int* ptr1 = (int*)clSVMAlloc(context_, 0, size, 0);
CHECK_RESULT(!ptr1, "clSVMAlloc() failed");
cl_event userEvent = clCreateUserEvent(context_, &error_);
CHECK_ERROR(error_, "clCreateUserEvent() failed");
cl_command_queue queue = cmdQueues_[_deviceId];
// coarse-grained buffer semantics: the SVM pointer needs to be mapped
// before the pointer can write to it
error_ = clEnqueueSVMMap(queue, CL_TRUE, CL_MAP_WRITE, ptr0, size, 0, NULL, NULL);
CHECK_ERROR(error_, "clEnqueueSVMMap() failed");
std::fill(ptr0, ptr0 + numElements, 1);
error_ = clEnqueueSVMUnmap(queue, ptr0, 0, NULL, NULL);
CHECK_ERROR(error_, "clEnqueueSVMUnmap() failed");
// we copy the 1st buffer into the 2nd buffer
error_ = clEnqueueSVMMemcpy(queue, true, ptr1, ptr0, size, 0, NULL, NULL);
CHECK_ERROR(error_, "clEnqueueSVMMemcpy() failed");
// verification: the 2nd buffer should be identical to the 1st
error_ = clEnqueueSVMMap(queue, CL_TRUE, CL_MAP_READ, ptr1, size, 0, NULL, &userEvent);
CHECK_ERROR(error_, "clEnqueueSVMMap() failed");
error_ = clWaitForEvents(1, &userEvent);
CHECK_ERROR(error_, "clWaitForEvents() failed");
size_t observed = std::count(ptr1, ptr1 + numElements, 1);
size_t expected = numElements;
CHECK_RESULT(observed != expected, "Expected: %zd, found:%zd", expected, observed);
void* ptrs[2] = {ptr0, ptr1};
error_ = clEnqueueSVMFree(queue, countOf(ptrs), ptrs, NULL, NULL, 0, NULL, NULL);
CHECK_ERROR(error_, "clEnqueueSVMFree() failed");
error_ = clFinish(queue);
CHECK_ERROR(error_, "clFinish() failed");
}
/**
* Simple test to ensure that SVM pointer arguments are identified properly in
* the runtime, since kernel arguments of pointer type can be bound to either
* SVM pointers or cl_mem objects.
*/
void OCLSVM::runSvmArgumentsAreRecognized() {
cl_int8 arg0;
error_ = clSetKernelArg(kernel_, 0, sizeof(arg0), &arg0);
CHECK_ERROR(error_, "clSetKernelArg() failed");
error_ = clSetKernelArgSVMPointer(kernel_, 1, NULL);
CHECK_ERROR(error_, "clSetKernelArgSVMPointer() failed");
cl_int arg2;
error_ = clSetKernelArg(kernel_, 2, sizeof(arg2), &arg2);
CHECK_ERROR(error_, "clSetKernelArg() failed");
error_ = clSetKernelArgSVMPointer(kernel_, 3, NULL);
CHECK_ERROR(error_, "clSetKernelArgSVMPointer() failed");
cl_mem arg4 = NULL;
error_ = clSetKernelArg(kernel_, 4, sizeof(arg4), &arg4);
CHECK_ERROR(error_, "clSetKernelArg() failed");
size_t gws[1] = {1};
// run dummy kernel
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL, gws, NULL, 0,
NULL, NULL);
CHECK_ERROR(error_, "clEnqueueNDRangeKernel() failed");
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_ERROR(error_, "Queue::finish() failed");
// now we bind a pointer argument to a standard buffer instead of a SVM one
cl_mem buffer = NULL;
error_ = clSetKernelArg(kernel_, 1, sizeof(buffer), &buffer);
CHECK_ERROR(error_, "clSetKernelArg() failed");
// re-execute the dummy kernel using different actual parameters
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL, gws, NULL, 0,
NULL, NULL);
CHECK_ERROR(error_, "clEnqueueNDRangeKernel() failed");
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_ERROR(error_, "Queue::finish() failed");
}
void OCLSVM::runSvmCommandsExecutedInOrder() {
#if EMU_ENV
// Small number is enough to verify functionality in Emu environment
const int numElements = 5000;
#else
const int numElements = 100000;
#endif // EMU_ENV
size_t size = numElements * sizeof(int);
// allocate SVM memory
int* data = (int*)clSVMAlloc(context_, CL_MEM_READ_WRITE, size, 0);
CHECK_RESULT(!data, "clSVMAlloc failed");
// map the SVM buffer to host
cl_int status =
clEnqueueSVMMap(cmdQueues_[_deviceId], CL_TRUE, CL_MAP_WRITE, data, size, 0, NULL, NULL);
CHECK_ERROR(status, "Error when mapping SVM buffer");
// fill buffer with 0s
std::fill(data, data + numElements, 0);
// unmap the SVM buffer to host
status = clEnqueueSVMUnmap(cmdQueues_[_deviceId], data, 0, NULL, NULL);
CHECK_ERROR(status, "Error when unmapping SVM buffer");
// enqueue kernel
status = clSetKernelArgSVMPointer(kernel_, 0, data);
CHECK_ERROR(status, "Error when setting kernel argument");
status = clSetKernelArg(kernel_, 1, sizeof(int), &numElements);
CHECK_ERROR(status, "clSetKernelArg() failed");
cl_event event;
size_t overallSize = (size_t)numElements;
status = clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL, &overallSize, NULL, 0,
NULL, &event);
CHECK_ERROR(status, "Error when enqueuing kernel");
error_ = clFinish(cmdQueues_[_deviceId]);
CHECK_ERROR(status, "clFinish()");
// map the SVM buffer to host
status = clEnqueueSVMMap(cmdQueues_[_deviceId], CL_TRUE, CL_MAP_READ, data, size, 0, NULL, NULL);
CHECK_ERROR(status, "Error when mapping SVM buffer");
bool pass = true;
// verify the data. Using descending order might increase the chance of
// finding an error since the GPU (when used) might not have finished
// updating the data array by the time we do the verification
for (int i = numElements - 1; i >= 0; i--) {
if (data[i] != numElements + 1) {
pass = false;
break;
}
}
// unmap the SVM buffer to host
status = clEnqueueSVMUnmap(cmdQueues_[_deviceId], data, 0, NULL, NULL);
CHECK_ERROR(status, "Error when unmapping SVM buffer");
// free the SVM buffer
status = clEnqueueSVMFree(cmdQueues_[_deviceId], 1, (void**)&data, NULL, NULL, 0, NULL, NULL);
CHECK_ERROR(status, "Error when freeing the SVM buffer");
error_ = clFinish(cmdQueues_[_deviceId]);
CHECK_ERROR(error_, "clFinish() failed");
CHECK_RESULT(!pass, "Wrong result");
}
void OCLSVM::runIdentifySvmBuffers() {
size_t size = 1024 * 1024;
// dummy allocation to force the runtime to track several SVM buffers
clSVMAlloc(context_, CL_MEM_READ_WRITE, size * 10, 0);
void* ptr = clSVMAlloc(context_, CL_MEM_READ_WRITE, size, 0);
cl_int status;
cl_bool usesSVMpointer = CL_FALSE;
// dummy allocation to force the runtime to track several SVM buffers
clSVMAlloc(context_, CL_MEM_READ_WRITE, size * 4, 0);
// buffer using the entire SVM region should be identified as such
cl_mem buf1 = clCreateBuffer(context_, CL_MEM_USE_HOST_PTR, size, ptr, &status);
CHECK_ERROR(status, "clCreateBuffer failed.");
size_t paramSize = 0;
status = clGetMemObjectInfo(buf1, CL_MEM_USES_SVM_POINTER, 0, 0, &paramSize);
CHECK_ERROR(status, "clGetMemObjectInfo failed");
CHECK_RESULT(paramSize != sizeof(cl_bool),
"clGetMemObjectInfo(CL_MEM_USES_SVM_POINTER) "
"returned wrong size.");
status = clGetMemObjectInfo(buf1, CL_MEM_USES_SVM_POINTER, sizeof(cl_bool), &usesSVMpointer, 0);
CHECK_ERROR(status, "clGetMemObjectInfo failed");
CHECK_RESULT(usesSVMpointer != CL_TRUE,
"clGetMemObjectInfo(CL_MEM_USES_SVM_POINTER) "
"returned CL_FALSE for buffer created from SVM pointer.");
// Buffer that uses random region within SVM buffers
cl_mem buf2 =
clCreateBuffer(context_, CL_MEM_USE_HOST_PTR, 256, (char*)ptr + size - 256, &status);
CHECK_ERROR(status, "clCreateBuffer failed.");
status = clGetMemObjectInfo(buf2, CL_MEM_USES_SVM_POINTER, sizeof(cl_bool), &usesSVMpointer, 0);
CHECK_ERROR(status, "clGetMemObjectInfo failed");
CHECK_RESULT(usesSVMpointer != CL_TRUE,
"clGetMemObjectInfo(CL_MEM_USES_SVM_POINTER) "
"returned CL_FALSE for buffer created from SVM pointer.");
// for any other pointer the query should return false
void* randomPtr = malloc(size);
cl_mem buf3 = clCreateBuffer(context_, CL_MEM_USE_HOST_PTR, size, randomPtr, &status);
CHECK_ERROR(status, "clCreateBuffer failed.");
status = clGetMemObjectInfo(buf3, CL_MEM_USES_SVM_POINTER, sizeof(cl_bool), &usesSVMpointer, 0);
CHECK_ERROR(status, "clGetMemObjectInfo failed");
CHECK_RESULT(usesSVMpointer == CL_TRUE,
"clGetMemObjectInfo(CL_MEM_USES_SVM_POINTER) "
"returned CL_TRUE for buffer not created from SVM pointer.");
clReleaseMemObject(buf3);
clReleaseMemObject(buf2);
clReleaseMemObject(buf1);
clSVMFree(context_, ptr);
}
#endif
cl_bool OCLSVM::isOpenClSvmAvailable(cl_device_id device_id) {
#ifdef CL_VERSION_2_0
error_ = clGetDeviceInfo(devices_[_deviceId], CL_DEVICE_SVM_CAPABILITIES, sizeof(svmCaps_),
&svmCaps_, NULL);
CHECK_ERROR_NO_RETURN(error_, "clGetDeviceInfo() failed");
if (!(svmCaps_ & CL_DEVICE_SVM_COARSE_GRAIN_BUFFER)) {
return CL_FALSE;
} else {
return CL_TRUE;
}
#endif
// -Device does not support OpenCL >= 2.0
// -Device supports OpenCL >= 2.0, but available headers are <= 1.2
return CL_FALSE;
}
void OCLSVM::run() {
if (!isOpenClSvmAvailable(devices_[_deviceId])) {
printf("Device does not support any SVM features, skipping...\n");
return;
}
if (_openTest == 0) {
runFineGrainedBuffer();
} else if (_openTest == 1) {
runFineGrainedSystem();
} else if (_openTest == 2) {
runFineGrainedSystemLargeAllocations();
} else if (_openTest == 3) {
runLinkedListSearchUsingFineGrainedSystem();
} else if (_openTest == 4) {
runPlatformAtomics();
} else if (_openTest == 5) {
runEnqueueOperations();
} else if (_openTest == 6) {
runSvmArgumentsAreRecognized();
} else if (_openTest == 7) {
runSvmCommandsExecutedInOrder();
} else if (_openTest == 8) {
runIdentifySvmBuffers();
}
}
unsigned int OCLSVM::close(void) { return OCLTestImp::close(); }