/* 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 }
/** ========================= 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; }
ttt::ttt(){ game = true; initializeGrid(); printGrid(); while(game){ playerTurn(false); printGrid(); gameCheck(false); if(game){ playerTurn(true); printGrid(); gameCheck(true); } } }
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") }
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); }
Reprojector::Reprojector(vk::AbstractCamera* cam, Map& map) : map_(map) { initializeGrid(cam); }
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; }
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; }
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() }