コード例 #1
0
/*!
  Updates the interaction matrices with the image plane the camera is facing. The plane must be in the format: \f$ \frac{1}{Z}=Ax+By+C \f$ .
  The moment primitives MUST be updated before calling this function.

  This method also computes the interaction matrix. Therefore, you must call vpFeatureMoment::update before calling vpFeatureMoment::interaction.

  \attention The behaviour of this method is not the same as vpMoment::update which only acknowledges the new object. This method also computes the interaction matrices.

  \param A : A coefficient of the plane.
  \param B : B coefficient of the plane.
  \param C : C coefficient of the plane.
*/
void vpFeatureMoment::update (double A, double B, double C){
    this->A = A;
    this->B = B;
    this->C = C;

    if(moment==NULL){
        bool found;        
        this->moment = &(moments.get(momentName(),found));
        if(!found) throw ("Moment not found for feature");

    }
    nbParameters = 1;
    if(this->moment!=NULL){
        dim_s = (unsigned int)this->moment->get().size();

        s.resize(dim_s);

        for(unsigned int i=0;i<dim_s;i++)
            s[i] = this->moment->get()[i];

        if (flags == NULL)
            flags = new bool[nbParameters];
        for (unsigned int i = 0; i < nbParameters; i++)
            flags[i] = false;
    }else
        dim_s = 0;

    compute_interaction();
}
コード例 #2
0
ファイル: nbody.c プロジェクト: skattoju/nbody
void init_particles(particle* system){

/*
* particles will be placed randomly 4 quadrants of 3d space
* q1: x>0, y>0
* q2: x<0, y>0
* q3: x<0, y<0
* q4: x>0, y<0
*
*/

 int i = 0;
 srand(time(NULL));

 // q1 x>0, y>0
 for(; i < NO_OF_PARTICLES/4; i++){
   system[i].position = (__vector float){rand()%INIT_BOUNDING_BOX,
rand()%INIT_BOUNDING_BOX,
(rand()%INIT_BOUNDING_BOX*2)-INIT_BOUNDING_BOX, 0};
   system[i].velocity = VECZERO;
   system[i].acceleration = VECZERO;
 }

 // q2 x<0, y>0
 for(; i < NO_OF_PARTICLES/2; i++){
   system[i].position = (__vector float){-rand()%INIT_BOUNDING_BOX,
rand()%INIT_BOUNDING_BOX,
(rand()%INIT_BOUNDING_BOX*2)-INIT_BOUNDING_BOX, 0};
   system[i].velocity = VECZERO;
   system[i].acceleration = VECZERO;
 }

 // q3 x<0, y<0
 for(; i < 3*NO_OF_PARTICLES/4; i++){

   system[i].position = (__vector float){-rand()%INIT_BOUNDING_BOX,
-rand()%INIT_BOUNDING_BOX,
(rand()%INIT_BOUNDING_BOX*2)-INIT_BOUNDING_BOX, 0};
   system[i].velocity = VECZERO;
   system[i].acceleration = VECZERO;
 }

 // q4 x>0, y<0
 for(; i < NO_OF_PARTICLES; i++){

   system[i].position = (__vector float){rand()%INIT_BOUNDING_BOX,
-rand()%INIT_BOUNDING_BOX,
(rand()%INIT_BOUNDING_BOX*2)-INIT_BOUNDING_BOX, 0};
   system[i].velocity = VECZERO;
   system[i].acceleration = VECZERO;

 }


}

void compute_interaction(particle* i , particle* j){

 __vector float radius, radius_sqr, s_vector, displ, accel, distSqr,
distSixth, invDistCube;

 /*compute acceleration of particle i*/
 radius = vec_sub(j->position,i->position);
 radius_sqr = vec_madd(radius,radius, VECZERO);
 distSqr = vec_add(vec_splat(radius_sqr,0),vec_splat(radius_sqr,1));
 distSqr = vec_add(vec_splat(radius_sqr,2),distSqr);
 distSqr = vec_add(EPS2_VECTOR,distSqr);
 distSixth = vec_madd(distSqr,distSqr,VECZERO);
 distSixth = vec_madd(distSixth,distSqr,VEC3ZERO);
 invDistCube = vec_rsqrte(distSixth);
 s_vector = vec_madd(MASS_VECTOR,invDistCube,VECZERO);
 i->acceleration = vec_madd(radius,s_vector,i->acceleration);

 /*compute new position & velocity of particle i*/
 displ = vec_madd(i->velocity,TIME_STEP_VECTOR,i->position);
 accel = vec_madd(VECHALF,i->acceleration, VECZERO);
 i->position = vec_madd(accel,TIME_SQUARED, displ);
 i->velocity = vec_madd(i->acceleration,TIME_STEP_VECTOR, i->velocity);

}


