template <class T> bool karbtest (Connector<T>* rc) { GradientParams gp; std::string in_file;// = std::string (base + "/" + std::string(rc->GetElement("/config/data-in")->Attribute("fname"))); std::string out_file;// = std::string (base + "/" + rc->GetElement("/config/data-out")->Attribute("fname")); bool simann = false; size_t hpoints = 1; rc->Attribute ("simann", &simann); rc->Attribute ("hpoints", &hpoints); if (simann) { double coolrate, startt, finalt; size_t coolit; bool verbose, exchange; rc->Attribute ("coolrate", &coolrate); rc->Attribute ("startt", &startt); rc->Attribute ("finalt", &finalt); rc->Attribute ("coolit", &coolit); rc->Attribute ("verbose", &verbose); rc->Attribute ("exchange", &exchange); SimulatedAnnealing sa (gp.k, coolit, startt, finalt, coolrate, verbose, exchange); sa.Cool(); gp.k = sa.GetSolution(); } rc->Attribute ("maxgrad", &(gp.mgr)); rc->Attribute ("maxslew", &(gp.msr)); rc->Attribute ("dt", &(gp.dt)); rc->Attribute ("gunits", &(gp.gunits)); rc->Attribute ("lunits", &(gp.lunits)); Matrix<double> x = linspace<double> (0.0,1.0,size(gp.k,0)); Matrix<double> xi = linspace<double> (0.0,1.0,size(gp.k,0)*hpoints); gp.k = interp1 (x, gp.k, xi, INTERP::AKIMA); printf ("\nComputing trajectory for ... \n"); printf (" [maxgrad: %.2f, maxslew: %.2f, dt: %.2e]\n\n", gp.mgr, gp.msr, gp.dt); SimpleTimer st ("VD spiral design"); Solution s = ComputeGradient (gp); st.Stop(); IOContext f = fopen (out_file.c_str(), WRITE); s.dump (f); fclose (f); return true; }
void doTest(const int numThreads, std::thread* threads, const bool stest, const bool locking) { iterations = 1; do { SimpleTimer timer; timer.Start(); //initialize testing threads, then wait for all threads to finish if(stest) { for(int i = 0; i < numThreads; ++i) { threads[i] = std::thread(StackSThread); } } else { for(int i = 0; i < numThreads; ++i) { threads[i] = std::thread(StackTThread); } } for(int i = 0; i < numThreads; ++i) { threads[i].join(); } timer.Stop(); while(!stack->IsEmpty()) { delete (stack->Pop()); } std::cout << (locking ? "Locking " : "LockFree ") << (stest ? "STest " : "TTest ") << iterations << " inner iterations with " << numThreads << " threads: " << timer.ElapsedMilliseconds() << std::endl; std::ofstream outfile; outfile.open(OUTPUT_FILE, std::ios_base::app); outfile << (locking ? "L," : "F,") << (stest ? "S," : "T,") << iterations << "," << numThreads << "," << timer.ElapsedMilliseconds() << std::endl; outfile.close(); iterations = iterations << 1; } while(iterations < MAX_INNER_ITERATIONS); }
int doParallelSuperPMI(CommandLine::Options& o) { HRESULT hr = E_FAIL; SimpleTimer st; st.Start(); #ifndef FEATURE_PAL // TODO-Porting: handle Ctrl-C signals gracefully on Unix //Register a ConsoleCtrlHandler if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) { LogError("Failed to set control handler."); return 1; } #endif // !FEATURE_PAL char tempPath[MAX_PATH]; if (!GetTempPath(MAX_PATH, tempPath)) { LogError("Failed to get path to temp folder."); return 1; } if (o.workerCount <= 0) { //Use the default value which is the number of processors on the machine. SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); o.workerCount = sysinfo.dwNumberOfProcessors; //If we ever execute on a machine which has more than MAXIMUM_WAIT_OBJECTS(64) CPU cores //we still can't spawn more than the max supported by WaitForMultipleObjects() if (o.workerCount > MAXIMUM_WAIT_OBJECTS) o.workerCount = MAXIMUM_WAIT_OBJECTS; } // Obtain the folder path of the current executable, which we will use to spawn ourself. char* spmiFilename = new char[MAX_PATH]; if (!GetModuleFileName(NULL, spmiFilename, MAX_PATH)) { LogError("Failed to get current exe path."); return 1; } char* spmiArgs = ConstructChildProcessArgs(o); // TODO: merge all this output to a single call to LogVerbose to avoid all the newlines. LogVerbose("Using child (%s) with args (%s)", spmiFilename, spmiArgs); if (o.mclFilename != nullptr) LogVerbose(" failingMCList=%s", o.mclFilename); if (o.diffMCLFilename != nullptr) LogVerbose(" diffMCLFilename=%s", o.diffMCLFilename); LogVerbose(" workerCount=%d, skipCleanup=%d.", o.workerCount, o.skipCleanup); HANDLE *hProcesses = new HANDLE[o.workerCount]; HANDLE *hStdOutput = new HANDLE[o.workerCount]; HANDLE *hStdError = new HANDLE[o.workerCount]; char** arrFailingMCListPath = new char*[o.workerCount]; char** arrDiffMCListPath = new char*[o.workerCount]; char** arrStdOutputPath = new char*[o.workerCount]; char** arrStdErrorPath = new char*[o.workerCount]; // Add a random number to the temporary file names to allow multiple parallel SuperPMI to happen at once. unsigned int randNumber = 0; #ifdef FEATURE_PAL PAL_Random(/* bStrong */ FALSE, &randNumber, sizeof(randNumber)); #else // !FEATURE_PAL rand_s(&randNumber); #endif // !FEATURE_PAL for (int i = 0; i < o.workerCount; i++) { if (o.mclFilename != nullptr) { arrFailingMCListPath[i] = new char[MAX_PATH]; sprintf_s(arrFailingMCListPath[i], MAX_PATH, "%sParallelSuperPMI-%u-%d.mcl", tempPath, randNumber, i); } else { arrFailingMCListPath[i] = nullptr; } if (o.diffMCLFilename != nullptr) { arrDiffMCListPath[i] = new char[MAX_PATH]; sprintf_s(arrDiffMCListPath[i], MAX_PATH, "%sParallelSuperPMI-Diff-%u-%d.mcl", tempPath, randNumber, i); } else { arrDiffMCListPath[i] = nullptr; } arrStdOutputPath[i] = new char[MAX_PATH]; arrStdErrorPath[i] = new char[MAX_PATH]; sprintf_s(arrStdOutputPath[i], MAX_PATH, "%sParallelSuperPMI-stdout-%u-%d.txt", tempPath, randNumber, i); sprintf_s(arrStdErrorPath[i], MAX_PATH, "%sParallelSuperPMI-stderr-%u-%d.txt", tempPath, randNumber, i); } char cmdLine[MAX_CMDLINE_SIZE]; cmdLine[0] = '\0'; int bytesWritten; for (int i = 0; i < o.workerCount; i++) { bytesWritten = sprintf_s(cmdLine, MAX_CMDLINE_SIZE, "%s -stride %d %d", spmiFilename, i + 1, o.workerCount); if (o.mclFilename != nullptr) { bytesWritten += sprintf_s(cmdLine + bytesWritten, MAX_CMDLINE_SIZE - bytesWritten, " -failingMCList %s", arrFailingMCListPath[i]); } if (o.diffMCLFilename != nullptr) { bytesWritten += sprintf_s(cmdLine + bytesWritten, MAX_CMDLINE_SIZE - bytesWritten, " -diffMCList %s", arrDiffMCListPath[i]); } bytesWritten += sprintf_s(cmdLine + bytesWritten, MAX_CMDLINE_SIZE - bytesWritten, " -v ewmin %s", spmiArgs); SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; // Let newly created stdout/stderr handles be inherited. LogDebug("stdout %i=%s", i, arrStdOutputPath[i]); hStdOutput[i] = CreateFileA(arrStdOutputPath[i], GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hStdOutput[i] == INVALID_HANDLE_VALUE) { LogError("Unable to open '%s'. GetLastError()=%u", arrStdOutputPath[i], GetLastError()); return -1; } LogDebug("stderr %i=%s", i, arrStdErrorPath[i]); hStdError[i] = CreateFileA(arrStdErrorPath[i], GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hStdError[i] == INVALID_HANDLE_VALUE) { LogError("Unable to open '%s'. GetLastError()=%u", arrStdErrorPath[i], GetLastError()); return -1; } //Create a SuperPMI worker process and redirect its output to file if (!StartProcess(cmdLine, hStdOutput[i], hStdError[i], &hProcesses[i])) { return -1; } } WaitForMultipleObjects(o.workerCount, hProcesses, true, INFINITE); // Close stdout/stderr for (int i = 0; i < o.workerCount; i++) { CloseHandle(hStdOutput[i]); CloseHandle(hStdError[i]); } DWORD exitCode = 0; // 0 == assume success if (!closeRequested) { // Figure out the error code to use. We use the largest magnitude error code of the children. // Mainly, if any child returns non-zero, we want to return non-zero, to indicate failure. for (int i = 0; i < o.workerCount; i++) { DWORD exitCodeTmp; BOOL ok = GetExitCodeProcess(hProcesses[i], &exitCodeTmp); if (ok && (exitCodeTmp > exitCode)) { exitCode = exitCodeTmp; } } bool usageError = false; //variable to flag if we hit a usage error in SuperPMI int loaded = 0, jitted = 0, failed = 0, diffs = 0; //Read the stderr files and log them as errors //Read the stdout files and parse them for counts and log any MISSING or ISSUE errors for (int i = 0; i < o.workerCount; i++) { ProcessChildStdErr(arrStdErrorPath[i]); ProcessChildStdOut(o, arrStdOutputPath[i], &loaded, &jitted, &failed, &diffs, &usageError); if (usageError) break; } if (o.mclFilename != nullptr && !usageError) { //Concat the resulting .mcl files MergeWorkerMCLs(o.mclFilename, arrFailingMCListPath, o.workerCount); } if (o.diffMCLFilename != nullptr && !usageError) { //Concat the resulting diff .mcl files MergeWorkerMCLs(o.diffMCLFilename, arrDiffMCListPath, o.workerCount); } if (!usageError) { if (o.applyDiff) { LogInfo(g_AsmDiffsSummaryFormatString, loaded, jitted, failed, diffs); } else { LogInfo(g_SummaryFormatString, loaded, jitted, failed); } } st.Stop(); LogVerbose("Total time: %fms", st.GetMilliseconds()); } if (!o.skipCleanup) { // Delete all temporary files generated for (int i = 0; i < o.workerCount; i++) { if (arrFailingMCListPath[i] != nullptr) { DeleteFile(arrFailingMCListPath[i]); } if (arrDiffMCListPath[i] != nullptr) { DeleteFile(arrDiffMCListPath[i]); } DeleteFile(arrStdOutputPath[i]); DeleteFile(arrStdErrorPath[i]); } } return (int)exitCode; }