From: Enblend <enb...@li...> - 2013-03-07 15:56:31
|
branch: details: http://enblend.hg.sourceforge.net/hgweb/enblend/enblend/hg/p/enblend/code/rev/080d5edf7492 changeset: 923:080d5edf7492 user: Chris <cs...@us...> date: Thu Mar 07 16:55:18 2013 +0100 description: Install some GPU-related command line options. diffstat: NEWS | 16 +++- VERSION | 2 +- doc/enblend.info | Bin doc/enblend.texi | 67 +++++++++++++++++++++-- doc/enfuse.info | Bin doc/enfuse.texi | 67 +++++++++++++++++++++-- doc/versenblend.texi | 6 +- doc/versenfuse.texi | 6 +- src/enblend.1 | 18 +++++- src/enblend.cc | 138 ++++++++++++++++++++++++++++++++++++++++++++++- src/enfuse.1 | 21 ++++++- src/enfuse.cc | 141 ++++++++++++++++++++++++++++++++++++++++++++++++- src/opencl.h | 147 +++++++++++++++++++++++++++++++++++++------------- 13 files changed, 557 insertions(+), 72 deletions(-) diffs (truncated from 956 to 500 lines): diff -r 227d89d02fb9 -r 080d5edf7492 NEWS --- a/NEWS Thu Mar 07 13:09:59 2013 +0100 +++ b/NEWS Thu Mar 07 16:55:18 2013 +0100 @@ -20,6 +20,11 @@ is now up to the user. The default still is the Gauss function as in all Enfuse versions before. +- Enblend and Enfuse now both can make use of the tremendous computing + power in modern graphics cards. To that end the binaries must be + compiled with OpenCL support and the necessary drivers and or + linraries must be installed on the host system. + ** New Commandline Options @@ -35,12 +40,13 @@ Options `--exposure-mu' and `--exposure-sigma' are scheduled for withdrawal in a later version of Enfuse. +- For a long time Enblend has had an option to run the seam-line + optimizer on the GPU. Now, both Enblend and Enfuse sport `--gpu' + options to offload computationally intensive tasks to any + OpenCL-compatible GPU device. -** Removed Commandline Options - -- All functionality behind the GPU acceleration option `--gpu' was - removed. The option itself is still valid, but does not do - anything. + On systems with more than one device `--prefer-gpu' selects the + desired GPU. ** Developer Stuff diff -r 227d89d02fb9 -r 080d5edf7492 VERSION --- a/VERSION Thu Mar 07 13:09:59 2013 +0100 +++ b/VERSION Thu Mar 07 16:55:18 2013 +0100 @@ -1,1 +1,1 @@ -4.2-4dc17c0df775 +4.2-227d89d02fb9 diff -r 227d89d02fb9 -r 080d5edf7492 doc/enblend.info Binary file doc/enblend.info has changed diff -r 227d89d02fb9 -r 080d5edf7492 doc/enblend.texi --- a/doc/enblend.texi Thu Mar 07 13:09:59 2013 +0100 +++ b/doc/enblend.texi Thu Mar 07 16:55:18 2013 +0100 @@ -452,6 +452,32 @@ @file{png}-files with the @sc{Deflate} method. @end table +@item --gpu +@opindex --gpu +@cindex graphics processing unit +@cindex GPU +@cindex central processing unit +@cindex CPU +@cindex OpenCL +Employ one of the graphics processing units (@acronym{GPU}s) to +perform selected operations instead of the central processing units +(@acronym{CPU}s) alone. Enblend must have been compiled with support +for @acronym{OpenCL} access to the @acronym{GPU} for this feature. + +Depending on the input images, the options passed to Enblend, and the +relative performance of the @acronym{CPU}s to the @acronym{GPU}s this +option may or may not increase performance. + +Negate this option with @option{--no-gpu}. + +See also option@tie{}@option{--prefer-gpu}. + +@item -h +@itemx --help +@opindex -h +@opindex --help +Print information on the available options and exit. + @item --layer-selector=@var{ALGORITHM} @opindex --layer-selector @cindex layer selection @@ -485,12 +511,6 @@ response files. @end table -@item -h -@itemx --help -@opindex -h -@opindex --help -Print information on the available options and exit. - @item -l @var{LEVELS} @itemx --levels=@var{LEVELS} @opindex -l @@ -627,6 +647,41 @@ Parameters allow the developers to change the internal workings of Enblend without the need to recompile. +@item --prefer-gpu +@itemx --prefer-gpu=DEVICE +@itemx --prefer-gpu=PLATFORM:DEVICE +@cindex GPU +@cindex OpenCL +@cindex OpenCL, platform +@cindex OpenCL, device +When told to employ the @acronym{GPU} with @option{--gpu}, by default +Enblend uses the first device on the first platform it finds via +queries of the @acronym{OpenCL} subsystem, where neither the device, +nor the platform may be the ones the user wants. Usually she will +select the device with the highest performance, largest associated +memory or most expansive maximum image size. + +The first form of @option{--prefer-gpu} prints a list of all available +devices on all accessible platforms and then exits; it is the same +enumeration that @samp{enblend --verbose --version} reveals. The +first entry is the default preferred device. Example: +@example +Available, OpenCL-compatible platform(s) and their device(s) + - Platform #1: NVIDIA Corporation, NVIDIA CUDA, OpenCL 1.1 CUDA 4.2.1 + * Device #1: 2 cores + 1047872 KB global memory + 48 KB local memory + 32768x32768 maximum image size +@end example + +Use the numbers of platforms and devices found there to select the +desired @var{DEVICE} on the first platform (second form) or +@var{DEVICE} on the given @var{PLATFORM} (third form). + +Enblend's default is equivalent to @samp{--prefer-gpu=1:1}. + +See also option@tie{}@option{--gpu}. + @item -v @itemx --verbose[=@var{LEVEL}] @opindex -v diff -r 227d89d02fb9 -r 080d5edf7492 doc/enfuse.info Binary file doc/enfuse.info has changed diff -r 227d89d02fb9 -r 080d5edf7492 doc/enfuse.texi --- a/doc/enfuse.texi Thu Mar 07 13:09:59 2013 +0100 +++ b/doc/enfuse.texi Thu Mar 07 16:55:18 2013 +0100 @@ -562,6 +562,32 @@ @file{png}-files with the @sc{Deflate} method. @end table +@item --gpu +@opindex --gpu +@cindex graphics processing unit +@cindex GPU +@cindex central processing unit +@cindex CPU +@cindex OpenCL +Employ one of the graphics processing units (@acronym{GPU}s) to +perform selected operations instead of the central processing units +(@acronym{CPU}s) alone. Enblend must have been compiled with support +for @acronym{OpenCL} access to the @acronym{GPU} for this feature. + +Depending on the input images, the options passed to Enblend, and the +relative performance of the @acronym{CPU}s to the @acronym{GPU}s this +option may or may not increase performance. + +Negate this option with @option{--no-gpu}. + +See also option@tie{}@option{--prefer-gpu}. + +@item -h +@itemx --help +@opindex -h +@opindex --help +Print information on the available options and exit. + @item --layer-selector=@var{ALGORITHM} @opindex --layer-selector @cindex layer selection @@ -595,12 +621,6 @@ response files. @end table -@item -h -@itemx --help -@opindex -h -@opindex --help -Print information on the available options and exit. - @item -l @var{LEVELS} @itemx --levels=@var{LEVELS} @opindex -l @@ -736,6 +756,41 @@ Parameters allow the developers to change the internal workings of Enfuse without the need to recompile. +@item --prefer-gpu +@itemx --prefer-gpu=DEVICE +@itemx --prefer-gpu=PLATFORM:DEVICE +@cindex GPU +@cindex OpenCL +@cindex OpenCL, platform +@cindex OpenCL, device +When told to employ the @acronym{GPU} with @option{--gpu}, by default +Enblend uses the first device on the first platform it finds via +queries of the @acronym{OpenCL} subsystem, where neither the device, +nor the platform may be the ones the user wants. Usually she will +select the device with the highest performance, largest associated +memory or most expansive maximum image size. + +The first form of @option{--prefer-gpu} prints a list of all available +devices on all accessible platforms and then exits; it is the same +enumeration that @samp{enblend --verbose --version} reveals. The +first entry is the default preferred device. Example: +@example +Available, OpenCL-compatible platform(s) and their device(s) + - Platform #1: NVIDIA Corporation, NVIDIA CUDA, OpenCL 1.1 CUDA 4.2.1 + * Device #1: 2 cores + 1047872 KB global memory + 48 KB local memory + 32768x32768 maximum image size +@end example + +Use the numbers of platforms and devices found there to select the +desired @var{DEVICE} on the first platform (second form) or +@var{DEVICE} on the given @var{PLATFORM} (third form). + +Enblend's default is equivalent to @samp{--prefer-gpu=1:1}. + +See also option@tie{}@option{--gpu}. + @item -v @itemx --verbose[=@var{LEVEL}] @opindex -v diff -r 227d89d02fb9 -r 080d5edf7492 doc/versenblend.texi --- a/doc/versenblend.texi Thu Mar 07 13:09:59 2013 +0100 +++ b/doc/versenblend.texi Thu Mar 07 16:55:18 2013 +0100 @@ -1,4 +1,4 @@ -@set UPDATED 3 March 2013 +@set UPDATED 7 March 2013 @set UPDATED-MONTH March 2013 -@set EDITION 4.2-1a6e8e29398a -@set VERSION 4.2-1a6e8e29398a +@set EDITION 4.2-227d89d02fb9 +@set VERSION 4.2-227d89d02fb9 diff -r 227d89d02fb9 -r 080d5edf7492 doc/versenfuse.texi --- a/doc/versenfuse.texi Thu Mar 07 13:09:59 2013 +0100 +++ b/doc/versenfuse.texi Thu Mar 07 16:55:18 2013 +0100 @@ -1,4 +1,4 @@ -@set UPDATED 3 March 2013 +@set UPDATED 7 March 2013 @set UPDATED-MONTH March 2013 -@set EDITION 4.2-1a6e8e29398a -@set VERSION 4.2-1a6e8e29398a +@set EDITION 4.2-227d89d02fb9 +@set VERSION 4.2-227d89d02fb9 diff -r 227d89d02fb9 -r 080d5edf7492 src/enblend.1 --- a/src/enblend.1 Thu Mar 07 13:09:59 2013 +0100 +++ b/src/enblend.1 Thu Mar 07 16:55:18 2013 +0100 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. -.TH ENBLEND "1" "March 2013" "enblend 4.2-3958ca9f5128" "User Commands" +.TH ENBLEND "1" "March 2013" "enblend 4.2-227d89d02fb9" "User Commands" .SH NAME -enblend \- manual page for enblend 4.2-3958ca9f5128 +enblend \- manual page for enblend 4.2-227d89d02fb9 .SH SYNOPSIS .B enblend [\fIoptions\fR] [\fI--output=IMAGE\fR] \fIINPUT\fR... @@ -38,6 +38,20 @@ "horizontal", "vertical", or "both"; default: none; without argument the option selects horizontal wrapping .TP +\fB\-\-gpu\fR +employ GPU in addition to CPU for selected computations; negate +with "\-\-no\-gpu" +.TP +\fB\-\-prefer\-gpu\fR +list all available GPUs according to their platform and device; +start with the preferred one +.TP +\fB\-\-prefer\-gpu\fR=\fIDEVICE\fR +select DEVICE on first platform as GPU +.TP +\fB\-\-prefer\-gpu\fR=\fIPLATFORM\fR:DEVICE +select DEVICE on PLATFORM as GPU +.TP \fB\-x\fR checkpoint partial results .TP diff -r 227d89d02fb9 -r 080d5edf7492 src/enblend.cc --- a/src/enblend.cc Thu Mar 07 13:09:59 2013 +0100 +++ b/src/enblend.cc Thu Mar 07 16:55:18 2013 +0100 @@ -173,6 +173,13 @@ #include "filespec.h" #include "enblend.h" +bool UseGPU = false; +#ifdef OPENCL +cl::Platform GPUPlatform; +cl::Device GPUDevice; +cl::Context* GPUContext = NULL; +#endif + #ifdef DMALLOC #include "dmalloc.h" // must be last #include #endif @@ -210,6 +217,7 @@ "+ Verbose = " << Verbose << ", option \"--verbose\"\n" << "+ OutputFileName = <" << OutputFileName << ">\n" << "+ ExactLevels = " << ExactLevels << "\n" << + "+ UseGPU = " << UseGPU << "\n" << "+ OneAtATime = " << enblend::stringOfBool(OneAtATime) << ", option \"-a\"\n" << "+ WrapAround = " << enblend::stringOfWraparound(WrapAround) << ", option \"--wrap\"\n" << "+ GimpAssociatedAlphaHack = " << enblend::stringOfBool(GimpAssociatedAlphaHack) << @@ -316,7 +324,7 @@ #ifdef OPENCL std::cout << "Extra feature: OpenCL: yes\n"; - print_opencl_information(); + ocl::print_opencl_information(); #else std::cout << "Extra feature: OpenCL: no\n"; #endif @@ -378,6 +386,15 @@ " \"horizontal\", \"vertical\", or \"both\"; default: " << enblend::stringOfWraparound(WrapAround) << ";\n" << " without argument the option selects horizontal wrapping\n" << +#ifdef OPENCL + " --gpu employ GPU in addition to CPU for selected computations; negate\n" << + " with \"--no-gpu\"\n" << + " --prefer-gpu list all available GPUs according to their platform and device;\n" << + " start with the preferred one\n" << + " --prefer-gpu=DEVICE select DEVICE on first platform as GPU\n" << + " --prefer-gpu=PLATFORM:DEVICE\n" << + " select DEVICE on PLATFORM as GPU\n" << +#endif " -x checkpoint partial results\n" << " --compression=COMPRESSION\n" << " set compression of output image to COMPRESSION,\n" << @@ -523,7 +540,8 @@ OutputOption, VerboseOption, WrapAroundOption /* -w */, CheckpointOption /* -x */, CompressionOption, LZWCompressionOption, BlockSizeOption, CIECAM02Option, NoCIECAM02Option, FallbackProfileOption, - DepthOption, AssociatedAlphaOption /* -g */, GPUOption, + DepthOption, AssociatedAlphaOption /* -g */, + GPUOption, NoGPUOption, PreferredGPUOption, SizeAndPositionOption /* -f */, CacheSizeOption, VisualizeOption, CoarseMaskOption, FineMaskOption, OptimizeOption, NoOptimizeOption, @@ -696,7 +714,26 @@ ": warning: because it was compiled without image cache" << std::endl; } -#endif +#endif // CACHE_IMAGES + +#ifdef OPENCL + if (!UseGPU && contains(optionSet, PreferredGPUOption)) { + std::cerr << command << ": warning: option \"--preferred-gpu\" has no effect without enabled GPU" << std::endl; + } +#else + if (contains(optionSet, GPUOption)) { + std::cerr << command << ": warning: option \"--gpu\" has no effect in this " << command << " binary,\n" << + command << ": warning: because it was compiled without support for OpenGL" << std::endl; + } + if (contains(optionSet, NoGPUOption)) { + std::cerr << command << ": warning: option \"--no-gpu\" has no effect in this " << command << " binary,\n" << + command << ": warning: because it was compiled without support for OpenGL" << std::endl; + } + if (contains(optionSet, PreferredGPUOption)) { + std::cerr << command << ": warning: option \"--prefer-gpu\" has no effect in this " << command << " binary,\n" << + command << ": warning: because it was compiled without support for OpenGL" << std::endl; + } +#endif // OPENCL } @@ -705,6 +742,8 @@ enum OptionId { OPTION_ID_OFFSET = 1023, // Ids start at 1024 UseGpuId, + NoUseGpuId, + PreferGpuId, CoarseMaskId, FineMaskId, OptimizeMaskId, @@ -736,6 +775,9 @@ static struct option long_options[] = { {"gpu", no_argument, 0, UseGpuId}, + {"no-gpu", no_argument, 0, NoUseGpuId}, + {"prefer-gpu", optional_argument, 0, PreferGpuId}, + {"preferred-gpu", optional_argument, 0, PreferGpuId}, // gramatically close alternative form {"coarse-mask", optional_argument, 0, CoarseMaskId}, {"fine-mask", no_argument, 0, FineMaskId}, {"optimize", no_argument, 0, OptimizeMaskId}, @@ -772,6 +814,10 @@ bool justPrintVersion = false; bool justPrintUsage = false; OptionSetType optionSet; +#ifdef OPENCL + size_t preferredGPUPlatform = 1U; // We start enumerating platforms at 1 for user convenience. + size_t preferredGPUDevice = 1U; // ditto for devices +#endif opterr = 0; // we have our own "unrecognized option" message while (true) { @@ -785,7 +831,34 @@ switch (code) { case UseGpuId: - // no effect whatsover + UseGPU = true; + optionSet.insert(GPUOption); + break; + + case NoUseGpuId: + UseGPU = false; + optionSet.insert(NoGPUOption); + break; + + case PreferGpuId: +#ifdef OPENCL + if (optarg != NULL && *optarg != 0) { + char* delimiter = strpbrk(optarg, NUMERIC_OPTION_DELIMITERS); + if (delimiter == NULL) { + preferredGPUDevice = enblend::numberOfString(optarg, _1 >= 1U, "preferred GPU device out of range", 1U); + } else { + *delimiter = 0; + ++delimiter; + preferredGPUPlatform = enblend::numberOfString(optarg, _1 >= 1U, "preferred GPU platform out of range", 1U); + preferredGPUDevice = enblend::numberOfString(delimiter, _1 >= 1U, "preferred GPU device out of range", 1U); + } + } else { + std::cout << "Available, OpenCL-compatible platform(s) and their device(s)\n"; + ocl::print_opencl_information(); + exit(0); + } +#endif + optionSet.insert(PreferredGPUOption); break; case FineMaskId: @@ -1525,6 +1598,59 @@ warn_of_ineffective_options(optionSet); +#ifdef OPENCL + if (UseGPU) { + cl_int error_code; + + ocl::platform_list_t platforms; + error_code = cl::Platform::get(&platforms); + + if (error_code != CL_SUCCESS) { + std::cerr << command << ": warning: query for OpenCL platforms failed, cannot enable GPU: " << + ocl::string_of_error_code(error_code) << "\n"; + } else if (platforms.empty()) { + std::cerr << command << ": warning: no OpenCL platform found, cannot enable GPU\n"; + } else { + if (preferredGPUPlatform <= platforms.size()) { + GPUPlatform = platforms[preferredGPUPlatform - 1U]; + } else { + std::cerr << command << ": OpenCL platform #" << preferredGPUPlatform << " is not available\n"; + std::cerr << command << ": info: largest OpenCL platform number is " << platforms.size() << "\n"; + exit(1); + } + + ocl::device_list_t devices; + error_code = GPUPlatform.getDevices(CL_DEVICE_TYPE_GPU, &devices); + + if (error_code != CL_SUCCESS) { + std::cerr << command << ": warning: query for OpenCL devices failed, cannot enable GPU: " << + ocl::string_of_error_code(error_code) << "\n"; + } else if (devices.empty()) { + std::cerr << command << ": warning: no OpenCL device found, cannot enable GPU\n"; + } else { + if (preferredGPUDevice <= devices.size()) { + GPUDevice = devices[preferredGPUDevice - 1U]; + } else { + std::cerr << command << ": OpenCL device #" << preferredGPUDevice << " is not available\n"; + std::cerr << command << ": info: largest OpenCL device number is " << devices.size() << "\n"; + exit(1); + } + + cl_context_properties context_properties[] = { + CL_CONTEXT_PLATFORM, (cl_context_properties) (GPUPlatform)(), 0 + }; + GPUContext = new cl::Context(CL_DEVICE_TYPE_GPU, context_properties, NULL, NULL, &error_code); + if (error_code != CL_SUCCESS) { + delete GPUContext; + GPUContext = NULL; + std::cerr << command << ": warning: failed to create OpenCL context, cannot enable GPU: " << + ocl::string_of_error_code(error_code) << "\n"; + } + } + } + } +#endif // OPENCL + return optind; } @@ -2165,6 +2291,10 @@ exit(1); } |