void update_particles(particle* system){

 int i, j;

 //Thread 1 ?
 for(i = 0;i<NO_OF_PARTICLES/4;i++){
   for(j = 0;j<NO_OF_PARTICLES;j++){
     compute_interaction(&system[i],&system[j]);
   }
 }

 //Thread 2 ?
 for(i = NO_OF_PARTICLES/4;i<NO_OF_PARTICLES/2;i++){
   for(j = 0;j<NO_OF_PARTICLES;j++){
     compute_interaction(&system[i],&system[j]);
   }
 }

 //Thread 3 ?
 for(i = NO_OF_PARTICLES/2;i<3*NO_OF_PARTICLES/4;i++){
   for(j = 0;j<NO_OF_PARTICLES;j++){
     compute_interaction(&system[i],&system[j]);
   }
 }

 //Thread 4 ?
 for(i = 3*NO_OF_PARTICLES/4;i<NO_OF_PARTICLES;i++){
   for(j = 0;j<NO_OF_PARTICLES;j++){
     compute_interaction(&system[i],&system[j]);
   }
 }

}

__vector int get_quadrant_count(particle* system){
 
  __vector int quad_count = VECINTZERO;
  __vector int quad_mask = VECINTZERO;
 int i;
 for(i = 0; i < NO_OF_PARTICLES ; i++){

         __vector int top2 = (__vector int){1,1,0,0};
         __vector int bottom2 = (__vector int){0,0,1,1};
         __vector int left2 = (__vector int){0,1,0,1};
         __vector int right2 = (__vector int){1,0,1,0};
	 __vector int mask1, mask2;
   
         __vector float vx = vec_splat(system[i].position,0);
         __vector float vy = vec_splat(system[i].position,1);
	 
	 mask1 = vec_sel(right2, left2, vec_cmpgt(vx,VECZERO));
	 mask2 = vec_sel(top2, bottom2, vec_cmpgt(vy,VECZERO));
         quad_mask = vec_and(mask1,mask2);
	 quad_count = vec_add(quad_count,quad_mask);
	 
 }
 return quad_count;
}

void render(particle* system){

 int i = 0;
 for(; i < NO_OF_PARTICLES; i++){

   float *pos = (float*) &system[i].position;
   float *vel = (float*) &system[i].velocity;
   float *acc = (float*) &system[i].acceleration;

   printf("position : %f %f %f ", pos[0], pos[1], pos[2]);
   printf("velocity : %f %f %f ", vel[0], vel[1], vel[2]);
   printf("acceleration : %f %f %f \n", acc[0], acc[1], acc[2]);

 }
}

