2013-06-02 6 views
3

Я хочу использовать две мои графические карты для расчета с помощью CUDA Thrust.Использование нескольких графических процессоров с помощью CUDA Thrust

У меня есть две графические карты. Работа на одиночных картах хорошо работает для обеих карт, даже когда я храню два устройства_объектов в std :: vector.

Если я использую обе карты одновременно, первый цикл цикла работает и не вызывает ошибок. После первого запуска он вызывает ошибку, возможно, потому, что указатель устройства недействителен.

Я не уверен, в чем проблема, или как использовать обе карты для расчета.

Минимальный пример кода:

std::vector<thrust::device_vector<float> > TEST() { 
    std::vector<thrust::device_vector<float> > vRes; 

    unsigned int iDeviceCount = GetCudaDeviceCount(); 
    for(unsigned int i = 0; i < iDeviceCount; i++) { 
     checkCudaErrors(cudaSetDevice(i)); 
     thrust::host_vector<float> hvConscience(1024); 

       // first run works, runs afterwards cause errors .. 
     vRes.push_back(hvConscience); // this push_back causes the error on exec 

    } 
    return vRes; 
} 

Сообщение об ошибке на исполнение:

terminate called after throwing an instance of 'thrust::system::system_error' 
what(): invalid argument 
+0

Вы используете копию с хоста или используете хост для буферов? –

+0

Не знаю, что вы имеете в виду. Этот код копирует с хоста на устройство. – dgrat

+0

Значит, они не в режиме SLI? –

ответ

5

Проблема здесь состоит в том, что вы пытаетесь выполнить устройство для устройства копирования данных между парой device_vector которая находятся в разных контекстах графического процессора (из-за вызова cudaSetDevice). То, что вы, возможно, упускать из виду, что эта последовательность операций:

thrust::host_vector<float> hvConscience(1024); 
vRes.push_back(hvConscience); 

выполняет копию из hvConscience на каждой итерации цикла. Бэкэнд тяги ожидает, что исходная и целевая память находятся в одном и том же контексте графического процессора. В этом случае они этого не делают, поэтому ошибка.

То, что вы, вероятно, хотите сделать, это работа с вектором указателей к device_vector вместо этого, так что-то вроде:

typedef thrust::device_vector<float> vec; 
typedef vec *p_vec; 
std::vector<p_vec> vRes; 

unsigned int iDeviceCount = GetCudaDeviceCount(); 
for(unsigned int i = 0; i < iDeviceCount; i++) { 
    cudaSetDevice(i); 
    p_vec hvConscience = new vec(1024); 
    vRes.push_back(hvConscience); 
} 

[отказ от ответственности: код, написанный в браузере, ни скомпилирован, ни испытания, мы по собственному риск]

Таким образом, вы создаете только каждый вектор один раз, в правильном контексте графического объекта, а затем копируете назначение указателя узла, который не вызывает никаких копий на стороне устройства во всех пространствах памяти.

Смежные вопросы