Я столкнулся с очень странной ошибкой, заключающейся в том, что я получаю ошибку «незаконный доступ к памяти» при запуске симуляции Heat 2D определенного размера, но симуляция работает хорошо, если я запускаю точно такую же симуляцию, только с меньшим количеством элементов.
Есть ли причина, по которой увеличение размера массива вызовет это исключение? Я использую графический процессор Titan Black (6 ГБ памяти), но симуляция, которую я запускаю, и близко не соответствует этому размеру. Я подсчитал, что могу запустить симуляцию 4000 x 4000, но получаю ошибки, если превышаю 250 x 250.
Ошибка возникает сразу после того, как я создаю массив объектов моделирования на устройстве. Код инстанцирования выглядит следующим образом:
template<typename PlaceType, typename StateType>
__global__ void instantiatePlacesKernel(Place** places, StateType *state,
void *arg, int *dims, int nDims, int qty) {
unsigned idx = blockDim.x * blockIdx.x + threadIdx.x;
if (idx < qty) {
// set pointer to corresponding state object
places[idx] = new PlaceType(&(state[idx]), arg);
places[idx]->setIndex(idx);
places[idx]->setSize(dims, nDims);
}
}
template<typename PlaceType, typename StateType>
Place** DeviceConfig::instantiatePlaces(int handle, void *argument, int argSize,
int dimensions, int size[], int qty) {
// add global constants to the GPU
memcpy(glob.globalDims,size, sizeof(int) * dimensions);
updateConstants(glob);
// create places tracking
PlaceArray p; // a struct to track qty,
p.qty = qty;
// create state array on device
StateType* d_state = NULL;
int Sbytes = sizeof(StateType);
CATCH(cudaMalloc((void** ) &d_state, qty * Sbytes));
p.devState = d_state; // save device pointer
// allocate device pointers
Place** tmpPlaces = NULL;
int ptrbytes = sizeof(Place*);
CATCH(cudaMalloc((void** ) &tmpPlaces, qty * ptrbytes));
p.devPtr = tmpPlaces; // save device pointer
// handle arg if necessary
void *d_arg = NULL;
if (NULL != argument) {
CATCH(cudaMalloc((void** ) &d_arg, argSize));
CATCH(cudaMemcpy(d_arg, argument, argSize, H2D));
}
// load places dimensions
int *d_dims;
int dimBytes = sizeof(int) * dimensions;
CATCH(cudaMalloc((void** ) &d_dims, dimBytes));
CATCH(cudaMemcpy(d_dims, size, dimBytes, H2D));
// launch instantiation kernel
int blockDim = (qty - 1) / BLOCK_SIZE + 1;
int threadDim = (qty - 1) / blockDim + 1;
Logger::debug("Launching instantiation kernel");
instantiatePlacesKernel<PlaceType, StateType> <<<blockDim, threadDim>>>(tmpPlaces, d_state,
d_arg, d_dims, dimensions, qty);
CHECK();
CATCH(cudaDeviceSynchronize()); // ERROR OCCURS HERE
// clean up memory
if (NULL != argument) {
CATCH(cudaFree(d_arg));
}
CATCH(cudaFree(d_dims));
CATCH(cudaMemGetInfo(&freeMem, &allMem));
return p.devPtr;
}
Пожалуйста, предполагайте, что все пользовательские типы, которые вы видите, работают, так как этот код выполняется без ошибок при достаточно небольшом моделировании. Я разочарован тем, что количество элементов в местах функций ядра и массивах состояний вызывает ошибку, когда размер превышает 250 x 250 элементов. Любое понимание было бы потрясающим.
Благодарю вас!