int main ()
{

 /* create particle system --> array of particles */
 particle particle_system[NO_OF_PARTICLES] __attribute__((aligned(64)));
 
 /* vector that tracks the no. of particles in each quadrant */
 __vector int quad_count;
 int * qc;
 
 /* place particles in 4 quadrants */
 init_particles(particle_system);

 /* run simulation */
 float simulationTime = 0.0;
 int iterations = COMPUTE_ITERATIONS;
 printf("----------------------------------------------");
 printf("----------------------------------------------\n");
 printf("Running Simulation with %d particles & %d iterations with %f seconds time steps\n",
	NO_OF_PARTICLES, COMPUTE_ITERATIONS, TIME_STEP);
 printf("----------------------------------------------");
 printf("----------------------------------------------\n");

 while(iterations > 0){

   /* Compute */
   update_particles(particle_system);

   /* Display */
   //render(particle_system);

   /* Update Time */
   simulationTime = simulationTime + TIME_STEP;
   printf("----------------------------------");
   printf("Simulation Time: %f |",simulationTime);
   quad_count = get_quadrant_count(particle_system);
   qc = (int*)&quad_count;
   printf(" q1:%d q2:%d q3:%d q4:%d",qc[0], qc[1], qc[2], qc[3]);
   printf("----------------------------------\n");

   iterations --;
 }

 return 0;
}
コード例 #3
0
ファイル: particles.c プロジェクト: njs55/particles
// Main function
int main(int argc, char** argv){
  int myRank;// Rank of process
  int p;// Number of processes
  int n;// Number of total particles
  int previous;// Previous rank in the ring
  int next;// Next rank in the ring
  int tag = TAG;// Tag for message
  int number;// Number of local particles
  int count_mpi;
  struct Particle *globals;// Array of all particles in the system
  struct Particle *locals;// Array of local particles
  struct Particle *remotes;// Array of foreign particles
  char *file_name;// File name
  MPI_Status status;// Return status for receive
  int j, rounds, initiator, sender;
  double start_time, end_time;

  // checking the number of parameters
  if(argc < 2){
    printf("ERROR: Not enough parameters\n");
    printf("Usage: %s <number of particles> [<file>]\n", argv[0]);
    exit(1);
  }
  
  // getting number of particles
  n = atoi(argv[1]);

  // initializing MPI structures and checking p is odd
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
  MPI_Comm_size(MPI_COMM_WORLD, &p);
  if(p % 2 == 0){
    p = p - 1;
    if(myRank == p){
      MPI_Finalize();
      return 0;
    }
  }
  srand(myRank+myRank*CONSTANT);

  // acquiring memory for particle arrays
  //**changed to make it right*******
  number = ceil(1.0 * n / p);
  locals = (struct Particle *) calloc(number , sizeof(struct Particle));
  remotes = (struct Particle *) calloc(number , sizeof(struct Particle));

  // checking for file information
  if(argc == 3){
    if(myRank == 0){
      globals = (struct Particle *) calloc((ceil((double)n/p))*p , sizeof(struct Particle));

      // YOUR CODE GOES HERE (reading particles from file)
      
      read_file(globals, n,  argv[2]);

    }
    
    // To send/recv (or scatter/gather) you will need to learn how to
    // transfer structs of floats, treat it as a contiguous block of
    // floats. Here is an example:
    // MPI_Send(locals,
    //          number * (sizeof (struct Particle)) / sizeof(float),
    //          MPI_FLOAT,
    //          next_rank,
    //          tag,
    //          MPI_COMM_WORLD)
    // MPI_Recv(remotes,
    //          number * (sizeof (struct Particle)) / sizeof(float),
    //          MPI_FLOAT,
    //          previous_rank,
    //          tag,
    //          MPI_COMM_WORLD,
    //          &status);
    // hint: because your nodes need to both send and receive you
    // might consider asyncronous send/recv.

    // YOUR CODE GOES HERE (distributing particles among processors)
    
    count_mpi = number * (sizeof(struct Particle)) /sizeof(float);
    
  
    MPI_Scatter(globals, 
				count_mpi,
				MPI_FLOAT,
				locals,				
				count_mpi, 
				MPI_FLOAT,
				0,
				MPI_COMM_WORLD);
    
    
  } else {
    // random initialization of local particle array
    for(j = 0; j < number; j++){
      locals[j].x = random_value(POSITION);
      locals[j].y = random_value(POSITION);
      locals[j].fx = 0.0;
      locals[j].fy = 0.0;
      locals[j].mass = MASS;
    }
  }
  
  // starting timer
  if(myRank == 0){
    start_time = MPI_Wtime();
  }
  
  // YOUR CODE GOES HERE (ring algorithm)
  
  MPI_Request request_send[4];
  
  int nextRank = (myRank + 1) % p;
  int prevRank = (myRank - 1 + p) %  p;
  
		MPI_Isend(locals, 
				count_mpi, 
				MPI_FLOAT,
				nextRank,
				tag,
				MPI_COMM_WORLD,
				&request_send[0]);
	
		MPI_Recv(remotes, 
				count_mpi,
				MPI_FLOAT,			
				prevRank, 
				tag,
				MPI_COMM_WORLD,
				&status);			
			
		compute_interaction(locals, remotes, number);		
		
		MPI_Isend(remotes, 
				count_mpi,
				MPI_FLOAT,				 
				nextRank,
				tag,
				MPI_COMM_WORLD,
				&request_send[1]);
				
		
		for(int i=1; i<(p-1)/2; i++){
			
			MPI_Recv(remotes, 
					count_mpi,
					MPI_FLOAT,			
					prevRank, 
					tag,
					MPI_COMM_WORLD,
					&status);
			
		    compute_interaction(locals, remotes, number);
					
			MPI_Isend(remotes, 
					count_mpi,
					MPI_FLOAT,				 
					nextRank,
					tag,
					MPI_COMM_WORLD,
					&request_send[2]);		
			
		}	

	int OG_rank = ((myRank - (p-1)/2 + p) % p); //maybe call get_OG_rank function here and not sure where to increment rank_count
	int final_rank = ((myRank + (p-1)/2 + p) % p);

    
	//send remote back to original process
	MPI_Isend(remotes, 
			  count_mpi,
			  MPI_FLOAT,				 
			  OG_rank,
			  tag,
			  MPI_COMM_WORLD,
			  &request_send[3]);
			  
	MPI_Recv(remotes, 
			 count_mpi,
			 MPI_FLOAT,			
			 final_rank, 
			 tag,
			 MPI_COMM_WORLD,
			 &status);

	merge(locals, remotes, number);
	compute_self_interaction(locals, number);  //not sure about second parameter ******
	//Step 8 of algo
	MPI_Barrier(MPI_COMM_WORLD); //*********************************double check this****


  // stopping timer
  if(myRank == 0){
    end_time = MPI_Wtime();
    printf("Duration: %f seconds\n", (end_time-start_time));
  }
  
  // printing information on particles
  if(argc == 3){
    
    // YOUR CODE GOES HERE (collect particles at rank 0)
    
    count_mpi = number * (sizeof(struct Particle)) /sizeof(float);
    
    MPI_Gather(locals, 
			   count_mpi,
			   MPI_FLOAT,
			   globals,
			   count_mpi, 
			   MPI_FLOAT,
			   0,
			   MPI_COMM_WORLD);

    if(myRank == 0) {
      print_particles(globals,n);
    }
  }


  // finalizing MPI structures
  MPI_Finalize();
}