"expression must be a modifiable lvalue"

My Code …

for ( i = 0 ; i < NP_CUDA ; i++ ) {

		pswap_cu = curpop_cu[i];

		curpop_cu[i] = nxtpop_cu[i];

		nxtpop_cu[i] = pswap_cu; 

}

I get an error “expression must be a modifiable lvalue” in the lines

		curpop_cu[i] = nxtpop_cu[i];

		nxtpop_cu[i] = pswap_cu; 

And I declare variable

device double* pswap_cu;

device double curpop_cu[100][10];

device double nxtpop_cu[100][10];

Please give me answer…

Neither curpop_cu or nxtpop_cu are arrays of pointers. You cannot use pointer interchange like that.

How should I do? Please advise me…

Sorry, I can’t answer that based on the 8 lines of code you have shown. The basic problem is that

__device__ double nxtpop_cu[100][10];

is not the same as this:

__device__ double * nxtpop_cu[100];

Your code is trying to use the first version like it was declared as the second version. That isn’t possible.

[quote name=‘avidday’ post=‘998981’ date=‘Feb 11 2010, 03:31 AM’]

Sorry, I can’t answer that based on the 8 lines of code you have shown. The basic problem is that

[codebox]__constant__ int NP_CUDA = 100;

constant int maxnfc_CUDA = 100000;

constant int maxrun_CUDA = 100;

constant int D_CUDA = 10;

constant int F_CUDA = 0.5;

constant int CR_CUDA = 0.9;

device double pswap_cu;

device double trial_cost; // f. of the trial vector

device double mincost = 0;

device double cost[MAXPOP]; // objective function values (f.)

device double best[MAXDIM], bestit[MAXDIM];

device double *x_d;

device double *curpop_cu[MAXPOP];

device double *nxtpop_cu[MAXPOP];

device long lseed_cu = -1234;

device int imin = 0; // index to member with the best cost (obj. func. val.)

device int gen = 0; //Generation[/codebox]

[codebox]global void deCUDA(double* mincost_CU)

{

double temp[100];

int	target, d, i, m=0,n; 

	

reset_de();

nfc = 0;

logc = 0;

for ( gen = 1 ; nfc <= maxnfc_CUDA ; gen++ ) {      

            imin = 0;

            for ( target = 0 ; target < NP_CUDA; target++ ) {     

		differential_mutation(target);                            // For display value to console

		for ( d = 0; d < D_CUDA; d++) {

			if ( x_d[d] < low[d] )

				x_d[d] = randreal_CUDA ( low[d], 0.005*(hi[d]-low[d]) );

			else if ( x_d[d] > hi[d] ) {

				double space = 0.005 * ( hi[d] - low[d] );

				x_d[d] = randreal_CUDA( hi[d] - space, space );

			}

		}

					

               trial_cost = DEevaluate(x_d);

		

                  if (trial_cost <= cost[target]) { 

			cost[target] = trial_cost;

                        dcopy_CUDA(D_CUDA, nxtpop_cu[target], x);

if ( trial_cost < mincost ) { // Was this a new minimum?

                               mincost = trial_cost;     // If so, set mincost to new low.

                               imin = target;

                               dcopy_CUDA(D_CUDA, best, x_d);

                        }

                    } else {  

                            dcopy_CUDA(D_CUDA, nxtpop_cu[target], curpop_cu[target]);

                    }            

        }

dcopy_CUDA(D_CUDA, bestit, best); // Save best member of the current gen.

	for ( i = 0 ; i < NP_CUDA ; i++ ) {

		pswap_cu = curpop_cu[i];

		curpop_cu[i] = nxtpop_cu[i];

		nxtpop_cu[i] = pswap_cu; // swap pop. for next gen.

	}

	if(nfc == maxnfc_CUDA){

		temp[m] = mincost;

		m++;

	}		

}

nrun++;

putchar('\n');



for(int f=0 ; f<maxrun_CUDA ; f++){

	mincost_CU[f] = temp[f];

}

}[/codebox]

[codebox]device void differential_mutation(int target)

{

int n, L;

int r1, r2, r3;     



do r1 = (int)(unirandom_cu()*NP_CUDA); while (r1==target);

do r2 = (int)(unirandom_cu()*NP_CUDA); while (r2==target || r2==r1); 

do r3 = (int)(unirandom_cu()*NP_CUDA); while (r3==target || r3==r1 || r3==r2);

dcopy_CUDA(D_CUDA, x_d, curpop_cu[target]);

    n = (int)( unirandom_cu() * D_CUDA );

	for ( L = 0 ; L < D_CUDA ; L++ ) {

        if ( unirandom_cu() < CR_CUDA || L == D_CUDA-1 ) /* change at least 1 parameter */

        	x_d[n] = curpop_cu[r1][n] + F_CUDA*( curpop_cu[r2][n] - curpop_cu[r3][n] );

        n = ( n + 1 ) % D_CUDA;

    }

}[/codebox]

