int main(){ Timing timer; #ifdef _DEBUG int size = 4;{ #else for(int size=1; size>0; size*=2){ #endif std::cout << "size: " << size << '\n'; const int times = 10; Matrix a, b; a.resize(size); b.resize(size); a.randomize(); b.randomize(); timer.setDivisor(times); timer.start(); for(int i=0; i<times; i++){ Matrix c = MatrixMultiplication::recursive(a, b); #ifdef _DEBUG c.print(); #endif } timer.end(); timer.reportCPUtime(); timer.start(); for(int i=0; i<times; i++){ Matrix c = MatrixMultiplication::strassen(a, b); #ifdef _DEBUG c.print(); #endif } timer.end(); timer.reportCPUtime(); } return system("pause"); }
int main(int argc, char* argv[]){ // Initialize MPI // Find out my identity in the default communicator MPI_Init(&argc, &argv); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); //used to store the final results std::vector<result_t> finalResults; //init the k value int k = 0; if(argc > 1){ try{ k = atoi(argv[1]); if(k < 0){ throw "just need to throw a random exception to catch`"; } } catch(...){ std::cerr<<"k must be a positive integer"<<std::endl; return 0; } } //init the custom openmpi datatype MPI_Datatype ResultMpiType; //wrapper function to set up the custom type createMPIResultStruct(&ResultMpiType); // Master if (rank == 0){ // ++++++++++++++++++++++++++++++ // Master process // ++++++++++++++++++++++++++++++ // check the arugmumants if (argc < 2){ std::cout << "Usage: " << argv[0] << " [k value] [directory path:default(/cluster)]" << std::endl; return 0; } std::string folderPath; //set the default for the folder to use if(argc == 2){ folderPath = "/cluster"; } else{ folderPath = argv[2]; } Directory dir; if(!dir.set_path(folderPath)){ std::cerr<<"Directory either not found or not a directory"<<std::endl; return 0; } //test for a correct k value try{ k = atoi(argv[1]); if(k < 0){ throw "just need to throw a random exception to catch`"; } } catch(...){ std::cerr<<"k must be a positive integer"<<std::endl; return 0; } auto test = dir.get_files(); searchVector_t searchVector; Timing wallClock; double timeResults[NUM_TIME_RESULTS]; //initlize timing holder for(int i = 0; i < NUM_TIME_RESULTS; i++){ timeResults[i] = 0; } wallClock.start(); //get the first vector the first file in the the directory as the search vector if(!getFirstVector(test.at(0),&searchVector)){ std::cerr << "Couldn't get the search vector" << std::endl; return 0; } std::cout << "Sending work to workers" << std::endl; sendWork(test,&ResultMpiType,k,&finalResults,searchVector.data,timeResults); //wait for the workers to finish to collect the results MPI_Barrier(MPI_COMM_WORLD); wallClock.end(); std::cout<<"wallClock time: "<<wallClock.get_elapse()<<std::endl; //get com size for timming results int threadCount; MPI_Comm_size(MPI_COMM_WORLD, &threadCount); //creat a vector fromt the timing results std::vector<double> finalTimingVec; finalTimingVec.push_back(threadCount); finalTimingVec.push_back(k); finalTimingVec.push_back(wallClock.get_elapse()); finalTimingVec.insert(finalTimingVec.end(),timeResults,timeResults+NUM_TIME_RESULTS); //output the timing vector to the timing for all the tests output_timing_vector_to_file("times.csv",finalTimingVec,1); //output the final results to a vector output_result_vector_to_file("results.csv", &finalResults); } else{ // ++++++++++++++++++++++++++++++ // Workers // ++++++++++++++++++++++++++++++ doWork(&ResultMpiType,k); //used for the barrier in master MPI_Barrier(MPI_COMM_WORLD); } MPI_Type_free(&ResultMpiType); //Shut down MPI MPI_Finalize(); return 1; } // END of main
void EntityEngine::generatePathfindingNodes(NodeVector & nodes) { // lay a grid over the static entities Timing tm; const int resolutionFactor = 1; const float collisionMarginFactor = 2.5f; const float gridSize = 1.0f / float(resolutionFactor); // 0.5f; //const float neighbourDistance = sqrt(gridSize * gridSize * 2.0f) * 1.1f; float floatHighestY = 0; float floatLowestY = 100000000000.0f; for (Entity const* ent : getStaticEntities()) { floatHighestY = std::max(floatHighestY, ent->getPosition().y()); floatLowestY = std::min(floatLowestY, ent->getPosition().y()); } dropNavigationNodes(nodes); // protect against no entities if (getStaticEntities().size() == 0) return; assert(floatHighestY > floatLowestY); logging::Info() << "Generating navigation grid for lowY: " << floatLowestY << " highY: " << floatHighestY; const int highestY = int(std::ceil(floatHighestY)); const int lowestY = int(std::floor(floatLowestY)); const int spanY = highestY - lowestY; const float spanX = 15.0f; const int nodeCount = (spanX * resolutionFactor) * (spanY * resolutionFactor); nodes.resize(nodeCount); // with a resolution of 2 times the tile size const int sizeX = spanX * resolutionFactor; const int sizeY = (spanY * resolutionFactor); for (int y = 0; y < sizeY; y++) { for (int x = 0; x < sizeX; x++) { Vector2 pos(float(x) * gridSize, float(y) * gridSize + float(lowestY)); // do only add if there is no collision object near by if (!checkForCollisionObject(pos, gridSize * collisionMarginFactor)) { const int thisNodeLocation = sizeX * y + x; NodePtr n = &nodes[thisNodeLocation]; n->Location = pos; // connect to left if (x > 0) { // left same line n->Neighbours.push_back(&nodes[thisNodeLocation - 1]); // left lower if (y > 0) { n->Neighbours.push_back(&nodes[thisNodeLocation - 1 - sizeX]); } // left upper if (y < (sizeY - 1)) { n->Neighbours.push_back(&nodes[thisNodeLocation - 1 + sizeX]); } } if (x < (sizeX - 1)) { // right same line n->Neighbours.push_back(&nodes[thisNodeLocation + 1]); // right lower if (y > 0) { n->Neighbours.push_back(&nodes[thisNodeLocation + 1 - sizeX]); } // right upper if (y < (sizeY - 1)) { n->Neighbours.push_back(&nodes[thisNodeLocation + 1 + sizeX]); } } if (y > 0) { // lower one n->Neighbours.push_back(&nodes[thisNodeLocation - sizeX]); } if (y < (sizeY - 1)) { // upper one n->Neighbours.push_back(&nodes[thisNodeLocation + sizeX]); } } } } float dt = tm.end(); logging::Info() << "Building the Pathfinding grid took " << dt << " seconds"; }
int doWork(MPI_Datatype* ResultMpiType,const int k){ int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); int MAX_RESULT_SIZE = k; char msg[MAX_MSG_SIZE]; float cmpData[SEARCH_VECTOR_SIZE]; double times[2]; MPI_Status status; Timing parserTime; Timing searchTime; Timing workWallTime; workWallTime.start(); std::chrono::duration<double> read_time_elapse; MPI_Recv(cmpData, SEARCH_VECTOR_SIZE, MPI_FLOAT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); if(status.MPI_TAG != SEARCH_VECTOR){ std::cout<< rank << " recieved terminate signal" << std::endl; return 0; } while (1) { // Receive a message from the master MPI_Recv(msg, /* message buffer */ MAX_MSG_SIZE, /* buffer size */ MPI_CHAR, /* data item is an integer */ 0, /* Receive from master */ MPI_ANY_TAG, MPI_COMM_WORLD, /* default communicator */ &status); // Check if we have been terminated by the master // exit from the worker loop if (status.MPI_TAG == TERMINATE) { std::cout<< rank << " recieved terminate signal" << std::endl; return 0; } std::shared_ptr<MapString_t> nameMap(new MapString_t); std::vector<result_t> results; std::shared_ptr<std::vector<float>> dataVector(new std::vector<float>); Parser p(nameMap,dataVector); parserTime.start(); if(!p.parse_file(msg,&read_time_elapse)){ std::cerr<<"could not parse file: "<<msg<<std::endl; return 0; } parserTime.end(); searchTime.start(); int lineLength = p.get_line_length(); int index = 0; for(auto& file : *nameMap){ results.push_back(result_t()); results.at(index).distance = findDist(lineLength, dataVector,file.second,cmpData); strcpy(results.at(index).fileName,file.first.c_str()); index++; } std::sort(results.begin(),results.end(),resultPairSort); results.resize(MAX_RESULT_SIZE); searchTime.end(); MPI_Send(results.data(), /* message buffer */ MAX_RESULT_SIZE, /* buffer size */ *ResultMpiType, /* data item is an integer */ 0, /* destination process rank, the master */ RESULTS, /* user chosen message tag */ MPI_COMM_WORLD); workWallTime.end(); //add the times to an array to be sent to the master times[0] = parserTime.get_elapse(); times[1] = searchTime.get_elapse(); times[2] = workWallTime.get_elapse(); //send out the timing results to be compiled MPI_Send(times, NUM_TIME_RESULTS, MPI_DOUBLE, 0, TIMING, MPI_COMM_WORLD); } return 0; }