KhronosGroup / KhronosGroup/OpenCL-CLHPP

Problem using SVMAllocator with multiple Context

Open
#144 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
425
Forks
133
Avg merge
3h 30m
Merged PRs (30d)
1

Description

Hi, I'm trying to use `cl::SVMAllocator` on two different platforms and encounter some problems. I created two `cl::Context` and construct `cl::coarse_svm_vector` using the following code:

```C++
#include
#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_TARGET_OPENCL_VERSION 200
#include

int main()
{
std::vector platforms;
cl::Platform::get(&platforms);
cl::Platform platform_0 = platforms[0], platform_1 = platforms[1];
std::vector devices;
platform_0.getDevices(CL_DEVICE_TYPE_ALL, &devices);
cl::Device device_0 = devices[0];
platform_1.getDevices(CL_DEVICE_TYPE_ALL, &devices);
cl::Device device_1 = devices[0];
cl::Context context_0(device_0), context_1(device_1);
// cl::Context::setDefault(context_0);
cl::SVMAllocator> alloc_0(context_0), alloc_1(context_1);
const int n = 10;
cl::coarse_svm_vector vec_0(n, 0, alloc_0);
std::cerr << "Debug 0" << std::endl;
cl::coarse_svm_vector vec_1(n, 1, alloc_1);
std::cerr << "Debug 1" << std::endl;
return 0;
}
```
I found that if I enable `cl::Context::setDefault`, I will get `Debug 0`, followed by a `Segmentation Fault`. Without `cl::Context::setDefault`, the program will go `Segmentation Fault` directly.

I did some investigation and found that `Segmentation Fault` is caused by `enqueueMapSVM` in `cl::SVMTraitCoarse:: allocate`:
```
#0 0x00007ffff7833424 in pthread_mutex_lock () from /usr/lib/libpthread.so.0
#1 0x00007ffff64f2fd6 in ?? () from /usr/lib/libnvidia-opencl.so.1
#2 0x000055555555cbbf in cl::CommandQueue::enqueueMapSVM (this=0x7fffffffe640, ptr=0x7fffd4400000, blocking=1, flags=3, size=40, events=0x0, event=0x0) at /usr/include/CL/opencl.hpp:8170
#3 0x000055555555c8ad in cl::enqueueMapSVM (ptr=0x7fffd4400000, blocking=1, flags=3, size=40, events=0x0, event=0x0) at /usr/include/CL/opencl.hpp:9308
#4 0x000055555555c428 in cl::SVMAllocator > >::allocate (this=0x7fffffffe860, size=10) at /usr/include/CL/opencl.hpp:3715
#5 0x000055555555bc99 in std::allocator_traits > > >::allocate (__a=..., __n=10) at /usr/include/c++/11.1.0/bits/alloc_traits.h:314
#6 0x000055555555b68e in std::_Vector_base > > >::_M_allocate (this=0x7fffffffe860, __n=10) at /usr/include/c++/11.1.0/bits/stl_vector.h:346
#7 0x000055555555aebf in std::_Vector_base > > >::_M_create_storage (this=0x7fffffffe860, __n=10) at /usr/include/c++/11.1.0/bits/stl_vector.h:361
#8 0x000055555555a299 in std::_Vector_base > > >::_Vector_base (this=0x7fffffffe860, __n=10, __a=...) at /usr/include/c++/11.1.0/bits/stl_vector.h:305
#9 0x0000555555559057 in std::vector > > >::vector (this=0x7fffffffe860, __n=10, __value=@0x7fffffffe880: 0, __a=...) at /usr/include/c++/11.1.0/bits/stl_vector.h:524
#10 0x00005555555565c0 in main () at test.cpp:20
```

In Line 3717 of `opencl.hpp`, `cl::SVMTraitCoarse:: allocate` will call `enqueueMapSVM` using default `cl::CommandQueue` no matter what `cl::Context` is passed to `cl::SVMTraitCoarse.context_`, I think maybe this is the cause of this problem:

```C++
// Line 3717
// If allocation was coarse-grained then map it
if (!(SVMTrait::getSVMMemFlags() & CL_MEM_SVM_FINE_GRAIN_BUFFER)) {
cl_int err = enqueueMapSVM(retValue, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, size*sizeof(T));
```

Now I'm wandering
1. Is there any problem using `cl::SVMAllocator` with a `cl::Context` different from default context?
2. How to use `cl::SVMAllocator` with multiple contexts correctly?

Some information about my devices:
```
Number of platforms 2
Platform Name NVIDIA CUDA
Platform Version OpenCL 3.0 CUDA 11.4.112
Device Name NVIDIA GeForce GTX 1660
Platform Name Intel(R) CPU Runtime for OpenCL(TM) Applications
Platform Version OpenCL 2.1 LINUX
Device Name AMD Ryzen 7 3700X 8-Core Processor
```

Thanks a lot for any help from anyone in advance.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at the reported opencl.hpp line 3717 in cl::SVMTraitCoarse::allocate and trace how enqueueMapSVM selects its command queue, comparing it with the allocator's context_. Reproduce the two-platform, two-context example and verify that coarse_svm_vector allocation works correctly for both contexts without relying on the default context.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.