Exemplo n.º 1
0
/*
play TicTacToe, calling all appropriate functions
Parameters: name of original player
Return Type: none
*/
void playTicTacToe(void)
{
	char copyname[MAX_NAME_LENGTH];
	char grid[ROW_SIZE][COLUMN_SIZE];
	char ordername[2][MAX_NAME_LENGTH];
	char ordersymbol[2];
	char symbol1;
	char symbol2;
	int index = 0;
	int result = FALSE;

	printf("Who wants to go first? Enter name: ");
	scanf("%s", ordername[index]);
	printf("Enter the name of the opponent: ");
	scanf("%s", ordername[index + 1]);
	printf("%s would you like to be X or O? Enter the character: ", ordername[index]);
	scanf(" %c", &symbol2);			//the empty space in front of %c tells to ignore invisible character i.e. '\n'

	if (symbol2 == 'X' || symbol2 == 'x')
	{
		symbol1 = 'O';
		symbol2 = 'X';
	}
	else if (symbol2 == 'O' || symbol2 == 'o')
	{
		symbol1 = 'X';
		symbol2 = 'O';
	}
	else
	{
		printf("Entered invalid character. %s is assigned X and %s is assigned O.\n(you had one job...)\n", ordername[index], ordername[index + 1]);
		symbol1 = 'O';
		symbol2 = 'X';
	}
	ordersymbol[index] = symbol2;
	ordersymbol[index + 1] = symbol1;

	do
	{
		initializeGrid(grid);
		printf("Enter the number corresponding to grid.\n\n");

		index = round_TTT(grid, ordersymbol, ordername);

		if (index == TIE)
			printf("Tie game!\n");
		else
			printf("%s wins!\n", ordername[abs(index - 1)]);
	} while (doAgain());
}
  void VoxelGridDownsampleManager::onInit(void)
  {
    PCLNodelet::onInit();
    pnh_->param("base_frame", base_frame_, std::string("pelvis"));

    initializeGrid();
    sequence_id_ = 0;
    sub_ = pnh_->subscribe("input", 1, &VoxelGridDownsampleManager::pointCB,
                           this);
    bounding_box_sub_ = pnh_->subscribe("add_grid", 1, &VoxelGridDownsampleManager::addGrid,
                                        this);
    pub_ = pnh_->advertise<sensor_msgs::PointCloud2>("output", 1);
    pub_encoded_ = pnh_->advertise<sensor_msgs::PointCloud2>("output_encoded", 1);
    max_points_ = 300;
    rate_ = 1.0;                // 1Hz
  }
