Question about cudaMemcpy2D

Hello,
i am trying to transfer a 2d array from cpu to gpu with cudaMemcpy2D. When i declare the 2d array statically my code works great. But when i declare it dynamically, as a double pointer, my array is not correctly transfered.
Is there any way that i can transfer a dynamically declared 2d array with cudaMemcpy2D?

Thank you in advance!

no

for a writeup on various approaches to handling double-pointer arrays, this may be a raasonable summary:

https://stackoverflow.com/questions/45643682/cuda-using-2d-and-3d-arrays

Your “double pointer” array is not a 2D array, i.e. a single contiguous allocation. You have not shown any code, but your so-called array is presumably a vector of pointers to separately allocated row vectors or column vectors (depending on whether you are using row major or column major storage convention).

You can keep this arrangement if you want, and copy this data structure one row vector or column vector at a time, just as you would do in regular C++. But this pseudo 2D array is not a high-performance data structure, and if you plan to use any sort of BLAS library (including CUBLAS) to manipulate the data, you will need to use a proper 2D array.

Here is a worked example of working with a vector-of-pointers-to-row-vectors pseudo matrix (as I said, not recommended):

#include <cstdio>
#include <cstdlib>
#include <complex>
#include "cuComplex.h"

#define N  (2)
#define M  (3)

typedef std::complex<float> T;

__global__ void print_device_matrix (cuComplex** mat)
{
    printf ("matrix on device:\n");
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            printf ("(%f, %f)  ", cuCrealf (mat[i][j]), cuCimagf (mat[i][j]));
        }
        printf ("\n");
    }
}

int main (void)
{
    /* allocate host "matrix" */
    T **mat = (T**)malloc (N * sizeof (mat[0]));
    for (int i = 0; i < N; i++) {
        mat[i] = (T *)malloc (M * sizeof (mat[0][0]));
    }
    
    /* fill in host "matrix" */
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            mat[i][j] = T (float(i)+1, float(j)+1);
        }
    }

    /* print host "matrix" */
    printf ("matrix on host:\n");
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            printf ("(%f, %f)  ", real(mat[i][j]), imag(mat[i][j]));
        }
        printf ("\n");
    }

    /* allocate device "matrix" */
    T **tmp = (T**)malloc (N * sizeof (tmp[0]));
    for (int i = 0; i < N; i++) {
        cudaMalloc ((void **)&tmp[i], M * sizeof (tmp[0][0]));
    }
    cuComplex **matD = 0;
    cudaMalloc ((void **)&matD, N * sizeof (matD[0]));

    /* copy "matrix" from host to device */
    cudaMemcpy (matD, tmp, N * sizeof (matD[0]), cudaMemcpyHostToDevice);
    for (int i = 0; i < N; i++) {
        cudaMemcpy (tmp[i], mat[i], M * sizeof (matD[0][0]), cudaMemcpyHostToDevice);
    }
    free (tmp);

    /* print device "matrix" */
    print_device_matrix<<<1,1>>> (matD);

    /* free host "matrix" */
    for (int i = 0; i < N; i++) {
        free (mat[i]);
    }
    free (mat);
    
    /* free device "matrix" */
    tmp = (T**)malloc (N * sizeof (tmp[0]));
    cudaMemcpy (tmp, matD, N * sizeof (matD[0]), cudaMemcpyDeviceToHost);
    for (int i = 0; i < N; i++) {
        cudaFree (tmp[i]);
    }
    free (tmp);
    cudaFree (matD);

    return EXIT_SUCCESS;
}

Thank you very much!