42 #include "boost/cstdint.hpp"
62 namespace pexExcept = lsst::pex::exceptions;
63 namespace pexLog = lsst::pex::logging;
64 namespace afwGeom = lsst::afw::geom;
66 namespace afwMath = lsst::afw::math;
67 namespace afwGpu = lsst::afw::gpu;
68 namespace mathDetail = lsst::afw::math::detail;
69 namespace gpuDetail = lsst::afw::gpu::detail;
78 template <
typename PixelT>
87 img.
Init(width, height);
88 var.
Init(width, height);
89 msk.
Init(width, height);
92 ::x_iterator x_iterator;
95 for (
int i = 0; i < height; ++i) {
96 x_iterator inPtr = image.
x_at(0, i);
101 for (x_iterator cnvEnd = inPtr + width; inPtr != cnvEnd;
102 ++inPtr, ++imageDataPtr, ++imageMaskPtr, ++imageVarPtr ) {
103 *imageDataPtr = (*inPtr).image();
104 *imageMaskPtr = (*inPtr).mask();
105 *imageVarPtr = (*inPtr).variance();
111 template <
typename PixelT>
113 int startX,
int startY,
125 ::x_iterator x_iterator;
127 for (
int i = 0; i < img.
height; ++i) {
132 for (x_iterator cnvPtr = outImage.
x_at(startX, i + startY),
133 cnvEnd = cnvPtr + img.
width; cnvPtr != cnvEnd; ++cnvPtr )
135 *cnvPtr =
typename x_iterator::type(*outPtrImg, *outPtrMsk, *outPtrVar);
169 template <
typename OutImageT,
typename InImageT>
171 OutImageT &convolvedImage,
172 InImageT
const& inImage,
177 throw LSST_EXCEPT(afwGpu::GpuRuntimeError,
"Afw not compiled with GPU support");
188 pexLog::TTrace<4>(
"lsst.afw.math.convolve",
189 "generic basicConvolve (GPU): dispatch to convolveLinearCombinationGPU");
191 *dynamic_cast<afwMath::LinearCombinationKernel const*>(&kernel),
196 pexLog::TTrace<3>(
"lsst.afw.math.convolve",
197 "generic basicConvolve (GPU): dispatch to convolveSpatiallyInvariantGPU");
225 template <
typename OutPixelT,
typename InPixelT>
233 throw LSST_EXCEPT(afwGpu::GpuRuntimeError,
"Afw not compiled with GPU support");
241 pexLog::TTrace<3>(
"lsst.afw.math.convolve",
242 "convolveLinearCombinationGPU: spatially invariant; will delegate");
258 refKernelPtr = kernel.
clone();
262 refKernelPtr = kernel.
clone();
268 assert(newKernel!=NULL);
272 if (sFn.size() < 1) {
275 if (
int(sFn.size()) != kernelN) {
278 bool isAllCheby =
true;
279 for (
int i = 0; i < kernelN; i++) {
284 bool isAllPoly =
true;
285 for (
int i = 0; i < kernelN; i++) {
300 }
else if(isAllCheby) {
312 const int minKernelSize = 25;
322 if (!shMemOkA || !shMemOkB) {
330 for (
int i = 0; i < kernelN; i++) {
331 if (kernelList[i]->getDimensions() != newKernel->
getDimensions()
332 || kernelList[i]->getCtr() != newKernel->
getCtr()
337 pexLog::TTrace<3>(
"lsst.afw.math.convolve",
338 "MaskedImage, convolveLinearCombinationGPU: will use GPU acceleration");
340 std::vector< KernelBuffer > basisKernels(kernelN);
341 for (
int i = 0; i < kernelN; i++) {
342 KernelImage kernelImage(kernelList[i]->getDimensions());
343 (void)kernelList[i]->computeImage(kernelImage,
false);
344 basisKernels[i].Init(kernelImage);
347 int const inImageWidth = inImage.
getWidth();
348 int const inImageHeight = inImage.
getHeight();
349 int const cnvWidth = inImageWidth + 1 - newKernel->
getWidth();
350 int const cnvHeight = inImageHeight + 1 - newKernel->
getHeight();
351 int const cnvStartX = newKernel->
getCtrX();
352 int const cnvStartY = newKernel->
getCtrY();
354 std::vector<double> colPos(cnvWidth);
355 std::vector<double> rowPos(cnvHeight);
357 for (
int i = 0; i < cnvWidth; i++) {
360 for (
int i = 0; i < cnvHeight; i++) {
367 CopyFromMaskedImage(inImage, inBufImg, inBufVar, inBufMsk);
373 pexLog::TTrace<3>(
"lsst.afw.math.convolve",
374 "MaskedImage, convolveLinearCombinationGPU: will use GPU acceleration");
377 GPU_ConvolutionMI_LinearCombinationKernel<OutPixelT, InPixelT>(
378 inBufImg, inBufVar, inBufMsk,
381 outBufImg, outBufVar, outBufMsk,
388 CopyToImage(convolvedImage, cnvStartX, cnvStartY,
389 outBufImg, outBufVar, outBufMsk);
417 template <
typename OutPixelT,
typename InPixelT>
425 throw LSST_EXCEPT(afwGpu::GpuRuntimeError,
"Afw not compiled with GPU support");
433 pexLog::TTrace<3>(
"lsst.afw.math.convolve",
434 "convolveLinearCombinationGPU: spatially invariant; delegate");
450 refKernelPtr = kernel.
clone();
454 refKernelPtr = kernel.
clone();
462 assert(newKernel!=NULL);
466 if (sFn.size() < 1) {
469 if (
int(sFn.size()) != kernelN) {
473 bool isAllCheby =
true;
474 for (
int i = 0; i < kernelN; i++) {
479 bool isAllPoly =
true;
480 for (
int i = 0; i < kernelN; i++) {
485 if (!isAllPoly && !isAllCheby) {
498 }
else if(isAllCheby) {
510 const int minKernelSize = 20;
520 if (!shMemOkA || !shMemOkB) {
529 for (
int i = 0; i < kernelN; i++) {
530 if (kernelList[i]->getDimensions() != newKernel->
getDimensions()
531 || kernelList[i]->getCtr() != newKernel->
getCtr()
537 std::vector< KernelBuffer > basisKernels(kernelN);
538 for (
int i = 0; i < kernelN; i++) {
539 KernelImage kernelImage(kernelList[i]->getDimensions());
540 (void)kernelList[i]->computeImage(kernelImage,
false);
541 basisKernels[i].Init(kernelImage);
544 int const inImageWidth = inImage.
getWidth();
545 int const inImageHeight = inImage.
getHeight();
546 int const cnvWidth = inImageWidth + 1 - newKernel->
getWidth();
547 int const cnvHeight = inImageHeight + 1 - newKernel->
getHeight();
548 int const cnvStartX = newKernel->
getCtrX();
549 int const cnvStartY = newKernel->
getCtrY();
551 std::vector<double> colPos(cnvWidth);
552 std::vector<double> rowPos(cnvHeight);
554 for (
int i = 0; i < cnvWidth; i++) {
557 for (
int i = 0; i < cnvHeight; i++) {
563 pexLog::TTrace<3>(
"lsst.afw.math.convolve",
564 "plain Image, convolveLinearCombinationGPU: will use GPU acceleration");
567 GPU_ConvolutionImage_LinearCombinationKernel<OutPixelT, InPixelT>(
568 inBuf, colPos, rowPos,
577 outBuf.CopyToImage(convolvedImage, cnvStartX, cnvStartY);
613 template <
typename OutPixelT,
typename InPixelT>
621 throw LSST_EXCEPT(afwGpu::GpuRuntimeError,
"Afw not compiled with GPU support");
632 typedef typename KernelImage::const_x_iterator KernelXIterator;
633 typedef typename KernelImage::const_xy_locator KernelXYLocator;
641 const int minKernelSize = 25;
643 int const inImageWidth = inImage.
getWidth();
644 int const inImageHeight = inImage.
getHeight();
645 int const kWidth = kernel.
getWidth();
647 int const cnvWidth = inImageWidth + 1 - kernel.
getWidth();
648 int const cnvHeight = inImageHeight + 1 - kernel.
getHeight();
649 int const cnvStartX = kernel.
getCtrX();
650 int const cnvStartY = kernel.
getCtrY();
654 pexLog::TTrace<3>(
"lsst.afw.math.convolve",
655 "convolveSpatiallyInvariantGPU: using GPU acceleration, "
656 "plain Image, kernel is spatially invariant");
668 if (kWidth * kHeight < minKernelSize &&
678 GPU_ConvolutionImage_SpatiallyInvariantKernel<OutPixelT, InPixelT>(inBuf, outBuf, kernelBuf);
680 outBuf.CopyToImage(convolvedImage, cnvStartX, cnvStartY);
714 template <
typename OutPixelT,
typename InPixelT>
722 throw LSST_EXCEPT(afwGpu::GpuRuntimeError,
"Afw not compiled with GPU support");
730 typedef typename KernelImage::const_x_iterator KernelXIterator;
731 typedef typename KernelImage::const_xy_locator KernelXYLocator;
739 const int minKernelSize = 20;
741 int const inImageWidth = inImage.
getWidth();
742 int const inImageHeight = inImage.
getHeight();
743 int const kWidth = kernel.
getWidth();
745 int const cnvWidth = inImageWidth + 1 - kernel.
getWidth();
746 int const cnvHeight = inImageHeight + 1 - kernel.
getHeight();
747 int const cnvStartX = kernel.
getCtrX();
748 int const cnvStartY = kernel.
getCtrY();
762 if (kWidth * kHeight < minKernelSize
769 pexLog::TTrace<3>(
"lsst.afw.math.convolve",
770 "convolveSpatiallyInvariantGPU: using GPU acceleration, "
771 "MaskedImage, kernel is spatially invariant");
777 CopyFromMaskedImage(inImage, inBufImg, inBufVar, inBufMsk);
785 GPU_ConvolutionMI_SpatiallyInvariantKernel<OutPixelT, InPixelT>(
786 inBufImg, inBufVar, inBufMsk,
787 outBufImg, outBufVar, outBufMsk,
791 CopyToImage(convolvedImage, cnvStartX, cnvStartY,
792 outBufImg, outBufVar, outBufMsk);
800 #define IMAGE(PIXTYPE) afwImage::Image<PIXTYPE>
801 #define MASKEDIMAGE(PIXTYPE) afwImage::MaskedImage<PIXTYPE, afwImage::MaskPixel, afwImage::VariancePixel>
804 #define INSTANTIATE_IM_OR_MI(IMGMACRO, OUTPIXTYPE, INPIXTYPE) \
805 template mathDetail::ConvolveGpuStatus::ReturnCode mathDetail::basicConvolveGPU( \
806 IMGMACRO(OUTPIXTYPE)&, IMGMACRO(INPIXTYPE) const&, afwMath::Kernel const&, \
807 afwMath::ConvolutionControl const&); NL \
808 template mathDetail::ConvolveGpuStatus::ReturnCode mathDetail::convolveLinearCombinationGPU( \
809 IMGMACRO(OUTPIXTYPE)&, IMGMACRO(INPIXTYPE) const&, afwMath::LinearCombinationKernel const&, \
810 afwMath::ConvolutionControl const&); NL \
811 template mathDetail::ConvolveGpuStatus::ReturnCode mathDetail::convolveSpatiallyInvariantGPU( \
812 IMGMACRO(OUTPIXTYPE)&, IMGMACRO(INPIXTYPE) const&, afwMath::Kernel const&, \
813 afwMath::ConvolutionControl const&);
815 #define INSTANTIATE(OUTPIXTYPE, INPIXTYPE) \
816 INSTANTIATE_IM_OR_MI(IMAGE, OUTPIXTYPE, INPIXTYPE) \
817 INSTANTIATE_IM_OR_MI(MASKEDIMAGE, OUTPIXTYPE, INPIXTYPE)
2-dimensional weighted sum of Chebyshev polynomials of the first kind.
int getWidth() const
Return the number of columns in the image.
An include file to include the header files for lsst::afw::geom.
Declare the Kernel class and subclasses.
Class for representing an image or 2D array in general)
ConvolveGpuStatus::ReturnCode convolveLinearCombinationGPU(lsst::afw::image::MaskedImage< OutPixelT, lsst::afw::image::MaskPixel, lsst::afw::image::VariancePixel > &convolvedImage, lsst::afw::image::MaskedImage< InPixelT, lsst::afw::image::MaskPixel, lsst::afw::image::VariancePixel > const &inImage, lsst::afw::math::LinearCombinationKernel const &kernel, lsst::afw::math::ConvolutionControl const &convolutionControl)
int getWidth() const
Return the Kernel's width.
bool IsSufficientSharedMemoryAvailable_ForImgBlock(int filterW, int filterH, int pixSize)
virtual KernelList const & getKernelList() const
Get the fixed basis kernels.
double indexToPosition(double ind, lsst::afw::image::xOrY const xy) const
Convert image index to image position.
int getHeight() const
Return the Kernel's height.
virtual boost::shared_ptr< Kernel > clone() const
Return a pointer to a deep copy of this kernel.
additional GPU exceptions
Parameters to control convolution.
double indexToPosition(double ind, lsst::afw::image::xOrY const xy) const
Convert image index to image position (see Image::indexToPosition)
2-dimensional polynomial function with cross terms
definition of the Trace messaging facilities
bool getDoNormalize() const
A kernel described by a pair of functions: func(x, y) = colFunc(x) * rowFunc(y)
std::vector< SpatialFunctionPtr > getSpatialFunctionList() const
Return a list of clones of the spatial functions.
unsigned int getNKernelParameters() const
Return the number of kernel parameters (0 if none)
Define a collection of useful Functions.
int getNSpatialParameters() const
Return the number of spatial parameters (0 if not spatially varying)
bool TryToSelectCudaDevice(bool noExceptions, bool reselect=false)
lsst::afw::geom::Point2I getCtr() const
Return index of kernel's center.
CPU and GPU convolution shared code.
ConvolveGpuStatus::ReturnCode convolveSpatiallyInvariantGPU(lsst::afw::image::MaskedImage< OutPixelT, lsst::afw::image::MaskPixel, lsst::afw::image::VariancePixel > &convolvedImage, lsst::afw::image::MaskedImage< InPixelT, lsst::afw::image::MaskPixel, lsst::afw::image::VariancePixel > const &inImage, lsst::afw::math::Kernel const &kernel, lsst::afw::math::ConvolutionControl const &convolutionControl)
contains GpuBuffer2D class (for simple handling of images or 2D arrays)
lsst::afw::image::VariancePixel VarPixel
bool isSpatiallyVarying() const
Return true iff the kernel is spatially varying (has a spatial function)
boost::shared_ptr< Kernel > Ptr
PixelT * GetImgLinePtr(int y)
table::Key< table::Array< Kernel::Pixel > > image
x_iterator x_at(int x, int y) const
Return an x_iterator at the point (x, y)
int getWidth() const
Return the number of columns in the image.
Set up for convolution, calls GPU convolution kernels.
A kernel that is a linear combination of fixed basis kernels.
A class to manipulate images, masks, and variance as a single object.
geom::Extent2I const getDimensions() const
Return the Kernel's dimensions (width, height)
bool isGpuBuild()
Inline function which returns true only when GPU_BUILD macro is defined.
bool IsSufficientSharedMemoryAvailable_ForSfn(int order, int kernelN)
boost::shared_ptr< Kernel > refactor() const
Refactor the kernel as a linear combination of N bases where N is the number of parameters for the sp...
int getNBasisKernels() const
Get the number of basis kernels.
Functions to help managing setup for GPU kernels.
Convolve and convolveAtAPoint functions for Image and Kernel.
#define LSST_EXCEPT(type,...)
void assertDimensionsOK(OutImageT const &convolvedImage, InImageT const &inImage, lsst::afw::math::Kernel const &kernel)
void Init(const ImageT &image)
Implementation of the Class MaskedImage.
int getHeight() const
Return the number of rows in the image.
std::vector< boost::shared_ptr< Kernel > > KernelList
int getCtrY() const
Return y index of kernel's center.
int getHeight() const
Return the number of rows in the image.
Kernels are used for convolution with MaskedImages and (eventually) Images.
A class to represent a 2-dimensional array of pixels.
#define IS_INSTANCE(A, B)
A kernel that has only one non-zero pixel (of value 1)
lsst::afw::image::MaskPixel MskPixel
bool IsSufficientSharedMemoryAvailable_ForImgAndMaskBlock(int filterW, int filterH, int pixSize)
lsst::afw::gpu::DevicePreference getDevicePreference() const
double computeImage(lsst::afw::image::Image< Pixel > &image, bool doNormalize, double x=0.0, double y=0.0) const
Compute an image (pixellized representation of the kernel) in place.
Include files required for standard LSST Exception handling.
A function to determine whether compiling for GPU is enabled.
ConvolveGpuStatus::ReturnCode basicConvolveGPU(OutImageT &convolvedImage, InImageT const &inImage, lsst::afw::math::Kernel const &kernel, lsst::afw::math::ConvolutionControl const &convolutionControl)
int getCtrX() const
Return x index of kernel's center.