int main()
{
  float f = sum_float(1, 2);
  double d = sum_double(1, 2);
  return f == d;
}
int main()
{
   int start,stride,rmlast,rstride,np_aset,inset,lpe;
   int my_pe,n_pes;
   int i,fail,n_err,asfail,nasfail;
   char Case[40];
   
   static double sSource_double[NREDUCE];
   static double sTarget_double[NREDUCE];
   static double spWrk_double[PWRKELEM];
   
   static long spSync[_SHMEM_REDUCE_SYNC_SIZE];


   shmem_init();
   my_pe = shmem_my_pe();
   n_pes = shmem_n_pes();
   lpe=my_pe;

   dpSync=shmem_malloc(_SHMEM_REDUCE_SYNC_SIZE*sizeof(long));
   for(i=0;i<_SHMEM_REDUCE_SYNC_SIZE;i++) {
      gpSync[i]=_SHMEM_SYNC_VALUE;
      dpSync[i]=_SHMEM_SYNC_VALUE;
      spSync[i]=_SHMEM_SYNC_VALUE;
   }
      
   dSource_double=shmem_malloc(NREDUCE*sizeof(double));
   dTarget_double=shmem_malloc(NREDUCE*sizeof(double));
   dpWrk_double=shmem_malloc((NREDUCE/2+1 > _SHMEM_REDUCE_MIN_WRKDATA_SIZE ? NREDUCE/2+1 : _SHMEM_REDUCE_MIN_WRKDATA_SIZE)*sizeof(double));

   for(start=0;start<=MAXSTART;start++) {
      rstride=1; 
      for(stride=0;stride<=MAXSTRIDE;stride++) {
         for(rmlast=0;rmlast<=MAXRMLAST;rmlast++)
	 {
	    np_aset=(n_pes+rstride-1-start)/rstride-rmlast; /* number of processes in the active set */
	    if(np_aset > 0) /* if active set is not empty */
	    {
	       if(my_pe==0) printf("\nActive set triplet: PE_start=%d,logPE_stride=%d,PE_size=%d \n",start,stride,np_aset);
	       if((my_pe>=start) && ((my_pe-start)%rstride==0) && ((my_pe-start)/rstride<np_aset)) inset=1;
	       else inset=0;

/* Initialize Source and Target arrays */
	       for(i=0;i<NREDUCE;i++) {
                  sSource_double[i]=SINIT;
                  sTarget_double[i]=TINIT;
                  gSource_double[i]=SINIT;
                  gTarget_double[i]=TINIT;
                  dSource_double[i]=SINIT;
                  dTarget_double[i]=TINIT;
	       }
               shmem_barrier_all();

/* CASE: static arrays, source is different from target */
               sprintf(Case,"static, source!=target");
	       if(inset) 
	          asfail=sum_double(sSource_double,sTarget_double,start,stride,np_aset,rstride,0,dpWrk_double,gpSync,Case);
	       else {	/* check that values of source and target have not been changed */
	          nasfail+=check_sval_notchanged(sSource_double,Case);
		  nasfail+=check_tval_notchanged(sTarget_double,Case);
	       }
		  
	       
/* CASE: global arrays, source is different from target */
               sprintf(Case,"global, source!=target");
	       if(inset)
                  asfail=sum_double(gSource_double,gTarget_double,start,stride,np_aset,rstride,0,spWrk_double,dpSync,Case);
	       else {	/* check that values of source and target have not been changed */
	          nasfail+=check_sval_notchanged(gSource_double,Case);
		  nasfail+=check_tval_notchanged(gTarget_double,Case);
	       }
	       
/* CASE: symmetric heap arrays, source is different from target */
               sprintf(Case,"sym heap, source!=target");
	       if(inset)
                  asfail=sum_double(dSource_double,dTarget_double,start,stride,np_aset,rstride,0,gpWrk_double,spSync,Case);
	       else {	/* check that values of source and target have not been changed */
	          nasfail+=check_sval_notchanged(dSource_double,Case);
		  nasfail+=check_tval_notchanged(dTarget_double,Case);
	       }
	       

/* Reinitialize Source arrays for new tests */
	       for(i=0;i<NREDUCE;i++) {
                  sSource_double[i]=SINIT;
                  gSource_double[i]=SINIT;
                  dSource_double[i]=SINIT;
	       }
               shmem_barrier_all();

/* CASE: static arrays, source and target are the same array */
               sprintf(Case,"static, source==target");
	       if(inset)
                  asfail=sum_double(sSource_double,sSource_double,start,stride,np_aset,rstride,1,gpWrk_double,dpSync,Case);
	       else 	/* check that values of source have not been changed */
	          nasfail+=check_sval_notchanged(sSource_double,Case);

/* CASE: global arrays, source and target are the same array */
               sprintf(Case,"global, source==target");
	       if(inset)
                  asfail=sum_double(gSource_double,gSource_double,start,stride,np_aset,rstride,1,dpWrk_double,spSync,Case);
	       else 	/* check that values of source have not been changed */
	          nasfail+=check_sval_notchanged(gSource_double,Case);

/* CASE: symmetric heap arrays, source and target are the same array */
               sprintf(Case,"sym heap, source==target");
	       if(inset)
                  asfail=sum_double(dSource_double,dSource_double,start,stride,np_aset,rstride,1,spWrk_double,gpSync,Case);
	       else 	/* check that values of source have not been changed */
	          nasfail+=check_sval_notchanged(dSource_double,Case);

	       
	    }	/* end of if active set is not empty */
	 } 	/* end of for loop on rmlast */
	 rstride*=2;
      } 	/* end of for loop on stride */
   } 		/* end of for loop on start */

   shmem_barrier_all();  
#ifdef NEEDS_FINALIZE
   shmem_finalize();
#endif
   return(0);
}