ThatQuantDude
ThatQuantDude

Reputation: 833

CUDA class with multidimensional pointers

I have been struggling with this class implementation now for quite a while and hope someone can help me with it.

class Material_Properties_Class_device 
{

public:
int max_variables;
Logical * table_prop;
Table_Class ** prop_table;
};

The implementation for the pointers looks like this

Material_Properties_Class **d_material_prop = new Material_Properties_Class* [4];
Logical *table_prop;

for (int k = 1; k <= 3; k++ )
{ 
cutilSafeCall(cudaMalloc((void**)&(d_material_prop[k]),sizeof(Material_Properties_Class)));  
cutilSafeCall(cudaMemcpy(d_material_prop[k], material_prop[k], sizeof(Material_Properties_Class ), cudaMemcpyHostToDevice)); 
}

for( int i = 1; i <= 3; i++ )
{   
cutilSafeCall(cudaMalloc((void**)&(table_prop), sizeof(Logical)));
cudaMemcpy(&(d_material_prop[i]->table_prop), &(table_prop), sizeof(Logical*),cudaMemcpyHostToDevice);
cudaMemcpy(table_prop, material_prop[i]->table_prop, sizeof(Logical),cudaMemcpyHostToDevice);
}

cutilSafeCall(cudaMalloc((void ***)&material_prop_device, (4) * sizeof(Material_Properties_Class *)));  
cutilSafeCall(cudaMemcpy(material_prop_device, d_material_prop, (4) * sizeof(Material_Properties_Class *), cudaMemcpyHostToDevice));

This implementation works but it can't get it working for the **prop_table. I assume it must somehow follow the same principle but I just can't get my head around it.

I have already tried

Table_Class_device **prop_table =  new Table_Class_device*[3];

and insert another loop inside the second for loop

for (int k = 1; k <= 3; k++ )
        { 
            cutilSafeCall(cudaMalloc((void**)&(prop_table[k]), sizeof(Table_Class))); 
            cutilSafeCall(cudaMemcpy( prop_table[k], material_prop[i]->prop_table[k], sizeof( Table_Class *), cudaMemcpyHostToDevice)); 
        }

Help would be much appriciated

Upvotes: 1

Views: 286

Answers (2)

T_T
T_T

Reputation: 583

some magic. May be it'll help

struct fading_coefficient
{
    double* frequency_array;
    double* temperature_array;
    int frequency_size;
    int temperature_size;
    double** fading_coefficients;
};

struct fading_coefficient* cuda_fading_coefficient;
    double* frequency_array = NULL;
    double* temperature_array = NULL;
    double** fading_coefficients = NULL;
    double** fading_coefficients1 = (double **)malloc(fading_coefficient->frequency_size * sizeof(double *));   

    cudaMalloc((void**)&frequency_array,fading_coefficient->frequency_size *sizeof(double));
    cudaMemcpy( frequency_array, fading_coefficient->frequency_array, fading_coefficient->frequency_size *sizeof(double), cudaMemcpyHostToDevice );
    free(fading_coefficient->frequency_array);

    cudaMalloc((void**)&temperature_array,fading_coefficient->temperature_size *sizeof(double));
    cudaMemcpy( temperature_array, fading_coefficient->temperature_array, fading_coefficient->temperature_size *sizeof(double), cudaMemcpyHostToDevice );
    free(fading_coefficient->temperature_array);

    cudaMalloc((void***)&fading_coefficients,fading_coefficient->temperature_size *sizeof(double*));

    for (int i = 0; i < fading_coefficient->temperature_size; i++)
    {
        cudaMalloc((void**)&(fading_coefficients1[i]),fading_coefficient->frequency_size *sizeof(double));
        cudaMemcpy( fading_coefficients1[i], fading_coefficient->fading_coefficients[i], fading_coefficient->frequency_size *sizeof(double), cudaMemcpyHostToDevice );
        free(fading_coefficient->fading_coefficients[i]);
    }
    cudaMemcpy(fading_coefficients, fading_coefficients1, fading_coefficient->temperature_size *sizeof(double*), cudaMemcpyHostToDevice );

    fading_coefficient->frequency_array = frequency_array;
    fading_coefficient->temperature_array = temperature_array;
    fading_coefficient->fading_coefficients = fading_coefficients;

    cudaMalloc((void**)&cuda_fading_coefficient,sizeof(struct fading_coefficient));
    cudaMemcpy( cuda_fading_coefficient, fading_coefficient, sizeof(struct fading_coefficient), cudaMemcpyHostToDevice );

Upvotes: 1

Robert Crovella
Robert Crovella

Reputation: 152164

This question comes up frequently. Multidimensional pointers are especially challenging.

If possible, it's recommended that you flatten multidimensional pointer usage (**) to single-dimensional pointer usage (*), and as you've seen, even that is somewhat cumbersome.

The single-dimensional case (*) is further described here. Although you seem to have already figured it out.

If you really want to handle the 2 dimensional (**) case, look here.

An example implementation for 3 dimensional case (***) is here. ("madness!")

Working with 2 and 3 dimensions this way is quite difficult. Thus the recommendation to flatten.

Upvotes: 1

Related Questions