He mirado todo este sitio y demás, y nada ha funcionado. Estoy de recurrir a la publicación de una pregunta para mi caso concreto.

Tengo un montón de matrices, y el objetivo es usar un kernel para permitir que el GPU a hacer la misma operación en todos ellos. Estoy bastante seguro de que puedo conseguir el kernel de trabajo, pero no puedo conseguir cudaMalloc /cudaMemcpy a trabajar.

Tengo un puntero a una estructura de Matriz, que tiene un miembro llamado de los elementos que señala algunas de las carrozas. Puedo hacer todo lo que no sean cuda mallocs bien.

Gracias por cualquier/toda la ayuda.

Código:

typedef struct {
    int width;
    int height;
    float* elements;
} Matrix;

int main void() {
    int rows, cols, numMat = 2; //These are actually determined at run-time
    Matrix* data = (Matrix*)malloc(numMat * sizeof(Matrix));

    //... Successfully read from file into "data" ...

    Matrix* d_data;
    cudaMalloc(&d_data, numMat*sizeof(Matrix)); 
    for (int i=0; i<numMat; i++){
        //The next line doesn't work
        cudaMalloc(&(d_data[i].elements), rows*cols*sizeof(float));

        //Don't know if this works
        cudaMemcpy(d_data[i].elements, data[i].elements,  rows*cols*sizeof(float)), cudaMemcpyHostToDevice);
    }

    //... Do other things ...
}

Gracias!

  • Esto no funciona de esta manera. Se han asignado d_data utilizando cudaMalloc y tratar de acceder a d_data[i] en el host que no es posible.
  • Un mejor enfoque sería asignar d_data en el host utilizando malloc y, a continuación, asignar d_data.elements en el dispositivo utilizando cudaMalloc. No está claro cómo utiliza usted la cantidad asignada a la estructura dentro del código de dispositivo.
  • Gracias @sgar91. Pero, ¿de dónde usted dice que yo estoy tratando de acceder d_data[i]?
  • Aquí en el primer argumento: cudaMemcpy(d_data[i].elements, data[i].elements, rows*cols*sizeof(float)), cudaMemcpyHostToDevice);. Tratando de acceso de dispositivo de puntero en el host.
  • En el código del dispositivo, sólo tengo que ser capaces de operar sobre los elementos de cada matriz. No he visto la asignación de estructuras de dispositivos en el host, cuyos miembros están en el dispositivo. Podría publicar un ejemplo rápido? Gracias!
  • Aquí tienes.

InformationsquelleAutor t_carn | 2013-10-16

1 Comentario

  1. 5

    Usted tiene que ser consciente de donde su memoria reside. malloc asigna la memoria principal, cudaMalloc asigna memoria en el dispositivo y devuelve un puntero a la memoria de nuevo. Sin embargo, este puntero es válida únicamente en las funciones del dispositivo.

    Lo que usted quiere puede ser logrado como sigue:

    typedef struct {
        int width;
        int height;
        float* elements;
    } Matrix;
    
    int main void() {
        int rows, cols, numMat = 2; //These are actually determined at run-time
        Matrix* data = (Matrix*)malloc(numMat * sizeof(Matrix));
    
        //... Successfully read from file into "data" ...
        Matrix* h_data = (Matrix*)malloc(numMat * sizeof(Matrix));
        memcpy(h_data, data, numMat * sizeof(Matrix);
    
        for (int i=0; i<numMat; i++){
    
            cudaMalloc(&(h_data[i].elements), rows*cols*sizeof(float));
            cudaMemcpy(h_data[i].elements, data[i].elements,  rows*cols*sizeof(float)), cudaMemcpyHostToDevice);
    
         }//matrix data is now on the gpu, now copy the "meta" data to gpu
         Matrix* d_data;
         cudaMalloc(&d_data, numMat*sizeof(Matrix)); 
         cudaMemcpy(d_data, h_data, numMat*sizeof(Matrix));
         //... Do other things ...
    }

    A poner las cosas en claro:
    Matrix* data contiene los datos en el host.
    Matrix* h_data contiene un puntero a la memoria del dispositivo en los elementos que se pueden pasar a los granos como parámetros. La memoria es en la GPU.
    Matrix* d_data está completamente en la GPU y puede utilizarse como datos en el host.

    en el código del kernel usted puede ahora tener acceso a los valores de la matriz, por ejemplo,

    __global__ void doThings(Matrix* matrices)
    {
          matrices[i].elements[0] = 42;
    }
    • gracias @kronos, voy a probar esto. Es la idea de que el «intermedio» puntero de h_data la manera estándar de hacer esto?
    • Así que depende. Representa una sobrecarga en su código de host, porque usted tiene que guardar su otra estructura de datos dos veces. Esto podría ser conduce a errores. Puedes hacer 2 cosas: pack el dispositivo punteros en una matriz y pasar la matriz de un núcleo (la matriz debe ser asignado en la memoria del dispositivo así), o agregar un campo a su estructura que sostiene el dispositivo de puntero. Con la segunda opinión puede utilizar la misma estructura en el host y el dispositivo de lado, pero el acceso a los datos del host a través de elementos y datos del dispositivo, digamos, a través de d_elements.
    • Esto es muy útil. Me pregunto si tengo que poner algo enteramente en el dispositivo todo – si se me puede llamar el núcleo con el anfitrión punteros a memoria del dispositivo. Gracias de nuevo!

Dejar respuesta

Please enter your comment!
Please enter your name here