7 #include <QCommandLineParser> 9 #define QT_SCALE_FACTOR "QT_SCALE_FACTOR" 10 #define QT_AUTO_SCREEN_SCALE_FACTOR "QT_AUTO_SCREEN_SCALE_FACTOR" 11 #define QT_SCREEN_SCALE_FACTORS "QT_SCREEN_SCALE_FACTORS" 20 QStringList
argsList(
int argc,
char* argv[]);
27 bool restart(QStringList args, QByteArray scaleFactors)
29 QString program = args[0];
31 args.append(
"--scale");
32 args.append(scaleFactors);
34 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) 36 proc.setProgram(args[0]);
37 proc.setArguments(args);
38 return proc.startDetached();
41 return QProcess::startDetached(program,args);
45 int main(
int argc,
char *argv[])
47 #if defined(Q_OS_WIN) && defined(QT_DEBUG) 49 int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
52 tmpFlag |= _CRTDBG_ALLOC_MEM_DF;
53 tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
54 tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF;
55 tmpFlag &= ~_CRTDBG_REPORT_FLAG;
58 _CrtSetDbgFlag( tmpFlag );
66 QCoreApplication::setOrganizationName(
"ti.fu-hagen.de");
67 QCoreApplication::setApplicationName(
"Frechet View");
70 QCoreApplication::setApplicationVersion(
"1.6.0");
77 QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
82 QCommandLineParser parser;
83 parser.setApplicationDescription(
"Fréchet Distance Free-Space Utility");
84 QCommandLineOption optVersion = parser.addVersionOption();
85 QCommandLineOption optHelp = parser.addHelpOption();
87 QCommandLineOption screenScale(
"scale",
"gui scale",
"scale-value");
88 parser.addPositionalArgument(
"input",
"input file (optional)",
"[*.svg,ipe,js,jscript]");
92 QCommandLineOption optCurve({
"curve",
"c"},
"Fréchet distance for polygonal curves");
93 QCommandLineOption optPoly({
"polygon",
"p"},
"Fréchet distance for simple polygons");
94 QCommandLineOption optKFrechet({
"kfrechet",
"k"},
"k-Fréchet distance\n");
96 QCommandLineOption optOptimize({
"optimize",
"opt"},
"calculate Fréchet distance (exact)");
97 QCommandLineOption optDecide({
"decide",
"dec"},
"decide whether Fréchet distance <= epsilon",
"epsilon");
98 QCommandLineOption optApprox({
"approx",
"app"},
"approximate to limited accuracy\n",
"accuracy");
100 QCommandLineOption optCores({
"cores",
"cpu"},
"run parallel on multiple cores",
"cores");
101 QCommandLineOption optGpu(
"gpu",
"GPU support");
102 QCommandLineOption optTile(
"tile",
"matrix tile size (n,m)",
"tile");
103 QCommandLineOption optTopo(
"large",
"large polygons\n");
106 parser.addOption(optCurve);
107 parser.addOption(optPoly);
108 parser.addOption(optKFrechet);
110 parser.addOption(optDecide);
111 parser.addOption(optOptimize);
112 parser.addOption(optApprox);
114 parser.addOption(optCores);
115 parser.addOption(optGpu);
116 parser.addOption(optTile);
117 parser.addOption(optTopo);
118 parser.addOption(screenScale);
120 QStringList args =
argsList(argc,argv);
121 bool optOk = parser.parse(args);
124 QCoreApplication qtApp(argc, argv);
125 std::cout << parser.errorText().toStdString() << std::endl << std::endl;
130 if (parser.isSet(optVersion)) {
131 QCoreApplication qtApp(argc, argv);
132 parser.showVersion();
136 if (parser.isSet(optHelp)) {
137 QCoreApplication qtApp(argc, argv);
144 if (parser.isSet(
"cores")) {
146 cores = parser.value(optCores).toInt(&intok);
147 if (!intok)
throw std::runtime_error(
"Number of cores expected.");
152 bool gpu = parser.isSet(optGpu);
153 bool topo = parser.isSet(optTopo);
156 QString inputFile =
"";
157 if (! parser.positionalArguments().isEmpty())
158 inputFile = parser.positionalArguments().first();
161 if ( parser.isSet(optCurve) || parser.isSet(optKFrechet) || parser.isSet(optPoly)
162 || parser.isSet(optOptimize) || parser.isSet(optDecide))
165 QCoreApplication qtApp(argc,argv);
166 FrechetViewApplication frApp(argv[0],
false);
167 parser.process(args);
171 if (parser.isSet(optTile)) {
172 QString tile_str = parser.value(optTile);
173 QStringList tile_strs = tile_str.split(QRegExp(
"\\D+"), QString::SkipEmptyParts);
174 if (tile_strs.size() >= 1) max_tile[0] = tile_strs[0].toUInt();
175 if (tile_strs.size() >= 2) max_tile[1] = tile_strs[1].toUInt();
181 if (inputFile.isEmpty())
throw std::runtime_error(
"Input file expected.");
182 if (! QFileInfo::exists(inputFile))
throw std::runtime_error(
"File "+inputFile.toStdString()+
" not found.");
186 if ((parser.isSet(optCurve) + parser.isSet(optPoly) + parser.isSet(optKFrechet)) > 1)
187 throw std::runtime_error(
"Please choose only one algorithm.");
189 if (parser.isSet(optCurve)) algo = FrechetViewApplication::Algorithm::ALGORITHM_CURVE;
190 if (parser.isSet(optPoly)) algo = FrechetViewApplication::Algorithm::ALGORITHM_POLYGON;
191 if (parser.isSet(optKFrechet)) algo = FrechetViewApplication::Algorithm::ALGORITHM_K_FRECHET;
192 if (algo==0) algo = FrechetViewApplication::Algorithm::ALGORITHM_CURVE;
194 if (topo && (algo != FrechetViewApplication::Algorithm::ALGORITHM_POLYGON))
195 throw std::runtime_error(
"Option --large is only applicable to -p.");
202 throw std::runtime_error(
"No compatible GPU found. Please install an OpenCL driver.");
204 if ( (parser.isSet(optDecide)+parser.isSet(optOptimize)+parser.isSet(optApprox)) >= 2 )
205 throw std::runtime_error(
"Please choose either -decide or -optimize or -approx, not both.");
206 if (parser.isSet(optDecide)) {
208 epsilon = parser.value(optDecide).toDouble(&ok);
209 if (!ok)
throw std::runtime_error(
"Epsilon expected for decision variant.");
211 if (parser.isSet(optOptimize)) accuracy=0.0;
212 if (parser.isSet(optApprox)) accuracy = parser.value(optApprox).toDouble(&ok);
213 if (!ok || (!std::isnan(accuracy) && (accuracy < 0.0)))
214 throw std::runtime_error(
"Accuracy expected for approximation variant.");
218 throw std::runtime_error(
">>> ERROR: no viable GPU device found. Use -nogpu instead.");
222 std::cout <<
">>> Info: core and gpu settings do not apply for this algorithm. Running on one core instead." << std::endl;
224 std::cout <<
" Info: using " 231 std::cout <<
" Info: using " 235 <<
" units." << std::endl
237 <<
"matrix tile = " << max_tile[0] <<
"," << max_tile[1]
241 return frApp.commandLineInterface(inputFile, algo, topo, accuracy, epsilon);
243 }
catch (std::exception& error) {
244 std::cout <<
">>> ERROR: " << error.what() << std::endl << std::endl << std::endl << std::endl;
277 QByteArray scaleFactors;
280 if (parser.isSet(screenScale)) {
282 scaleFactors = parser.value(
"scale").toLocal8Bit();
288 if (scaleFactors.isEmpty())
291 if (!scaleFactors.isEmpty())
296 if (!scaleFactors.isEmpty()) {
304 QApplication qtApp(argc,argv);
312 && !parser.isSet(
"scale"))
316 if (
restart(args,scaleFactors)) {
317 std::cout <<
"Relaunch with --scale " << scaleFactors.toStdString() << std::endl;
321 std::cout <<
"Relaunch failed " << std::endl;
326 QApplication qtApp(argc,argv);
330 std::cout <<
"WARNING: option --large is ignored. Use it only with command line option -p." << std::endl;
332 std::cout <<
"WARNING: option --gpu is ignored. Use it only with command line option -p." << std::endl;
334 FrechetViewApplication frApp(argv[0],
true);
335 frApp.init(inputFile);
342 for(
int i=0; i < argc; ++i)
343 result += QString::fromLocal8Bit(argv[i]);
352 QList<QScreen*> screens = QGuiApplication::screens();
353 foreach(QScreen* screen, screens)
363 qreal screenDpi = screen->logicalDotsPerInch();
364 if ((screenDpi < minDpi) || (screenDpi > maxDpi))
367 if (!factors.isEmpty()) factors +=
";";
368 factors += QByteArray::number(screen->devicePixelRatio() * screenDpi/targetDpi,
'g',2);
QStringList argsList(int argc, char *argv[])
size_t size2_t[2]
tow-dimensional size; used for various OpenCL parameters
global definitions for all algorithms.
static int countThreads()
static void maxMaxtrixTile(size2_t &)
set tile size for cubic matrix multiplication. Tiles adapt to local memory and/or compute units....
#define QT_SCREEN_SCALE_FACTORS
Algorithm
we have three Fréchet Distance algorithms
static bool hasGpuSupport()
static ConcurrencyContext instance
singleton instance
bool calculateScaleFactors(qreal minDpi, qreal targetDpi, qreal maxDpi, QByteArray &factors)
bool setupGpu(size2_t max_tile)
set up OpenCL context
static std::string gpuName()
bool restart(QStringList args, QByteArray scaleFactors)
static cl_uint countGpuUnits()
#define QT_AUTO_SCREEN_SCALE_FACTOR
int main(int argc, char *argv[])
void setup(int max_threads)
set up TBB thread count
compute k-Fréchet distance between two curves