Exemplo n.º 3
0
/** ========================= Main function ==========================*/
int main (){
    init();
    Serial.begin(9600);
   
    randomSeed(analogRead(3)); // randomSeed() initializes the pseudo-random number generator
   
    pinMode(SEL, INPUT);
    digitalWrite(SEL, HIGH);
    tft.initR(INITR_BLACKTAB); // initialize a ST7735R chip
   
    initializeGrid();
    displayGrid();
    gamePlay();
  
    return 0;
}
Exemplo n.º 4
0
ttt::ttt(){
	game = true;
	initializeGrid();
	printGrid();
	while(game){
		playerTurn(false);
		printGrid();
		gameCheck(false);
		if(game){
			playerTurn(true);
			printGrid();
			gameCheck(true);
		}
	}
	
}
Exemplo n.º 5
0
Reprojector::Reprojector(vk::AbstractCamera* cam, Map& map) :
    map_(map)
{
  initializeGrid(cam);
  outfile.open ("/home/worxli/Datasets/data/depthunscaled.txt");
  outfile2.open ("/home/worxli/Datasets/data/xyzcoords.ply");
  // outfile.open ("/home/worxli/data/test/depthunscaled.txt");
  // outfile2.open ("/home/worxli/data/test/xyzcoords.ply");
  outfile2 << "ply\n"
          << "format ascii 1.0\n"
          << "element face 0\n"
          << "property list uchar int vertex_indices\n"
          << "element vertex 3527\n"
          << "property float x\n"
          << "property float y\n"
          << "property float z\n"
          << "end_header\n";
  // outfile3.open("/home/worxli/Datasets/data/xyzcoords.ply")
}
Exemplo n.º 6
0
Arquivo: pic.c Projeto: ParRes/Kernels
int main(int argc, char ** argv) {

  int         args_used = 1;     // keeps track of # consumed arguments
  uint64_t    L;                 // dimension of grid in cells
  uint64_t    iterations;        // total number of simulation steps
  uint64_t    n;                 // total number of particles in the simulation
  char        *init_mode;        // particle initialization mode (char)
  uint64_t    particle_mode;     // particle initialization mode (int)
  double      rho;               // attenuation factor for geometric particle distribution
  int64_t     k, m;              // determine initial horizontal and vertical velocity of
                                 // particles-- (2*k)+1 cells per time step
  double      alpha, beta;       // slope and offset values for linear particle distribution
  bbox_t      grid_patch,        // whole grid
              init_patch;        // subset of grid used for localized initialization
  int         correctness = 1;   // determines whether simulation was correct
  double      *Qgrid;            // field of fixed charges
  particle_t  *particles, *p;    // the particles array
  uint64_t    iter, i;           // dummies
  double      fx, fy, ax, ay;    // forces and accelerations
#if UNUSED
  int         particles_per_cell;// number of particles per cell to be injected
  int         error=0;           // used for graceful exit after error
#endif
  double      avg_time, pic_time;// timing parameters
  int         nthread_input,     // thread parameters
              nthread;
  int         num_error=0;       // flag that signals that requested and obtained
                                 // numbers of threads are the same
  random_draw_t dice;

  printf("Parallel Research Kernels Version %s\n", PRKVERSION);
  printf("OpenMP Particle-in-Cell execution on 2D grid\n");

  /*******************************************************************************
  ** process and test input parameters
  ********************************************************************************/

  if (argc<7) {
    printf("Usage: %s <#threads> <#simulation steps> <grid size> <#particles> <k (particle charge semi-increment)> ", argv[0]);
    printf("<m (vertical particle velocity)>\n");
    printf("          <init mode> <init parameters>]\n");
    printf("   init mode \"GEOMETRIC\"  parameters: <attenuation factor>\n");
    printf("             \"SINUSOIDAL\" parameters: none\n");
    printf("             \"LINEAR\"     parameters: <negative slope> <constant offset>\n");
    printf("             \"PATCH\"      parameters: <xleft> <xright>  <ybottom> <ytop>\n");
    exit(SUCCESS);
  }

  /* Take number of threads to request from command line */
  nthread_input = atoi(*++argv);

  if ((nthread_input < 1) || (nthread_input > MAX_THREADS)) {
    printf("ERROR: Invalid number of threads: %d\n", nthread_input);
    exit(EXIT_FAILURE);
  }

  omp_set_num_threads(nthread_input);

  iterations = atol(*++argv);  args_used++;
  if (iterations<1) {
    printf("ERROR: Number of time steps must be positive: %" PRIu64 "\n", iterations);
    exit(FAILURE);
  }
  L = atol(*++argv);  args_used++;
  if (L<1 || L%2) {
    printf("ERROR: Number of grid cells must be positive and even: %" PRIu64 "\n", L);
    exit(FAILURE);
  }

  grid_patch = (bbox_t){0, L+1, 0, L+1};
  n = atol(*++argv);  args_used++;
  if (n<1) {
    printf("ERROR: Number of particles must be positive: %" PRIu64 "\n", n);
    exit(FAILURE);
  }

  particle_mode  = UNDEFINED;
  k = atoi(*++argv);   args_used++;
  if (k<0) {
    printf("ERROR: Particle semi-charge must be non-negative: %" PRIu64 "\n", k);
    exit(FAILURE);
  }
  m = atoi(*++argv);   args_used++;
  init_mode = *++argv; args_used++;

  /* Initialize particles with geometric distribution */
  if (strcmp(init_mode, "GEOMETRIC") == 0) {
    if (argc<args_used+1) {
      printf("ERROR: Not enough arguments for GEOMETRIC\n");
      exit(FAILURE);
    }
    particle_mode = GEOMETRIC;
    rho = atof(*++argv);   args_used++;
  }

  /* Initialize with a sinusoidal particle distribution (single period) */
  if (strcmp(init_mode, "SINUSOIDAL") == 0) {
    particle_mode = SINUSOIDAL;
  }

  /* Initialize particles with linear distribution */
  /* The linear function is f(x) = -alpha * x + beta , x in [0,1]*/
  if (strcmp(init_mode, "LINEAR") == 0) {
    if (argc<args_used+2) {
      printf("ERROR: Not enough arguments for LINEAR initialization\n");
      exit(EXIT_FAILURE);
    }
    particle_mode = LINEAR;
    alpha = atof(*++argv); args_used++;
    beta  = atof(*++argv); args_used++;
    if (beta <0 || beta<alpha) {
      printf("ERROR: linear profile gives negative particle density\n");
      exit(EXIT_FAILURE);
    }
  }

  /* Initialize particles uniformly within a "patch" */
  if (strcmp(init_mode, "PATCH") == 0) {
    if (argc<args_used+4) {
      printf("ERROR: Not enough arguments for PATCH initialization\n");
      exit(FAILURE);
    }
    particle_mode = PATCH;
    init_patch.left   = atoi(*++argv); args_used++;
    init_patch.right  = atoi(*++argv); args_used++;
    init_patch.bottom = atoi(*++argv); args_used++;
    init_patch.top    = atoi(*++argv); args_used++;
    if (bad_patch(&init_patch, &grid_patch)) {
      printf("ERROR: inconsistent initial patch\n");
      exit(FAILURE);
    }
  }

  #pragma omp parallel
  {

  #pragma omp master
  {
  nthread = omp_get_num_threads();

  if (nthread != nthread_input) {
    num_error = 1;
    printf("ERROR: number of requested threads %d does not equal ",
           nthread_input);
    printf("number of spawned threads %d\n", nthread);
  }
  else {
    printf("Number of threads              = %d\n",nthread_input);
    printf("Grid size                      = %lld\n", L);
    printf("Number of particles requested  = %lld\n", n);
    printf("Number of time steps           = %lld\n", iterations);
    printf("Initialization mode            = %s\n", init_mode);

    switch(particle_mode) {
    case GEOMETRIC: printf("  Attenuation factor           = %lf\n", rho);    break;
    case SINUSOIDAL:                                                          break;
    case LINEAR:    printf("  Negative slope               = %lf\n", alpha);
                    printf("  Offset                       = %lf\n", beta);   break;
    case PATCH:     printf("  Bounding box                 = %" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "\n",
                           init_patch.left, init_patch.right,
                           init_patch.bottom, init_patch.top);                break;
    default:        printf("ERROR: Unsupported particle initializating mode\n");
                     exit(FAILURE);
    }
    printf("Particle charge semi-increment = %"PRIu64"\n", k);
    printf("Vertical velocity              = %"PRIu64"\n", m);

    /* Initialize grid of charges and particles */
    Qgrid = initializeGrid(L);

    LCG_init(&dice);
    switch(particle_mode) {
    case GEOMETRIC:  particles = initializeGeometric(n, L, rho, k, m, &n, &dice);      break;
    case SINUSOIDAL: particles = initializeSinusoidal(n, L, k, m, &n, &dice);          break;
    case LINEAR:     particles = initializeLinear(n, L, alpha, beta, k, m, &n, &dice); break;
    case PATCH:      particles = initializePatch(n, L, init_patch, k, m, &n, &dice);   break;
    default:         printf("ERROR: Unsupported particle distribution\n");  exit(FAILURE);
    }

    printf("Number of particles placed     = %lld\n", n);
  }
  }
  bail_out(num_error);
  }

  for (iter=0; iter<=iterations; iter++) {

    /* start the timer after one warm-up time step */
    if (iter==1) {
      pic_time = wtime();
    }

    /* Calculate forces on particles and update positions */
    #pragma omp parallel for private(i, p, fx, fy, ax, ay)
    for (i=0; i<n; i++) {
      p = particles;
      fx = 0.0;
      fy = 0.0;
      computeTotalForce(p[i], L, Qgrid, &fx, &fy);
      ax = fx * MASS_INV;
      ay = fy * MASS_INV;

      /* Update particle positions, taking into account periodic boundaries */
      p[i].x = fmod(p[i].x + p[i].v_x*DT + 0.5*ax*DT*DT + L, L);
      p[i].y = fmod(p[i].y + p[i].v_y*DT + 0.5*ay*DT*DT + L, L);

      /* Update velocities */
      p[i].v_x += ax * DT;
      p[i].v_y += ay * DT;
    }
  }

  pic_time = wtime() - pic_time;

  /* Run the verification test */
  for (i=0; i<n; i++) {
    correctness *= verifyParticle(particles[i], iterations, Qgrid, L);
  }

  if (correctness) {
    printf("Solution validates\n");
#ifdef VERBOSE
    printf("Simulation time is %lf seconds\n", pic_time);
#endif
    avg_time = n*iterations/pic_time;
    printf("Rate (Mparticles_moved/s): %lf\n", 1.0e-6*avg_time);
  } else {
    printf("Solution does not validate\n");
  }

  return(EXIT_SUCCESS);
}
Exemplo n.º 7
0
Reprojector::Reprojector(vk::AbstractCamera* cam, Map& map) :
    map_(map)
{
  initializeGrid(cam);
}
Exemplo n.º 8
0
int main(int argc, char* argv[]){
  // domain variables
  int iter = 0;
  int i;
  int file_index;
  int max_iter;
  double max_time = 1.0;
  double dt = .0000001;
  double domain_box[4] = {0.0, 0.0, 1.0, 2.0};
  double domain_m_box[4] = {.10, 0.2, 0.90, 2.00};
  int domain_num_cells[2] = {10, 20};
  int pp_cell[2] = {2,2};
  double ipart_dim[2];
  int domain_num_particles[2];
  double test_px, test_py;
  char p_filename[40];
  char p_filename2[40];
  char g_filename[40];

  //timing variables
  double start_time;
  double end_time;

  // patch variables
  int rank = 0;
  int size;
  int num_proc[2];
  double box[4];
  double m_box[4];
  int num_cells[2];
  int halo_cells[4] = {1,1,1,1};
  int num_particles[2];
  int sfactor = 2;

  GridData grid_data;
  Node** grid;

  InitialParticleData ipart_data;
  Particle* particles;
  Particle* post_particles;
  Particle* particle_list;
  Particle* rhalo_parts[8];
  Particle* shalo_parts[8];

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  MPI_Request halo_req[8][2];
  MPI_Status halo_stat[8][2];

  max_iter = (int)(max_time/dt);

  if(rank == 0){
    if(argc == 3){
      num_proc[0] = atoi(argv[1]);
      num_proc[1] = atoi(argv[2]);
    }else if(argc == 6){
      num_proc[0] = atoi(argv[1]);
      num_proc[1] = atoi(argv[2]);
      domain_num_cells[0] = atoi(argv[3]);
      domain_num_cells[1] = atoi(argv[4]);
      max_iter = atoi(argv[5]);
    }
  }

  MPI_Bcast(num_proc,         2, MPI_INT, 0, MPI_COMM_WORLD);
  MPI_Bcast(domain_num_cells, 2, MPI_INT, 0, MPI_COMM_WORLD);
  MPI_Bcast(&max_iter,        1, MPI_INT, 0, MPI_COMM_WORLD);
  MPI_Barrier(MPI_COMM_WORLD);
 
  grid_data.gravity[0] = 0;
  grid_data.gravity[1] = -900.8;
  grid_data.cell_dim[0] = (domain_box[2] - domain_box[0])/domain_num_cells[0];
  grid_data.cell_dim[1] = (domain_box[3] - domain_box[1])/domain_num_cells[1];

  test_px = grid_data.cell_dim[0]/pp_cell[0];
  test_py = grid_data.cell_dim[1]/pp_cell[1];

  domain_num_particles[0] = (int)((domain_m_box[2] - domain_m_box[0])/test_px);
  domain_num_particles[1] = (int)((domain_m_box[3] - domain_m_box[1])/test_py);

  ipart_dim[0] = (domain_m_box[2] - domain_m_box[0])/domain_num_particles[0];
  ipart_dim[1] = (domain_m_box[3] - domain_m_box[1])/domain_num_particles[1];


  decomposeGrid(rank, num_proc, domain_num_cells, num_cells, domain_box, box, halo_cells, &grid_data);
  decomposeMaterial(box, domain_m_box, m_box, ipart_dim, num_particles);

  ipart_data.density = 1000;
  ipart_data.bulk = 3;
  ipart_data.shear = 4;
  ipart_data.E = 90000;
  ipart_data.poisson = .30;
  ipart_data.idim[0] = ipart_dim[0];
  ipart_data.idim[1] = ipart_dim[1];
  ipart_data.velocity[0] = 0;
  ipart_data.velocity[1] = 0;
  ipart_data.box[0] = m_box[0];
  ipart_data.box[1] = m_box[1];
  ipart_data.box[2] = m_box[2];
  ipart_data.box[3] = m_box[3];
  ipart_data.num_particles[0] = num_particles[0];
  ipart_data.num_particles[1] = num_particles[1];
  ipart_data.domain_num_particles[0] = domain_num_particles[0];
  ipart_data.domain_num_particles[1] = domain_num_particles[1];

  grid = createGrid(&grid_data, box, num_cells);
  particles = createMaterial(&grid_data, &ipart_data);
  post_particles = createMaterial(&grid_data, &ipart_data);

  initializeGrid(&grid_data, grid);
	initializeMaterial(&grid_data, &ipart_data, particles);
  
  //allocate halo particles
  allocateHaloParticles(&grid_data, sfactor, pp_cell, rhalo_parts, shalo_parts);
  
  file_index = 0;

  start_time = MPI_Wtime();
  for(iter = 0; iter <= max_iter; iter++){
    gatherHaloParticles(&grid_data, particles, rhalo_parts, shalo_parts);
    sendRecvParticles(&grid_data, rhalo_parts, shalo_parts);
    clearGridValues(&grid_data, grid);
    mapToGrid(&grid_data, grid, particles);
    for(i = 0; i < 8; i++){
      if(grid_data.rank[i] >= 0 && rhalo_parts[i][0].particle_count > 0){
        mapToGrid(&grid_data, grid, rhalo_parts[i]);
      }
    }
    momentumToVelocityOnGrid(&grid_data, grid);
    computeForces(&grid_data, grid, particles);
    for(i = 0; i < 8; i++){
      if(grid_data.rank[i] >= 0 && rhalo_parts[i][0].particle_count > 0){
        computeForces(&grid_data, grid, rhalo_parts[i]);
      }
    }
    computeAcceleration(&grid_data, grid);

    /**
    particle_list = gatherParticles(rank, size, domain_num_particles[0] * domain_num_particles[1],
                                    particles, post_particles);
    if(rank == 0){
      //if(iter%100 == 0){
      sprintf(p_filename, "ppart%06d.vtk", file_index);
      //sprintf(p_filename2, "center%06d.vtk", file_index);
      //sprintf(g_filename, "grid_output%06d.vtk", file_index);
      //writeParticlesVtkFile(&grid_data, grid, rhalo_parts[0], p_filename);
      writeParticlesVtkFile(&grid_data, grid, particle_list, p_filename);
      //writeParticlesVtkFile(&grid_data, grid, particle_list, p_filename);
      //writeParticlesVtkFile(&grid_data, grid, particles, p_filename);
      //writeGridVtkFile(&grid_data, grid, g_filename);
      //writeGridVtkFile(&grid_data, grid, g_filename);
      //free(particle_list);
      file_index++;
      //}
    }
    **/

    updateNodalValues(&grid_data, grid, dt);
    updateStressAndStrain(&grid_data, grid, particles, dt);
    pUpdateParticlePosition(&grid_data, grid, particles, post_particles, shalo_parts, dt);
    sendRecvParticles(&grid_data, rhalo_parts, shalo_parts);
    updateParticleList(&grid_data, particles, rhalo_parts);

    /**
    particle_list = gatherParticles(rank, size, domain_num_particles[0] * domain_num_particles[1],
                                    particles, post_particles);
    if(rank == 0){
      sprintf(p_filename, "particle_output%06d.vtk", file_index);
      file_index++;
      //sprintf(g_filename, "grid_output%06d.vtk", file_index);
      writeParticlesVtkFile(&grid_data, grid, particles, p_filename);
      //writeParticlesVtkFile(&grid_data, grid, particle_list, p_filename);
      //writeParticlesVtkFile(&grid_data, grid, particles, p_filename);
      //writeGridVtkFile(&grid_data, grid, g_filename);
      free(particle_list);
    }
    **/

    MPI_Barrier(MPI_COMM_WORLD);
  }
  end_time = MPI_Wtime();

  MPI_Barrier(MPI_COMM_WORLD);
  //particle_list = gatherParticles(rank, size, domain_num_particles[0] * domain_num_particles[1],
  //                                particles, post_particles);
  if(rank == 0){
    printf("Parallel, np: %d, iterations: %d, time: %f\n", size, max_iter, end_time-start_time);
    //writeParticlesVtkFile(&grid_data, grid, particle_list, "pparts.vtk");
    //free(particle_list);
  }

  
  freeGrid(grid, &grid_data);
  freeMaterial(particles);
  freeMaterial(post_particles);
  freeHaloParticles(&grid_data, rhalo_parts, shalo_parts);

  //MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();

  return 0;
}
Exemplo n.º 9
0
Arquivo: pic.c Projeto: afanfa/Kernels
int main(int argc, char ** argv) {
   
  int             Num_procs;         // number of ranks 
  int             Num_procsx, 
                  Num_procsy;        // number of ranks in each coord direction      
  int             args_used = 1;     // keeps track of # consumed arguments
  int             my_ID;             // MPI rank
  int             my_IDx, my_IDy;    // coordinates of rank in rank grid                  
  int             root = 0;          // master rank
  uint64_t        L;                 // dimension of grid in cells
  uint64_t        iterations ;       // total number of simulation steps
  uint64_t        n;                 // total number of particles requested in the simulation
  uint64_t        actual_particles,  // actual number of particles owned by my rank
                  total_particles;   // total number of generated particles
  char            *init_mode;        // particle initialization mode (char)
  double          rho ;              // attenuation factor for geometric particle distribution
  uint64_t        k, m;              // determine initial horizontal and vertical velocity of 
                                 // particles-- (2*k)+1 cells per time step 
  double          *grid;             // the grid is represented as an array of charges
  uint64_t        iter, i;           // dummies
  double          fx, fy, ax, ay;    // particle forces and accelerations
  int             error=0;           // used for graceful exit after error
  uint64_t        correctness=0;     // boolean indicating correct particle displacements
  uint64_t        istart, jstart, iend, jend, particles_size, particles_count;
  bbox_t          grid_patch,        // whole grid
                  init_patch,        // subset of grid used for localized initialization
                  my_tile;           // subset of grid owner by my rank
  particle_t      *particles, *p;    // array of particles owned by my rank
  uint64_t        *cur_counts;       //
  uint64_t        ptr_my;            //
  uint64_t        owner;             // owner (rank) of a particular particle
  double          pic_time, local_pic_time, avg_time;
  uint64_t        my_checksum = 0, tot_checksum = 0, correctness_checksum = 0;
  uint64_t        width, height;     // minimum dimensions of grid tile owned by my rank
  int             particle_mode;     // type of initialization
  double          alpha, beta;       // negative slope and offset for linear initialization
  int             nbr[8];            // topological neighbor ranks
  int             icrit, jcrit;      // global grid indices where tile size drops to minimum
  find_owner_type find_owner;
  int             ileftover, jleftover;// excess grid points divided among "fat" tiles
  uint64_t        to_send[8], to_recv[8];// 
  int             procsize;          // number of ranks per OS process                      
   
  MPI_Status  status[16];
  MPI_Request requests[16];
   
  /* Initialize the MPI environment */
  MPI_Init(&argc,&argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &my_ID);
  MPI_Comm_size(MPI_COMM_WORLD, &Num_procs);

  /* FIXME: This can be further improved */
  /* Create MPI data type for particle_t */
  MPI_Datatype PARTICLE;
  MPI_Type_contiguous(sizeof(particle_t)/sizeof(double), MPI_DOUBLE, &PARTICLE);
  MPI_Type_commit( &PARTICLE );

  if (my_ID==root) {
    printf("Parallel Research Kernels version %s\n", PRKVERSION);
    printf("FG_MPI Particle-in-Cell execution on 2D grid\n");

    if (argc<6) {
      printf("Usage: %s <#simulation steps> <grid size> <#particles> <k (particle charge semi-increment)> ", argv[0]);
      printf("<m (vertical particle velocity)>\n");
      printf("          <init mode> <init parameters>]\n");
      printf("   init mode \"GEOMETRIC\"  parameters: <attenuation factor>\n");
      printf("             \"SINUSOIDAL\" parameters: none\n");
      printf("             \"LINEAR\"     parameters: <negative slope> <constant offset>\n");
      printf("             \"PATCH\"      parameters: <xleft> <xright>  <ybottom> <ytop>\n");
      error = 1;
      goto ENDOFTESTS;
    }

    iterations = atol(*++argv);  args_used++;   
    if (iterations<1) {
      printf("ERROR: Number of time steps must be positive: %llu\n", iterations);
      error = 1;
      goto ENDOFTESTS;  
    }

    L = atol(*++argv);  args_used++;   
    if (L<1 || L%2) {
      printf("ERROR: Number of grid cells must be positive and even: %llu\n", L);
      error = 1;
      goto ENDOFTESTS;  
    }
    n = atol(*++argv);  args_used++;   
    if (n<1) {
      printf("ERROR: Number of particles must be positive: %llu\n", n);
      error = 1;
      goto ENDOFTESTS;  
    }

    particle_mode  = UNDEFINED;
    k = atoi(*++argv);   args_used++; 
    if (k<0) {
      printf("ERROR: Particle semi-charge must be non-negative: %llu\n", k);
      error = 1;
      goto ENDOFTESTS;  
    }
    m = atoi(*++argv);   args_used++; 
    init_mode = *++argv; args_used++;  

    ENDOFTESTS:;  

  } // done with standard initialization parameters
  bail_out(error);

  MPI_Bcast(&iterations, 1, MPI_UINT64_T, root, MPI_COMM_WORLD);
  MPI_Bcast(&L,          1, MPI_UINT64_T, root, MPI_COMM_WORLD);
  MPI_Bcast(&n,          1, MPI_UINT64_T, root, MPI_COMM_WORLD);
  MPI_Bcast(&k,          1, MPI_UINT64_T, root, MPI_COMM_WORLD);
  MPI_Bcast(&m,          1, MPI_UINT64_T, root, MPI_COMM_WORLD);

  grid_patch = (bbox_t){0, L+1, 0, L+1};
   
  if (my_ID==root) { // process initialization parameters
    /* Initialize particles with geometric distribution */
    if (strcmp(init_mode, "GEOMETRIC") == 0) {
      if (argc<args_used+1) {
        printf("ERROR: Not enough arguments for GEOMETRIC\n"); 
        error = 1;
        goto ENDOFTESTS2;  
      }
      particle_mode = GEOMETRIC;
      rho = atof(*++argv);   args_used++;
    }
   
    /* Initialize with a sinusoidal particle distribution (single period) */
    if (strcmp(init_mode, "SINUSOIDAL") == 0) {
      particle_mode = SINUSOIDAL;
    }
   
    /* Initialize particles with linear distribution */
    /* The linear function is f(x) = -alpha * x + beta , x in [0,1]*/
    if (strcmp(init_mode, "LINEAR") == 0) {
      if (argc<args_used+2) {
        printf("ERROR: Not enough arguments for LINEAR initialization\n");
        error = 1;
        goto ENDOFTESTS2;  
        exit(EXIT_FAILURE);
      }
      particle_mode = LINEAR;
      alpha = atof(*++argv); args_used++; 
      beta  = atof(*++argv); args_used++;
      if (beta <0 || beta<alpha) {
        printf("ERROR: linear profile gives negative particle density\n");
        error = 1;
        goto ENDOFTESTS2;  
      }
    }
   
    /* Initialize particles uniformly within a "patch" */
    if (strcmp(init_mode, "PATCH") == 0) {
      if (argc<args_used+4) {
        printf("ERROR: Not enough arguments for PATCH initialization\n");
        error = 1;
        goto ENDOFTESTS2;  
      }
      particle_mode = PATCH;
      init_patch.left   = atoi(*++argv); args_used++;
      init_patch.right  = atoi(*++argv); args_used++;
      init_patch.bottom = atoi(*++argv); args_used++;
      init_patch.top    = atoi(*++argv); args_used++;
      if (bad_patch(&init_patch, &grid_patch)) {
        printf("ERROR: inconsistent initial patch\n");
        error = 1;
        goto ENDOFTESTS2;  
      }
    }
    ENDOFTESTS2:;  

  } //done with processing initializaton parameters, now broadcast

  bail_out(error);

  MPI_Bcast(&particle_mode, 1, MPI_INT, root, MPI_COMM_WORLD);
  switch (particle_mode) {
  case GEOMETRIC:  MPI_Bcast(&rho,               1, MPI_DOUBLE,  root, MPI_COMM_WORLD);
                   break;
  case SINUSOIDAL: break;
  case LINEAR:     MPI_Bcast(&alpha,             1, MPI_DOUBLE,  root, MPI_COMM_WORLD);
                   MPI_Bcast(&beta,              1, MPI_DOUBLE,  root, MPI_COMM_WORLD);
                   break;
  case PATCH:      MPI_Bcast(&init_patch.left,   1, MPI_INT64_T, root, MPI_COMM_WORLD);
                   MPI_Bcast(&init_patch.right,  1, MPI_INT64_T, root, MPI_COMM_WORLD);
                   MPI_Bcast(&init_patch.bottom, 1, MPI_INT64_T, root, MPI_COMM_WORLD);
                   MPI_Bcast(&init_patch.top,    1, MPI_INT64_T, root, MPI_COMM_WORLD);
                   break;
  }
   
  /* determine best way to create a 2D grid of ranks (closest to square, for 
     best surface/volume ratio); we do this brute force for now                        */

  for (Num_procsx=(int) (sqrt(Num_procs+1)); Num_procsx>0; Num_procsx--) {
    if (!(Num_procs%Num_procsx)) {
      Num_procsy = Num_procs/Num_procsx;
      break;
    }
  }      
  my_IDx = my_ID%Num_procsx;
  my_IDy = my_ID/Num_procsx;

  if (my_ID == root) {
    MPIX_Get_collocated_size(&procsize);
    printf("Number of ranks                    = %llu\n", Num_procs);
    printf("Number of ranks/process            = %d\n", procsize);
    printf("Load balancing                     = None\n");
    printf("Grid size                          = %llu\n", L);
    printf("Tiles in x/y-direction             = %d/%d\n", Num_procsx, Num_procsy);
    printf("Number of particles requested      = %llu\n", n); 
    printf("Number of time steps               = %llu\n", iterations);
    printf("Initialization mode                = %s\n",   init_mode);
    switch(particle_mode) {
    case GEOMETRIC: printf("  Attenuation factor               = %lf\n", rho);    break;
    case SINUSOIDAL:                                                              break;
    case LINEAR:    printf("  Negative slope                   = %lf\n", alpha);
                    printf("  Offset                           = %lf\n", beta);   break;
    case PATCH:     printf("  Bounding box                     = %llu, %llu, %llu, %llu\n",
                           init_patch.left, init_patch.right, 
                           init_patch.bottom, init_patch.top);                    break;
    default:        printf("ERROR: Unsupported particle initializating mode\n");
                    error = 1;
    }
    printf("Particle charge semi-increment (k) = %llu\n", k);
    printf("Vertical velocity              (m) = %llu\n", m);
  }
  bail_out(error);

  /* The processes collectively create the underlying grid following a 2D block decomposition;
     unlike in the stencil code, successive blocks share an overlap vertex                   */
  width = L/Num_procsx;
  if (width < 2*k) {
    if (my_ID==0) printf("k-value too large: %llu, must be no greater than %llu\n", k, width/2);
    bail_out(1);
  }
  ileftover = L%Num_procsx;
  if (my_IDx<ileftover) {
    istart = (width+1) * my_IDx; 
    iend = istart + width + 1;
  }
  else {
    istart = (width+1) * ileftover + width * (my_IDx-ileftover);
    iend = istart + width;
  }
  icrit = (width+1) * ileftover;

  height = L/Num_procsy;
  if (height < m) {
    if (my_ID==0) printf("m-value too large: %llu, must be no greater than %llu\n", m, height);
    bail_out(1);
  }

  jleftover = L%Num_procsy;
  if (my_IDy<jleftover) {
    jstart = (height+1) * my_IDy; 
    jend = jstart + height + 1;
  }
  else {
    jstart = (height+1) * jleftover + height * (my_IDy-jleftover);
    jend = jstart + height;
  }
  jcrit = (height+1) * jleftover;

  /* if the problem can be divided evenly among ranks, use the simple owner finding function */
  if (icrit==0 && jcrit==0) {
    find_owner = find_owner_simple;
    if (my_ID==root) printf("Rank search mode used              = simple\n");
  }
  else {
    find_owner = find_owner_general;
    if (my_ID==root) printf("Rank search mode used              = general\n");
  }

  /* define bounding box for tile owned by my rank for convenience */
  my_tile = (bbox_t){istart,iend,jstart,jend};

  /* Find neighbors. Indexing: left=0, right=1, bottom=2, top=3, 
                               bottom-left=4, bottom-right=5, top-left=6, top-right=7 */

  /* These are IDs in the global communicator */
  nbr[0] = (my_IDx == 0           ) ? my_ID  + Num_procsx - 1         : my_ID  - 1;
  nbr[1] = (my_IDx == Num_procsx-1) ? my_ID  - Num_procsx + 1         : my_ID  + 1;
  nbr[2] = (my_IDy == Num_procsy-1) ? my_ID  + Num_procsx - Num_procs : my_ID  + Num_procsx;
  nbr[3] = (my_IDy == 0           ) ? my_ID  - Num_procsx + Num_procs : my_ID  - Num_procsx;
  nbr[4] = (my_IDy == Num_procsy-1) ? nbr[0] + Num_procsx - Num_procs : nbr[0] + Num_procsx;
  nbr[5] = (my_IDy == Num_procsy-1) ? nbr[1] + Num_procsx - Num_procs : nbr[1] + Num_procsx;
  nbr[6] = (my_IDy == 0           ) ? nbr[0] - Num_procsx + Num_procs : nbr[0] - Num_procsx;
  nbr[7] = (my_IDy == 0           ) ? nbr[1] - Num_procsx + Num_procs : nbr[1] - Num_procsx;

  grid = initializeGrid(my_tile);

  switch(particle_mode){
  case GEOMETRIC: 
    particles = initializeGeometric(n, L, rho, my_tile, k, m,
                                     &particles_count, &particles_size);
    break;
  case LINEAR:
    particles = initializeLinear(n, L, alpha, beta, my_tile, k, m, 
                                     &particles_count, &particles_size);
    break;
  case SINUSOIDAL:
    particles = initializeSinusoidal(n, L, my_tile, k, m, 
                                     &particles_count, &particles_size);
    break;
  case PATCH:
    particles = initializePatch(n, L, init_patch, my_tile, k, m,
                                     &particles_count, &particles_size);
  }

  if (!particles) {
    printf("ERROR: Rank %d could not allocate space for %llu particles\n", my_ID, particles_size);
    error=1;
  }
  bail_out(error);

#if VERBOSE
  for (i=0; i<Num_procs; i++) {
    MPI_Barrier(MPI_COMM_WORLD);
    if (i == my_ID)  printf("Rank %d has %llu particles\n", my_ID, particles_count);
  }
#endif
  if (my_ID==root) {
    MPI_Reduce(&particles_count, &total_particles, 1, MPI_UINT64_T, MPI_SUM, root, MPI_COMM_WORLD);
    printf("Number of particles placed         = %llu\n", total_particles);
  }
  else {
    MPI_Reduce(&particles_count, &total_particles, 1, MPI_UINT64_T, MPI_SUM, root, MPI_COMM_WORLD);
  }

  /* Allocate space for communication buffers. Adjust appropriately as the simulation proceeds */
  
  uint64_t sendbuf_size[8], recvbuf_size[8];
  particle_t *sendbuf[8], *recvbuf[8];
  error=0;
  for (i=0; i<8; i++) {
    sendbuf_size[i] = MAX(1,n/(MEMORYSLACK*Num_procs));
    recvbuf_size[i] = MAX(1,n/(MEMORYSLACK*Num_procs));
    sendbuf[i] = (particle_t*) prk_malloc(sendbuf_size[i] * sizeof(particle_t));
    recvbuf[i] = (particle_t*) prk_malloc(recvbuf_size[i] * sizeof(particle_t));
    if (!sendbuf[i] || !recvbuf[i]) error++;
  }
  if (error) printf("Rank %d could not allocate communication buffers\n", my_ID);
  bail_out(error);
    
  /* Run the simulation */
  for (iter=0; iter<=iterations; iter++) {

    /* start timer after a warmup iteration */
    if (iter == 1) { 
      MPI_Barrier(MPI_COMM_WORLD);
      local_pic_time = wtime();
    }

    ptr_my = 0;
    for (i=0; i<8; i++) to_send[i]=0;
      
    /* Process own particles */
    p = particles;

    for (i=0; i < particles_count; i++) {
      fx = 0.0;
      fy = 0.0;
      computeTotalForce(p[i], my_tile, grid, &fx, &fy);

      ax = fx * MASS_INV;
      ay = fy * MASS_INV;

      /* Update particle positions, taking into account periodic boundaries */
      p[i].x = fmod(p[i].x + p[i].v_x*DT + 0.5*ax*DT*DT + L, L);
      p[i].y = fmod(p[i].y + p[i].v_y*DT + 0.5*ay*DT*DT + L, L);

      /* Update velocities */
      p[i].v_x += ax * DT;
      p[i].v_y += ay * DT;

      /* Check if particle stayed in same subdomain or moved to another */
      owner = find_owner(p[i], width, height, Num_procsx, icrit, jcrit, ileftover, jleftover);
      if (owner==my_ID) {
        add_particle_to_buffer(p[i], &p, &ptr_my, &particles_size);
      /* Add particle to the appropriate communication buffer */
      } else if (owner == nbr[0]) {
        add_particle_to_buffer(p[i], &sendbuf[0], &to_send[0], &sendbuf_size[0]);
      } else if (owner == nbr[1]) {
        add_particle_to_buffer(p[i], &sendbuf[1], &to_send[1], &sendbuf_size[1]);
      } else if (owner == nbr[2]) {
        add_particle_to_buffer(p[i], &sendbuf[2], &to_send[2], &sendbuf_size[2]);
      } else if (owner == nbr[3]) {
        add_particle_to_buffer(p[i], &sendbuf[3], &to_send[3], &sendbuf_size[3]);
      } else if (owner == nbr[4]) {
        add_particle_to_buffer(p[i], &sendbuf[4], &to_send[4], &sendbuf_size[4]);
      } else if (owner == nbr[5]) {
        add_particle_to_buffer(p[i], &sendbuf[5], &to_send[5], &sendbuf_size[5]);
      } else if (owner == nbr[6]) {
        add_particle_to_buffer(p[i], &sendbuf[6], &to_send[6], &sendbuf_size[6]);
      } else if (owner == nbr[7]) {
        add_particle_to_buffer(p[i], &sendbuf[7], &to_send[7], &sendbuf_size[7]);
      } else {
        printf("Could not find neighbor owner of particle %llu in tile %llu\n", 
        i, owner);
        MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
      }
    }

    /* Communicate the number of particles to be sent/received */
    for (i=0; i<8; i++) {
      MPI_Isend(&to_send[i], 1, MPI_UINT64_T, nbr[i], 0, MPI_COMM_WORLD, &requests[i]);
      MPI_Irecv(&to_recv[i], 1, MPI_UINT64_T, nbr[i], 0, MPI_COMM_WORLD, &requests[8+i]);
    }
    MPI_Waitall(16, requests, status);
      
    /* Resize receive buffers if need be */
    for (i=0; i<8; i++) {
      resize_buffer(&recvbuf[i], &recvbuf_size[i], to_recv[i]);
    }
      
    /* Communicate the particles */
    for (i=0; i<8; i++) {
      MPI_Isend(sendbuf[i], to_send[i], PARTICLE, nbr[i], 0, MPI_COMM_WORLD, &requests[i]);
      MPI_Irecv(recvbuf[i], to_recv[i], PARTICLE, nbr[i], 0, MPI_COMM_WORLD, &requests[8+i]);
    }
    MPI_Waitall(16, requests, status);
     
    /* Attach received particles to particles buffer */
    for (i=0; i<4; i++) {
      attach_received_particles(&particles, &ptr_my, &particles_size, recvbuf[2*i], to_recv[2*i], 
                                recvbuf[2*i+1], to_recv[2*i+1]);
    }    
    particles_count = ptr_my;
  }
   
  local_pic_time = MPI_Wtime() - local_pic_time;
  MPI_Reduce(&local_pic_time, &pic_time, 1, MPI_DOUBLE, MPI_MAX, root,
             MPI_COMM_WORLD);
   
  /* Run the verification test */
  /* First verify own particles */
  for (i=0; i < particles_count; i++) {
    correctness += verifyParticle(particles[i], (double)L, iterations);
    my_checksum += (uint64_t)particles[i].ID;
  }

  /* Gather total checksum of particles */
  MPI_Reduce(&my_checksum, &tot_checksum, 1, MPI_UINT64_T, MPI_SUM, root, MPI_COMM_WORLD);
  /* Gather total checksum of correctness flags */
  MPI_Reduce(&correctness, &correctness_checksum, 1, MPI_UINT64_T, MPI_SUM, root, MPI_COMM_WORLD);

  if ( my_ID == root) {
    if (correctness_checksum != total_particles ) {
      printf("ERROR: there are %llu miscalculated locations\n", total_particles-correctness_checksum);
    }
    else {
      if (tot_checksum != (total_particles*(total_particles+1))/2) {
        printf("ERROR: Particle checksum incorrect\n");
      }
      else {
        avg_time = total_particles*iterations/pic_time;
        printf("Solution validates\n");
        printf("Rate (Mparticles_moved/s): %lf\n", 1.0e-6*avg_time);
      }
    }
  }
   
#if VERBOSE
  for (i=0; i<Num_procs; i++) {
    MPI_Barrier(MPI_COMM_WORLD);
    if (i == my_ID)  printf("Rank %d has %llu particles\n", my_ID, particles_count);
  }
#endif

  MPI_Finalize();
   
  return 0;
}
Exemplo n.º 10
0
int main(int argc, char **argv) {
	InitSD();
	FILE * file = fopen("sd:/hello.txt", "w");
	if (file == NULL)
		exit(0);
	fprintf(file, "hello, there!\n");
	fclose(file);

	// initialize the sound system.
	//ASND_Init();

	// Initialise the Graphics & Video subsystem
	GRRLIB_Init();
	GRRLIB_Settings.antialias = true;

	tex_Calibri = GRRLIB_LoadTexture(Calibri_18);

	GRRLIB_InitTileSet(tex_Calibri, 27, 37, 32);

	// Initialize the Wiimotes
	WPAD_Init();

	mainMenu();

	Ship *ship;
	ship = (Ship*) malloc(NUM_SHIPS * sizeof(Ship));
	ship = initializeShips(NUM_SHIPS, ship);
	Planet* planet;
	planet = (Planet*) malloc(NUM_PLANETS * sizeof(Planet));

	planet[0].x = 200;
	planet[0].y = 200;
	planet[0].m = 700;
	planet[0].r = 60;
	planet[0].color = 0xFFFFFFFF;
	planet[0].owner = NO_OWNER;
	planet[0].health = PLANET_HEALTH;
	planet[0].currentUpgrade = 0;
	planet[1].x = 400;
	planet[1].y = 400;
	planet[1].m = 300;
	planet[1].r = 30;
	planet[1].color = 0x00FFFFFF;
	planet[1].owner = NO_OWNER;
	planet[1].health = PLANET_HEALTH;
	planet[1].currentUpgrade = 0;
	planet[2].x = 1000;
	planet[2].y = 400;
	planet[2].m = 1000;
	planet[2].r = 200;
	planet[2].color = 0xFF2200FF;
	planet[2].owner = NO_OWNER;
	planet[2].health = PLANET_HEALTH;
	planet[2].currentUpgrade = 0;
	planet[3].x = 1400;
	planet[3].y = 1200;
	planet[3].m = 700;
	planet[3].r = 51;
	planet[3].color = 0x29AF1BFF;
	planet[3].owner = NO_OWNER;
	planet[3].health = PLANET_HEALTH;
	planet[3].currentUpgrade = 0;
	planet[4].x = 1850;
	planet[4].y = 1850;
	planet[4].m = 100;
	planet[4].r = 20;
	planet[4].color = 0xFF7777FF;
	planet[4].owner = NO_OWNER;
	planet[4].health = PLANET_HEALTH;
	planet[4].currentUpgrade = 0;
	// initialize planet's bullet arrays
	int i = 0;
	for (i = 0; i < NUM_PLANETS; i++) {
		planet[i].bullets = (struct Bullet *) malloc(sizeof(Bullet)
				* PLANET_BULLET_NUM);
		if (planet[i].bullets == NULL) {
			exit(0);
		}
		planet[i].numBullets = 0;
	}

	ship = initializeShips(NUM_SHIPS, ship);

	u8 frame_rate;

	initializeTextures();
	int buttons;
	initializeGrid();

	//ASND_Init();
	//ASND_SetVoice(5,VOICE_STEREO_16BIT,8000, 0, &betamaster_raw, betamaster_raw_size, 255, 255, NULL);
	/*
	 MODPlay_Init(&play);
	 MODPlay_SetMOD(&play, paradox_mod);
	 MODPlay_SetVolume(&play, 63, 63);
	 MODPlay_Start(&play);
	 */
	while (1) {

		profiler(1);
		WPAD_ScanPads(); // Scan the Wiimotes
		buttons = WPAD_ButtonsDown(0);
		// If [HOME] was pressed on the first Wiimote, break out of the loop
		if (buttons & WPAD_BUTTON_HOME)
			break;

		update(ship, planet);
		doMechanics(ship, planet);
		render(ship, planet);

		frame_rate = calculateFPS();

		GRRLIB_Printf(20, 20, tex_Calibri, 0xFFFFFFFF, .5, "FPS: %d",
				frame_rate);
		GRRLIB_Printf(20, 40, tex_Calibri, 0xFFFFFFFF, .5, "%d",
		                                ship[0].bullets[0].exploded);
		//int endProfile = profiler(0);
		GRRLIB_Render();
		frameCount++;

	}

	GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB
	for (i = 0; i < NUM_SHIPS; i++) {
		free(ship[i].bullets);
	}
	free(ship);
	GRRLIB_FreeTexture(tex_Calibri);
	freeStarMemory();
	exit(0); // Use exit() to exit a program, do not use 'return' from main()
}