void ProgressReporter::PrintBar() { int barLength = TerminalWidth() - 28; int totalPlusses = std::max(2, barLength - (int)title.size()); int plussesPrinted = 0; // Initialize progress string const int bufLen = title.size() + totalPlusses + 64; std::unique_ptr<char[]> buf(new char[bufLen]); snprintf(buf.get(), bufLen, "\r%s: [", title.c_str()); char *curSpace = buf.get() + strlen(buf.get()); char *s = curSpace; for (int i = 0; i < totalPlusses; ++i) *s++ = ' '; *s++ = ']'; *s++ = ' '; *s++ = '\0'; fputs(buf.get(), stdout); fflush(stdout); std::chrono::milliseconds sleepDuration(250); int iterCount = 0; while (!exitThread) { std::this_thread::sleep_for(sleepDuration); // Periodically increase sleepDuration to reduce overhead of // updates. ++iterCount; if (iterCount == 10) // Up to 0.5s after ~2.5s elapsed sleepDuration *= 2; else if (iterCount == 70) // Up to 1s after an additional ~30s have elapsed. sleepDuration *= 2; Float percentDone = Float(workDone) / Float(totalWork); int plussesNeeded = std::round(totalPlusses * percentDone); while (plussesPrinted < plussesNeeded) { *curSpace++ = '+'; ++plussesPrinted; } fputs(buf.get(), stdout); // Update elapsed time and estimated time to completion Float seconds = ElapsedMS() / 1000.f; Float estRemaining = seconds / percentDone - seconds; if (percentDone == 1.f) printf(" (%.1fs) ", seconds); else if (!std::isinf(estRemaining)) printf(" (%.1fs|%.1fs) ", seconds, std::max((Float)0., estRemaining)); else printf(" (%.1fs|?s) ", seconds); fflush(stdout); } }
/** Helper function for Error(), Warning(), etc. @param type The type of message being printed (e.g. "Warning") @param p Position in source file that is connected to the message being printed @param fmt printf()-style format string @param args Arguments with values for format string % entries */ static void lPrint(const char *type, bool isError, SourcePos p, const char *fmt, va_list args) { char *errorBuf, *formattedBuf; if (vasprintf(&errorBuf, fmt, args) == -1) { fprintf(stderr, "vasprintf() unable to allocate memory!\n"); abort(); } int indent = 0; if (p.first_line == 0) { // We don't have a valid SourcePos, so create a message without it if (asprintf(&formattedBuf, "%s%s%s%s%s: %s%s", lStartBold(), isError ? lStartRed() : lStartBlue(), type, lResetColor(), lStartBold(), errorBuf, lResetColor()) == -1) { fprintf(stderr, "asprintf() unable to allocate memory!\n"); exit(1); } indent = lFindIndent(1, formattedBuf); } else { // Create an error message that includes the file and line number if (asprintf(&formattedBuf, "%s%s:%d:%d: %s%s%s%s: %s%s", lStartBold(), p.name, p.first_line, p.first_column, isError ? lStartRed() : lStartBlue(), type, lResetColor(), lStartBold(), errorBuf, lResetColor()) == -1) { fprintf(stderr, "asprintf() unable to allocate memory!\n"); exit(1); } indent = lFindIndent(3, formattedBuf); } // Don't indent too much with long filenames indent = std::min(indent, 8); // Now that we've done all that work, see if we've already printed the // exact same error message. If so, return, so we don't redundantly // print it and annoy the user. static std::set<std::string> printed; if (printed.find(formattedBuf) != printed.end()) return; printed.insert(formattedBuf); PrintWithWordBreaks(formattedBuf, indent, TerminalWidth(), stderr); lPrintFileLineContext(p); free(errorBuf); free(formattedBuf); }
// ProgressReporter Method Definitions ProgressReporter::ProgressReporter(int tw, const std::string &title) : totalWork(tw) { int barLength = TerminalWidth() - 28; totalPlusses = std::max(2, barLength - (int)title.size()); plussesPrinted = 0; workDone = 0; startTime = std::chrono::system_clock::now(); outFile = stdout; // Initialize progress string const int bufLen = title.size() + totalPlusses + 64; buf = new char[bufLen]; snprintf(buf, bufLen, "\r%s: [", title.c_str()); curSpace = buf + strlen(buf); char *s = curSpace; for (int i = 0; i < totalPlusses; ++i) *s++ = ' '; *s++ = ']'; *s++ = ' '; *s++ = '\0'; if (!PbrtOptions.quiet) { fputs(buf, outFile); fflush(outFile); } }
static void usage(int ret) { lPrintVersion(); printf("\nusage: ispc\n"); printf(" [--addressing={32,64}]\t\tSelect 32- or 64-bit addressing. (Note that 32-bit\n"); printf(" \t\taddressing calculations are done by default, even\n"); printf(" \t\ton 64-bit target architectures.)\n"); printf(" [--arch={%s}]\t\tSelect target architecture\n", Target::SupportedArchs()); printf(" [--c++-include-file=<name>]\t\tSpecify name of file to emit in #include statement in generated C++ code.\n"); #ifndef ISPC_IS_WINDOWS printf(" [--colored-output]\t\tAlways use terminal colors in error/warning messages.\n"); #endif printf(" "); char cpuHelp[2048]; sprintf(cpuHelp, "[--cpu=<cpu>]\t\t\tSelect target CPU type\n<cpu>={%s}\n", Target::SupportedCPUs().c_str()); PrintWithWordBreaks(cpuHelp, 16, TerminalWidth(), stdout); printf(" [-D<foo>]\t\t\t\t#define given value when running preprocessor\n"); printf(" [--dev-stub <filename>]\t\tEmit device-side offload stub functions to file\n"); printf(" [--emit-asm]\t\t\tGenerate assembly language file as output\n"); printf(" [--emit-c++]\t\t\tEmit a C++ source file as output\n"); printf(" [--emit-llvm]\t\t\tEmit LLVM bitode file as output\n"); printf(" [--emit-obj]\t\t\tGenerate object file file as output (default)\n"); printf(" [--force-alignment=<value>]\t\tForce alignment in memory allocations routine to be <value>\n"); printf(" [-g]\t\t\t\tGenerate debugging information\n"); printf(" [--help]\t\t\t\tPrint help\n"); printf(" [--help-dev]\t\t\tPrint help for developer options\n"); printf(" [--host-stub <filename>]\t\tEmit host-side offload stub functions to file\n"); printf(" [-h <name>/--header-outfile=<name>]\tOutput filename for header\n"); printf(" [-I <path>]\t\t\t\tAdd <path> to #include file search path\n"); printf(" [--instrument]\t\t\tEmit instrumentation to gather performance data\n"); printf(" [--math-lib=<option>]\t\tSelect math library\n"); printf(" default\t\t\t\tUse ispc's built-in math functions\n"); printf(" fast\t\t\t\tUse high-performance but lower-accuracy math functions\n"); printf(" svml\t\t\t\tUse the Intel(r) SVML math libraries\n"); printf(" system\t\t\t\tUse the system's math library (*may be quite slow*)\n"); printf(" [-MMM <filename>\t\t\t\tWrite #include dependencies to given file.\n"); printf(" [--nostdlib]\t\t\tDon't make the ispc standard library available\n"); printf(" [--nocpp]\t\t\t\tDon't run the C preprocessor\n"); printf(" [-o <name>/--outfile=<name>]\tOutput filename (may be \"-\" for standard output)\n"); printf(" [-O0/-O1]\t\t\t\tSet optimization level (-O1 is default)\n"); printf(" [--opt=<option>]\t\t\tSet optimization option\n"); printf(" disable-assertions\t\tRemove assertion statements from final code.\n"); printf(" disable-fma\t\t\tDisable 'fused multiply-add' instructions (on targets that support them)\n"); printf(" disable-loop-unroll\t\tDisable loop unrolling.\n"); printf(" fast-masked-vload\t\tFaster masked vector loads on SSE (may go past end of array)\n"); printf(" fast-math\t\t\tPerform non-IEEE-compliant optimizations of numeric expressions\n"); printf(" force-aligned-memory\t\tAlways issue \"aligned\" vector load and store instructions\n"); #ifndef ISPC_IS_WINDOWS printf(" [--pic]\t\t\t\tGenerate position-independent code\n"); #endif // !ISPC_IS_WINDOWS printf(" [--quiet]\t\t\t\tSuppress all output\n"); printf(" "); char targetHelp[2048]; sprintf(targetHelp, "[--target=<t>]\t\t\tSelect target ISA and width.\n" "<t>={%s}", Target::SupportedTargets()); PrintWithWordBreaks(targetHelp, 24, TerminalWidth(), stdout); printf(" [--version]\t\t\t\tPrint ispc version\n"); printf(" [--werror]\t\t\t\tTreat warnings as errors\n"); printf(" [--woff]\t\t\t\tDisable warnings\n"); printf(" [--wno-perf]\t\t\tDon't issue warnings related to performance-related issues\n"); printf(" <file to compile or \"-\" for stdin>\n"); exit(ret); }
// Error Reporting Functions static void processError(const char *format, va_list args, const char *errorType, int disposition) { // Report error if (disposition == PBRT_ERROR_IGNORE) return; // fprintf(stdout, format, args); // Build up an entire formatted error string and print it all at once; // this way, if multiple threads are printing messages at once, they // don't get jumbled up... std::string errorString; // // Print line and position in input file, if available // extern int line_num; // if (line_num != 0) { // extern string current_file; // errorString += current_file; // char buf[16]; // sprintf(buf, "(%d): ", line_num); // errorString += buf; // } // PBRT_ERROR_CONTINUE, PBRT_ERROR_ABORT // Print formatted error message int width = max(20, TerminalWidth() - 2); errorString += errorType; errorString += ": "; int column = errorString.size(); #if !defined(PBRT_IS_WINDOWS) char *errorBuf; if (vasprintf(&errorBuf, format, args) == -1) { fprintf(stderr, "vasprintf() unable to allocate memory!\n"); abort(); } #else char errorBuf[2048]; vsnprintf_s(errorBuf, sizeof(errorBuf), _TRUNCATE, format, args); #endif const char *msgPos = errorBuf; while (true) { while (*msgPos != '\0' && isspace(*msgPos)) ++msgPos; if (*msgPos == '\0') break; const char *wordEnd = findWordEnd(msgPos); if (column + wordEnd - msgPos > width) { errorString += "\n "; column = 4; } while (msgPos != wordEnd) { errorString += *msgPos++; ++column; } errorString += ' '; ++column; } fprintf(stderr, "%s\n", errorString.c_str()); if (disposition == PBRT_ERROR_ABORT) { #if defined(PBRT_IS_WINDOWS) __debugbreak(); #else abort(); #endif } #if !defined(PBRT_IS_WINDOWS) free(errorBuf); #endif }
static void processError(const char *format, va_list args, const char *errorType, int disposition) { // Report error if (disposition == PBRT_ERROR_IGNORE) return; // Build up an entire formatted error string and print it all at once; // this way, if multiple threads are printing messages at once, they // don't get jumbled up... std::string errorString; // Print line and position in input file, if available extern int line_num; if (line_num != 0) { extern std::string current_file; errorString += current_file; errorString += StringPrintf("(%d): ", line_num); } // PBRT_ERROR_CONTINUE, PBRT_ERROR_ABORT // Print formatted error message int width = std::max(20, TerminalWidth() - 2); errorString += errorType; errorString += ": "; int column = errorString.size(); std::string message = StringVaprintf(format, args); const char *msgPos = message.c_str(); while (true) { while (*msgPos != '\0' && isspace(*msgPos)) ++msgPos; if (*msgPos == '\0') break; const char *wordEnd = findWordEnd(msgPos); if (column + wordEnd - msgPos > width) { errorString += "\n "; column = 4; } while (msgPos != wordEnd) { errorString += *msgPos++; ++column; } errorString += ' '; ++column; } // Print the error message (but not more than one time). static std::string lastError; static std::mutex mutex; std::lock_guard<std::mutex> lock(mutex); if (errorString != lastError) { fprintf(stderr, "%s\n", errorString.c_str()); lastError = errorString; } if (disposition == PBRT_ERROR_ABORT) { #if defined(PBRT_IS_WINDOWS) __debugbreak(); #else abort(); #endif } }