es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué mi parámetros de copia de matriz 2D están siendo rechazados por la API del controlador?

Estoy intentando usar la API del controlador CUDA para copiar datos en una matriz 2D, en el programa enumerado a continuación, pero obtengo un error de “valor inválido” cuando paso mis parámetros de copia. ¿Qué valor en ellos está mal?

“`lang-cuda
#include <cuda.h>
#include <iostream>
#include <iomanip>
#include <numeric>
#include <limits>
#include <cstring>

[[noreturn]] void die(const std::string& message) {
std::cerr << message << "\n";
exit(EXIT_FAILURE);
}

void dieiferror(CUresult status, const std::string& extra_message) {
if (status != CUDA_SUCCESS) {
const char* error_string;
cuGetErrorString(status, &error_string);
die(extra_message + ": " + error_string);
}
}

template <typename t="void">
T* as_pointer(CUdeviceptr address) noexcept { return reinterpret_cast<t*>(address); }

CUdeviceptr as_address(void* ptr) noexcept { return reinterpret_cast<cudeviceptr>(ptr); }

int main() {
CUresult status;
int device_id = 0;
status = cuInit(0);
dieiferror(status, "Inicializando el controlador CUDA");
CUcontext pctx;
status = cuDevicePrimaryCtxRetain(&pctx, device_id);
dieiferror(status, "Obteniendo el contexto del dispositivo principal");
cuCtxSetCurrent(pctx);
struct { unsigned width, height; } dims = { 3, 3 };
std::cout << "Creando una matriz CUDA " << dims.width << " x " << dims.height << std::endl;
CUarray arr_handle;
{
CUDA_ARRAY_DESCRIPTOR array_descriptor;
array_descriptor.Width = dims.width;
array_descriptor.Height = dims.height;
array_descriptor.Format = CU_AD_FORMAT_FLOAT;
array_descriptor.NumChannels = 1;
status = cuArrayCreate(&arr_handle, &array_descriptor);
dieiferror(status, "Error al crear una matriz CUDA 2D");
}
auto arr_size = dims.width * dims.height;
CUdeviceptr dptr;
status = cuMemAllocManaged(&dptr, arr_size, CU_MEM_ATTACH_GLOBAL);
dieiferror(status, "Error al asignar memoria administrada");
float* ptr_in = as_pointer<float>(dptr);
std::iota(ptr_in, ptr_in + arr_size, 0);
CUmemorytype ptr_in_memory_type;
status = cuPointerGetAttribute(&ptr_in_memory_type, CU_POINTER_ATTRIBUTE_MEMORY_TYPE, as_address(ptr_in));
if (not (ptr_in_memory_type == CU_MEMORYTYPE_UNIFIED or ptr_in_memory_type == CU_MEMORYTYPE_DEVICE)) {
die("Tipo de memoria inesperado para ptr_in");
}
std::cout << "El tipo de memoria de ptr_in es " << (ptr_in_memory_type == CU_MEMORYTYPE_DEVICE ? "DEVICE" : "UNIFIED") << std::endl;
std::cout << "Copiaré de ptr_in a una matriz CUDA 2D" << std::endl;

CUDA_MEMCPY2D cp;
{
// Origen

<pre><code>cp.srcXInBytes = 0; cp.srcY = 0; // Sin desplazamiento
cp.srcMemoryType = ptr_in_memory_type;
cp.srcDevice = as_address(ptr_in);
// sin paso de origen adicional
cp.srcPitch = dims.width * sizeof(float);

// Destino

cp.dstXInBytes = 0; cp.dstY = 0; // Sin desplazamiento de destino
cp.dstMemoryType = CU_MEMORYTYPE_ARRAY;
cp.dstArray = arr_handle;

cp.WidthInBytes = dims.width * sizeof(float);
cp.Height = dims.height;
</code></pre>

}

status = cuMemcpy2D(&cp);
dieiferror(status, "Error en cuMemcpy2D");
cuMemFree(as_address(ptr_in));
}
“`</t*></cuda.h>

Tags:  ,

Answer

  1. Avatar for davy.ai

    El valor incorrecto en los parámetros de la copia es cp.srcPitch, el cual está establecido en dims.width * sizeof(float), pero debería establecerse en dims.width * sizeof(float) redondeado hacia arriba al múltiplo más cercano de 256 bytes. Esto se debe a que CUDA requiere alineación de espacios para ciertos accesos a la memoria para asegurar patrones de acceso de memoria óptimos. Por lo tanto, cambiar la línea cp.srcPitch = dims.width * sizeof(float); a cp.srcPitch = (dims.width * sizeof(float) + 255) & ~255; debería resolver el error de “argumento inválido”.

Comments are closed.