[codebox]device void reset_de(){

int n, d;



// Initialize population

for ( n = 0; n < NP_CUDA; n++ ) {

   for ( d = 0; d < D_CUDA; d++ )

        curpop_cu[n][d] = randreal_CUDA(low[d], hi[d]);

    cost[n] = DEevaluate(curpop_cu[n]);  // Calculate cost value

}

// Find the best individual at startup

imin = 0;

mincost = cost[0];

for ( n = 1; n < NP_CUDA; n++ )   // collect mincost

   if ( cost[n] < mincost ) {

       mincost = cost[n];

       imin = n;

   }

dcopy_CUDA(D_CUDA, best,   curpop_cu[imin]);  // save best member ever

    dcopy_CUDA(D_CUDA, bestit, curpop_cu[imin]);  // save best member of generation

}[/codebox]

I choose some part to show, ans this get an error

a value of type “double” cannot be assigned to an entity of type "double *

in red lines.

Help me please… Thank you.

I think that you should change

device double pswap_cu;

to

device double *pswap_cu;

because curpop_cu and nxtpop_cu are pointer arrays.

Yeah!! I change it.

Now, when I debug program, it stop at the red line, How should I do ?

[codebox]

device void reset_de(){

int n, d;



// Initialize population

for ( n = 0; n < NP_CUDA; n++ ) {

   for ( d = 0; d < D_CUDA; d++ )

        curpop_cu[n][d] = randreal_CUDA(low[d], hi[d]);

    cost[n] = DEevaluate(curpop_cu[n]);  // Calculate cost value

}

// Find the best individual at startup

imin = 0;

mincost = cost[0];

for ( n = 1; n < NP_CUDA; n++ )   // collect mincost

   if ( cost[n] < mincost ) {

       mincost = cost[n];

       imin = n;

   }

dcopy_CUDA(D_CUDA, best,   curpop_cu[imin]);  // save best member ever

    dcopy_CUDA(D_CUDA, bestit, curpop_cu[imin]);  // save best member of generation

}

[/codebox]

I am going to guess that you have not done any memory allocation to curpop_cu.

This might sound a little bit impolite, so pardon me in advance, but none of these problems have anything to do with CUDA. They are C language issues which seem to stem from a lack of understanding of pointers and memory management in C. You might be better served by getting some reading material on C programming and working through it first. Trying to program parallel algorithms in CUDA when you don’t actually understand the language you are programming in is not easy, as you are obviously finding out.

Thanks for your advise.

My concept about CUDA is programming parallel algorithm, so I have algorithm, which is running up to 100 rounds. I think I want to run this code up to 100 rounds in CUDA. I will program DE as parallel programming to run it 100 rounds at the same time.

And this is the code to call DE algorithm in CUDA

[codebox]

threadsPerBlock = (1,100);

threadsPerGrid = (1,1);

deCUDA<<<threadsPerGrid, threadsPerBlock>>>(mincost_p);

[/codebox]

Do I understand it correctly ? If I’m not… Please give me your idea.

P.S. sorry, I’m a newbie in CUDA programming and my English skills are very weak.

Running only one block is a pretty poor use of resources. Ideally you would want more than one block per multiprocessor, so that if you had a GT200 class GPU you would use at least 60 blocks. Using 100 threads per block and 1 block, your program would be using less than 3% of the total capacity of a GT200 GPU. Which doesn’t sound like a recipe for very good performance to me.

If that is really the scale of your problem, then you should look at a different algorithm which can much more finely divide the total workload so it can be parallelized over many more threads. Otherwise you are probably wasting your time using CUDA - a well optimized CPU implementation running on a fast, multicore CPU will probably be faster.

Now… I improve my project. I increase workload run it up to 500 rounds, maxnfc (incode) up to 1,000,000 , NP up to 200 and D up to 100. But CUDA is slower than CPU. I’m so sad. It’s running only one block. I don’t know to manage it.

This is my project, The goal of my project is processing time of CUDA must faster than processing time of CPU. So I’ll try to develope my CUDA program to faster than CPU. Please give me your advise.

If you want to see my full project in C language, you can download is attached file.

The important method is de().
Project.zip (33.3 KB)

Please help me…