const PartitionInfo * RoundRobinPartitioner::partition( const vector<SimulationObject *> *objects, const unsigned int numLPs ) const { PartitionInfo *myPartitionInfo = new PartitionInfo( numLPs ); vector< vector<SimulationObject *>* > partitions(numLPs); for(unsigned int i = 0; i < numLPs; i++){ partitions[i] = new vector<SimulationObject *>; } unsigned int n = 0; unsigned int skew = 0; while( n < objects->size() ){ // if((n % numLPs) ==1 && ++skew % 2 == 1) // partitions[0]->push_back( (*objects)[n] ); // else partitions[n % numLPs]->push_back( (*objects)[n] ); n++; } for(unsigned int i = 0; i < numLPs; i++){ myPartitionInfo->addPartition( i, partitions[i] ); } return myPartitionInfo; }
bool seissol::checkpoint::mpio::Wavefield::validate(MPI_File file) const { if (setHeaderView(file) != 0) { logWarning() << "Could not set checkpoint header view"; return false; } int result = true; if (rank() == 0) { Header header; // Check the header MPI_File_read(file, &header, 1, headerType(), MPI_STATUS_IGNORE); if (header.identifier != identifier()) { logWarning() << "Checkpoint identifier does match"; result = false; } else if (header.partitions != partitions()) { logWarning() << "Number of partitions in checkpoint does not match"; result = false; } } // Make sure everybody knows the result of the validation MPI_Bcast(&result, 1, MPI_INT, 0, comm()); return result; }
hpx::lcos::future<std::vector<std::vector<double> > > interpolator::interpolate_bulk_async( std::vector<sheneos_coord> const& coords, boost::uint32_t eosvalues) const { namespace naming = hpx::naming; namespace lcos = hpx::lcos; typedef std::map<naming::id_type, context_data> partitions_type; std::shared_ptr<partitions_type> partitions( std::make_shared<partitions_type>()); partitions_type& parts = *partitions; std::size_t index = 0; std::vector<sheneos_coord>::const_iterator end = coords.end(); for (std::vector<sheneos_coord>::const_iterator it = coords.begin(); it != end; ++it, ++index) { context_data& d = parts[get_id(*it)]; d.indicies_.push_back(index); d.coords_.push_back(*it); } return hpx::async( bulk_context(partitions, coords.size(), eosvalues) ); }
// Implements a greedy algorithm that split cells using the bisection until a target cell size is // reached std::tuple<std::vector<Partition>, std::vector<std::uint32_t>> bisectionToPartition(const std::vector<BisectionID> &node_to_bisection_id, const std::vector<std::size_t> &max_cell_sizes) { std::vector<std::uint32_t> permutation(node_to_bisection_id.size()); std::iota(permutation.begin(), permutation.end(), 0); std::vector<CellBisection> cells; cells.push_back(CellBisection{ 0, static_cast<std::uint32_t>(node_to_bisection_id.size()), NUM_BISECTION_BITS - 1, false}); std::vector<Partition> partitions(max_cell_sizes.size()); std::vector<std::uint32_t> num_cells(max_cell_sizes.size()); int level_idx = max_cell_sizes.size() - 1; for (auto max_cell_size : boost::adaptors::reverse(max_cell_sizes)) { BOOST_ASSERT(level_idx >= 0); partitionLevel(node_to_bisection_id, max_cell_size, permutation, cells); partitions[level_idx] = cellsToPartition(cells, permutation); num_cells[level_idx] = cells.size(); level_idx--; } return std::make_tuple(std::move(partitions), std::move(num_cells)); }
bool seissol::checkpoint::h5::Wavefield::validate(hid_t h5file) const { // Turn of error printing H5ErrHandler errHandler; // Check #partitions hid_t h5attr = H5Aopen(h5file, "partitions", H5P_DEFAULT); if (h5attr < 0) { logWarning(rank()) << "Checkpoint does not have a partition attribute."; return false; } int p; herr_t err = H5Aread(h5attr, H5T_NATIVE_INT, &p); checkH5Err(H5Aclose(h5attr)); if (err < 0 || p != partitions()) { logWarning(rank()) << "Partitions in checkpoint do not match."; return false; } // Check dimensions hid_t h5data = H5Dopen(h5file, "values", H5P_DEFAULT); if (h5data < 0) { logWarning(rank()) << "Checkpoint does not contains a data array."; return false; } hid_t h5space = H5Dget_space(h5data); checkH5Err(H5Dclose(h5data)); if (h5space < 0) { logWarning(rank()) << "Could not get space identifier in checkpoint."; return false; } bool isValid = true; int dims = H5Sget_simple_extent_ndims(h5space); if (dims != 1) { isValid = false; logWarning(rank()) << "Number of dimensions in checkpoint does not match."; } else { hsize_t dimSize; if (H5Sget_simple_extent_dims(h5space, &dimSize, 0L) != 1) { isValid = false; logWarning(rank()) << "Could not get dimension sizes of checkpoint."; } else { if (dimSize != numTotalElems()) { isValid = false; logWarning(rank()) << "Number of elements in checkpoint does not match."; } } } checkH5Err(H5Sclose(h5space)); return isValid; }
std::vector<std::vector<SimulationObject*>> RoundRobinPartitioner::partition( const std::vector<SimulationObject*>& objects, const unsigned int num_partitions) const { std::vector<std::vector<SimulationObject*>> partitions(num_partitions); for (unsigned int i = 0; i < objects.size(); ++i) { partitions[i % num_partitions].push_back(objects[i]); } return partitions; }
int main() { int n = 0; printf("Enter n : "); scanf("%d", &n); // We assume a number between 1 and 416 is entered unsigned long long result = partitions(n); if (result) printf("%llu partitions for %d\n", result, n); else printf("Buy some RAM...\n"); return EXIT_SUCCESS; }
/** * Finds the kth smallest number in an unsorted list. */ int selection_algorithm(int left, int right, int kth, int sensor) { for (;;) { int pivotIndex = partitions(left, right, sensor); //Pivot Between Left and Right int len = pivotIndex - left + 1; if (kth == len) { return A[sensor][pivotIndex]; } else if (kth < len) { right = pivotIndex - 1; } else { kth = kth - len; left = pivotIndex + 1; } } }
/* * Assign loop iterations to tiles simply inheriting a seed loop partitioning * provided to the inspector. */ static int* inherit(loop_t* seedLoop, int tileSize, map_list* partitionings, int* nCore, int* nExec, int* nNonExec, int nThreads) { map_t* partitioning = NULL; map_list::const_iterator it, end; for (it = partitionings->begin(), end = partitionings->end(); it != end; it++) { if (set_eq(seedLoop->set, (*it)->inSet)) { partitioning = *it; break; } } if (! partitioning) { return NULL; } int setCore = seedLoop->set->core; int setSize = seedLoop->set->size; int* indMap = new int[setSize]; ASSERT(partitioning->size == setSize, "Set partitioning size and seed loop size don't match"); // need to work on a copy because we can't modify an array provided by the user memcpy (indMap, partitioning->values, sizeof(int)*setSize); // restrict partitions to the core region std::fill (indMap + setCore, indMap + setSize, 0); std::set<int> partitions (indMap, indMap + setCore); // ensure the set of partitions IDs is compact (i.e., if we have a partitioning // 0: {0,1,...}, 1: {4,5,...}, 2: {}, 3: {6,10,...} ... // we instead want to have // 0: {0,1,...}, 1: {4,5,...}, 2: {6,10,...}, ... int i; std::map<int, int> mapper; std::set<int>::const_iterator sIt, sEnd; for (i = 0, sIt = partitions.begin(), sEnd = partitions.end(); sIt != sEnd; sIt++, i++) { mapper[*sIt] = i; } for (i = 0; i < setCore; i++) { indMap[i] = mapper[indMap[i]]; } *nCore = partitions.size(); // partition the exec halo region chunk_halo (seedLoop, tileSize, *nCore - 1, indMap, nExec, nNonExec, nThreads); return indMap; }
void seissol::checkpoint::mpio::Wavefield::writeHeader(double time, int timestepWaveField) { EPIK_TRACER("checkpoint_write_header"); SCOREP_USER_REGION("checkpoint_write_header", SCOREP_USER_REGION_TYPE_FUNCTION); checkMPIErr(setHeaderView(file())); if (rank() == 0) { Header header; header.identifier = identifier(); header.partitions = partitions(); header.time = time; header.timestepWavefield = timestepWaveField; checkMPIErr(MPI_File_write(file(), &header, 1, headerType(), MPI_STATUS_IGNORE)); } }
int main(int argc, char* argv[]) { if (argc != 2) { std::cout << "Hey! gimme one numba bubba" << std::endl; return 0; } boost::uint64_t x = std::atoi(argv[1]); Partitions partitions(x); boost::uint64_t answer = partitions.getResult(); std::cout << "P(" << x << ") is ... " << answer << std::endl; return 0; }
extern "C" int partitions(int cards[10], int subtotal) { int m=0; int total; // Hit for (int i = 0; i < 10; i++) { if (cards[i]>0) { total = subtotal+i+1; if (total < 21) { // Stand m += 1; // Hit again cards[i] -= 1; m += partitions(cards, total); cards[i] += 1; } else if (total==21) { // Stand; hit again is an automatic bust m += 1; } } } return m; }
unsigned long long partitions(unsigned long long n,unsigned long long m) { if(n==0) return 1; if(n==1) return 1; if(m==0) return 0; if(m==1) return 1; if(partitions_arr[n][m] != 0) return partitions_arr[n][m]; unsigned long long s = 0; for(unsigned long long i = m; i>0; i--) { s = s + partitions(n-i,std::min(i,n-i)); if(s>1000000) //uncomment this if you want the value mod 1000000 s = s%1000000; } partitions_arr[n][m] = s; return s; }
// Break this up into smaller bits std::vector<std::pair<boost::gregorian::date, boost::gregorian::date> > ParallelEnergyPlus::createPartitions(const openstudio::WorkspaceObject &t_runPeriod, int t_offset, int t_numPartitions) { boost::gregorian::date sd, ed; getRunPeriod(t_runPeriod, sd, ed); boost::gregorian::date_duration totalduration = ed - sd; double totalDays = totalduration.days() + 1; LOG(Debug, "t_offset " << t_offset << " t_numPartitions " << t_numPartitions << " totalDays " << totalDays); std::vector<std::pair<boost::gregorian::date, boost::gregorian::date> > partitions(t_numPartitions); // Compute partitions double daysPerPeriod = totalDays / t_numPartitions; if (daysPerPeriod-1 < t_offset) { throw std::runtime_error("The days per period is too small compared to the offset, they fully overlap"); } int X, Y, A, B; double averageDays; computeLinearCombination(A, B, X, Y, averageDays, daysPerPeriod, totalDays, t_numPartitions); // So... x processors get A days and y processors get B days // Start with ranks 0... x boost::gregorian::date d1(sd); //std::cout << boost::gregorian::to_simple_string(d1) << std::endl; createPartitions(d1, ed, A, 0, X, t_offset, sd, partitions); //std::cout << boost::gregorian::to_simple_string(d1) << std::endl; createPartitions(d1, ed, B, X, t_numPartitions, t_offset, sd, partitions); return partitions; }
hid_t seissol::checkpoint::h5::Wavefield::initFile(int odd, const char* filename) { hid_t h5file; if (loaded()) { // Open the old file h5file = open(filename, false); checkH5Err(h5file); // Time m_h5time[odd] = H5Aopen(h5file, "time", H5P_DEFAULT); checkH5Err(m_h5time[odd]); // Wavefield writer m_h5timestepWavefield[odd] = H5Aopen(h5file, "timestep_wavefield", H5P_DEFAULT); checkH5Err(m_h5timestepWavefield[odd]); // Data m_h5data[odd] = H5Dopen(h5file, "values", H5P_DEFAULT); checkH5Err(m_h5data[odd]); } else { // Create the file hid_t h5plist = H5Pcreate(H5P_FILE_ACCESS); checkH5Err(h5plist); checkH5Err(H5Pset_libver_bounds(h5plist, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST)); hsize_t align = utils::Env::get<hsize_t>("SEISSOL_CHECKPOINT_ALIGNMENT", 0); if (align > 0) checkH5Err(H5Pset_alignment(h5plist, 1, align)); #ifdef USE_MPI MPIInfo info; checkH5Err(H5Pset_fapl_mpio(h5plist, seissol::MPI::mpi.comm(), info.get())); #endif // USE_MPI h5file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, h5plist); checkH5Err(h5file); checkH5Err(H5Pclose(h5plist)); // Create scalar dataspace for attributes hid_t h5spaceScalar = H5Screate(H5S_SCALAR); checkH5Err(h5spaceScalar); // Time m_h5time[odd] = H5Acreate(h5file, "time", H5T_IEEE_F64LE, h5spaceScalar, H5P_DEFAULT, H5P_DEFAULT); checkH5Err(m_h5time[odd]); // Partitions hid_t h5partitions = H5Acreate(h5file, "partitions", H5T_STD_I32LE, h5spaceScalar, H5P_DEFAULT, H5P_DEFAULT); checkH5Err(h5partitions); int p = partitions(); checkH5Err(H5Awrite(h5partitions, H5T_NATIVE_INT, &p)); checkH5Err(H5Aclose(h5partitions)); // Wavefield writer m_h5timestepWavefield[odd] = H5Acreate(h5file, "timestep_wavefield", H5T_STD_I32LE, h5spaceScalar, H5P_DEFAULT, H5P_DEFAULT); checkH5Err(m_h5timestepWavefield[odd]); int t = 0; checkH5Err(H5Awrite(m_h5timestepWavefield[odd], H5T_NATIVE_INT, &t)); checkH5Err(H5Sclose(h5spaceScalar)); // Variable h5plist = H5Pcreate(H5P_DATASET_CREATE); checkH5Err(h5plist); checkH5Err(H5Pset_layout(h5plist, H5D_CONTIGUOUS)); checkH5Err(H5Pset_alloc_time(h5plist, H5D_ALLOC_TIME_EARLY)); m_h5data[odd] = H5Dcreate(h5file, "values", H5T_IEEE_F64LE, m_h5fSpaceData, H5P_DEFAULT, h5plist, H5P_DEFAULT); checkH5Err(m_h5data[odd]); checkH5Err(H5Pclose(h5plist)); } return h5file; }
void seissol::checkpoint::mpio::Wavefield::initHeader(WavefieldHeader &header) { seissol::checkpoint::Wavefield::initHeader(header); header.value(m_partitionComp) = partitions(); }
/* * Assign loop iterations to tiles carving partitions out of /seedLoop/ using * the METIS library. */ static int* metis(loop_t* seedLoop, int tileSize, map_list* meshMaps, int* nCore, int* nExec, int* nNonExec, int nThreads) { int i; int setCore = seedLoop->set->core; int setSize = seedLoop->set->size; // use the mesh description to find a suitable map for partitioning through METIS map_t* map = NULL; map_list::const_iterator it, end; for (it = meshMaps->begin(), end = meshMaps->end(); it != end; it++) { if (set_eq(seedLoop->set, (*it)->inSet) || set_eq(seedLoop->set, (*it)->outSet)) { map = *it; break; } } if (! map) { // unfortunate scenario: the user provided a mesh description, but the loop picked // as seed has an iteration space which is not part of the mesh description. // will have to revert to chunk partitioning return NULL; } // now partition through METIS: // ... mesh geometry int nElements = map->inSet->size; int nNodes = map->outSet->size; int nParts = nElements / tileSize; int arity = map->size / nElements; // ... data needed for partitioning int* indMap = new int[nElements]; int* indNodesMap = new int[nNodes]; int* adjncy = map->values; int* offsets = new int[nElements+1](); for (i = 1; i < nElements+1; i++) { offsets[i] = offsets[i-1] + arity; } // ... options int result, objval, ncon = 1; int options[METIS_NOPTIONS]; METIS_SetDefaultOptions(options); options[METIS_OPTION_NUMBERING] = 0; options[METIS_OPTION_CONTIG] = 1; // ... do partition! result = (arity == 2) ? METIS_PartGraphKway (&nNodes, &ncon, offsets, adjncy, NULL, NULL, NULL, &nParts, NULL, NULL, options, &objval, indMap) : METIS_PartMeshNodal (&nElements, &nNodes, offsets, adjncy, NULL, NULL, &nParts, NULL, options, &objval, indMap, indNodesMap); ASSERT(result == METIS_OK, "Invalid METIS partitioning"); // what's the target iteration set ? if (set_eq(seedLoop->set, map->inSet)) { delete[] indNodesMap; } else { // note: must be set_eq(seedLoop->set, map-outSet) delete[] indMap; indMap = indNodesMap; } delete[] offsets; // restrict partitions to the core region std::fill (indMap + setCore, indMap + setSize, 0); std::set<int> partitions (indMap, indMap + setCore); // ensure the set of partitions IDs is compact (i.e., if we have a partitioning // 0: {0,1,...}, 1: {4,5,...}, 2: {}, 3: {6,10,...} ... // we instead want to have // 0: {0,1,...}, 1: {4,5,...}, 2: {6,10,...}, ... std::map<int, int> mapper; std::set<int>::const_iterator sIt, sEnd; for (i = 0, sIt = partitions.begin(), sEnd = partitions.end(); sIt != sEnd; sIt++, i++) { mapper[*sIt] = i; } for (i = 0; i < setCore; i++) { indMap[i] = mapper[indMap[i]]; } *nCore = partitions.size(); // partition the exec halo region chunk_halo (seedLoop, tileSize, *nCore - 1, indMap, nExec, nNonExec, nThreads); return indMap; }