Skip to content

Commit 7ea21c4

Browse files
authored
Merge pull request opencv#19259 from nglee:dev_gpumatnd1
Minimal implementation of GpuMatND * GpuMatND - minimal implementation * GpuMatND - createGpuMatHeader * GpuMatND - GpuData, offset, getDevicePtr(), license * reviews * reviews
1 parent 9d22764 commit 7ea21c4

File tree

4 files changed

+730
-0
lines changed

4 files changed

+730
-0
lines changed

modules/core/include/opencv2/core/cuda.hpp

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
340340
Allocator* allocator;
341341
};
342342

343+
struct CV_EXPORTS_W GpuData
344+
{
345+
explicit GpuData(size_t _size);
346+
~GpuData();
347+
348+
GpuData(const GpuData&) = delete;
349+
GpuData& operator=(const GpuData&) = delete;
350+
351+
GpuData(GpuData&&) = delete;
352+
GpuData& operator=(GpuData&&) = delete;
353+
354+
uchar* data;
355+
size_t size;
356+
};
357+
358+
class CV_EXPORTS_W GpuMatND
359+
{
360+
public:
361+
using SizeArray = std::vector<int>;
362+
using StepArray = std::vector<size_t>;
363+
using IndexArray = std::vector<int>;
364+
365+
//! destructor
366+
~GpuMatND();
367+
368+
//! default constructor
369+
GpuMatND();
370+
371+
/** @overload
372+
@param size Array of integers specifying an n-dimensional array shape.
373+
@param type Array type. Use CV_8UC1, ..., CV_16FC4 to create 1-4 channel matrices, or
374+
CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
375+
*/
376+
GpuMatND(SizeArray size, int type);
377+
378+
/** @overload
379+
@param size Array of integers specifying an n-dimensional array shape.
380+
@param type Array type. Use CV_8UC1, ..., CV_16FC4 to create 1-4 channel matrices, or
381+
CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
382+
@param data Pointer to the user data. Matrix constructors that take data and step parameters do not
383+
allocate matrix data. Instead, they just initialize the matrix header that points to the specified
384+
data, which means that no data is copied. This operation is very efficient and can be used to
385+
process external data using OpenCV functions. The external data is not automatically deallocated, so
386+
you should take care of it.
387+
@param step Array of _size.size()-1 steps in case of a multi-dimensional array (the last step is always
388+
set to the element size). If not specified, the matrix is assumed to be continuous.
389+
*/
390+
GpuMatND(SizeArray size, int type, void* data, StepArray step = StepArray());
391+
392+
/** @brief Allocates GPU memory.
393+
Suppose there is some GPU memory already allocated. In that case, this method may choose to reuse that
394+
GPU memory under the specific condition: it must be of the same size and type, not externally allocated,
395+
the GPU memory is continuous(i.e., isContinuous() is true), and is not a sub-matrix of another GpuMatND
396+
(i.e., isSubmatrix() is false). In other words, this method guarantees that the GPU memory allocated by
397+
this method is always continuous and is not a sub-region of another GpuMatND.
398+
*/
399+
void create(SizeArray size, int type);
400+
401+
void release();
402+
403+
void swap(GpuMatND& m) noexcept;
404+
405+
/** @brief Creates a full copy of the array and the underlying data.
406+
The method creates a full copy of the array. It mimics the behavior of Mat::clone(), i.e.
407+
the original step is not taken into account. So, the array copy is a continuous array
408+
occupying total()\*elemSize() bytes.
409+
*/
410+
GpuMatND clone() const;
411+
412+
/** @overload
413+
This overload is non-blocking, so it may return even if the copy operation is not finished.
414+
*/
415+
GpuMatND clone(Stream& stream) const;
416+
417+
/** @brief Extracts a sub-matrix.
418+
The operator makes a new header for the specified sub-array of \*this.
419+
The operator is an O(1) operation, that is, no matrix data is copied.
420+
@param ranges Array of selected ranges along each dimension.
421+
*/
422+
GpuMatND operator()(const std::vector<Range>& ranges) const;
423+
424+
/** @brief Creates a GpuMat header for a 2D plane part of an n-dim matrix.
425+
@note The returned GpuMat is constructed with the constructor for user-allocated data.
426+
That is, It does not perform reference counting.
427+
@note This function does not increment this GpuMatND's reference counter.
428+
*/
429+
GpuMat createGpuMatHeader(IndexArray idx, Range rowRange, Range colRange) const;
430+
431+
/** @overload
432+
Creates a GpuMat header if this GpuMatND is effectively 2D.
433+
@note The returned GpuMat is constructed with the constructor for user-allocated data.
434+
That is, It does not perform reference counting.
435+
@note This function does not increment this GpuMatND's reference counter.
436+
*/
437+
GpuMat createGpuMatHeader() const;
438+
439+
/** @brief Extracts a 2D plane part of an n-dim matrix.
440+
It differs from createGpuMatHeader(IndexArray, Range, Range) in that it clones a part of this
441+
GpuMatND to the returned GpuMat.
442+
@note This operator does not increment this GpuMatND's reference counter;
443+
*/
444+
GpuMat operator()(IndexArray idx, Range rowRange, Range colRange) const;
445+
446+
/** @brief Extracts a 2D plane part of an n-dim matrix if this GpuMatND is effectively 2D.
447+
It differs from createGpuMatHeader() in that it clones a part of this GpuMatND.
448+
@note This operator does not increment this GpuMatND's reference counter;
449+
*/
450+
operator GpuMat() const;
451+
452+
GpuMatND(const GpuMatND&) = default;
453+
GpuMatND& operator=(const GpuMatND&) = default;
454+
455+
GpuMatND(GpuMatND&&) noexcept = default;
456+
GpuMatND& operator=(GpuMatND&&) noexcept = default;
457+
458+
void upload(InputArray src);
459+
void upload(InputArray src, Stream& stream);
460+
void download(OutputArray dst) const;
461+
void download(OutputArray dst, Stream& stream) const;
462+
463+
//! returns true iff the GpuMatND data is continuous
464+
//! (i.e. when there are no gaps between successive rows)
465+
bool isContinuous() const;
466+
467+
//! returns true if the matrix is a sub-matrix of another matrix
468+
bool isSubmatrix() const;
469+
470+
//! returns element size in bytes
471+
size_t elemSize() const;
472+
473+
//! returns the size of element channel in bytes
474+
size_t elemSize1() const;
475+
476+
//! returns true if data is null
477+
bool empty() const;
478+
479+
//! returns true if not empty and points to external(user-allocated) gpu memory
480+
bool external() const;
481+
482+
//! returns pointer to the first byte of the GPU memory
483+
uchar* getDevicePtr() const;
484+
485+
//! returns the total number of array elements
486+
size_t total() const;
487+
488+
//! returns the size of underlying memory in bytes
489+
size_t totalMemSize() const;
490+
491+
//! returns element type
492+
int type() const;
493+
494+
private:
495+
//! internal use
496+
void setFields(SizeArray size, int type, StepArray step = StepArray());
497+
498+
public:
499+
/*! includes several bit-fields:
500+
- the magic signature
501+
- continuity flag
502+
- depth
503+
- number of channels
504+
*/
505+
int flags;
506+
507+
//! matrix dimensionality
508+
int dims;
509+
510+
//! shape of this array
511+
SizeArray size;
512+
513+
/*! step values
514+
Their semantics is identical to the semantics of step for Mat.
515+
*/
516+
StepArray step;
517+
518+
private:
519+
/*! internal use
520+
If this GpuMatND holds external memory, this is empty.
521+
*/
522+
std::shared_ptr<GpuData> data_;
523+
524+
/*! internal use
525+
If this GpuMatND manages memory with reference counting, this value is
526+
always equal to data_->data. If this GpuMatND holds external memory,
527+
data_ is empty and data points to the external memory.
528+
*/
529+
uchar* data;
530+
531+
/*! internal use
532+
If this GpuMatND is a sub-matrix of a larger matrix, this value is the
533+
difference of the first byte between the sub-matrix and the whole matrix.
534+
*/
535+
size_t offset;
536+
};
537+
343538
/** @brief Creates a continuous matrix.
344539
345540
@param rows Row count.

modules/core/include/opencv2/core/cuda.inl.hpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,92 @@ void swap(GpuMat& a, GpuMat& b)
383383
a.swap(b);
384384
}
385385

386+
//===================================================================================
387+
// GpuMatND
388+
//===================================================================================
389+
390+
inline
391+
GpuMatND::GpuMatND() :
392+
flags(0), dims(0), data(nullptr), offset(0)
393+
{
394+
}
395+
396+
inline
397+
GpuMatND::GpuMatND(SizeArray _size, int _type) :
398+
flags(0), dims(0), data(nullptr), offset(0)
399+
{
400+
create(std::move(_size), _type);
401+
}
402+
403+
inline
404+
void GpuMatND::swap(GpuMatND& m) noexcept
405+
{
406+
std::swap(*this, m);
407+
}
408+
409+
inline
410+
bool GpuMatND::isContinuous() const
411+
{
412+
return (flags & Mat::CONTINUOUS_FLAG) != 0;
413+
}
414+
415+
inline
416+
bool GpuMatND::isSubmatrix() const
417+
{
418+
return (flags & Mat::SUBMATRIX_FLAG) != 0;
419+
}
420+
421+
inline
422+
size_t GpuMatND::elemSize() const
423+
{
424+
return CV_ELEM_SIZE(flags);
425+
}
426+
427+
inline
428+
size_t GpuMatND::elemSize1() const
429+
{
430+
return CV_ELEM_SIZE1(flags);
431+
}
432+
433+
inline
434+
bool GpuMatND::empty() const
435+
{
436+
return data == nullptr;
437+
}
438+
439+
inline
440+
bool GpuMatND::external() const
441+
{
442+
return !empty() && data_.use_count() == 0;
443+
}
444+
445+
inline
446+
uchar* GpuMatND::getDevicePtr() const
447+
{
448+
return data + offset;
449+
}
450+
451+
inline
452+
size_t GpuMatND::total() const
453+
{
454+
size_t p = 1;
455+
for(auto s : size)
456+
p *= s;
457+
return p;
458+
}
459+
460+
inline
461+
size_t GpuMatND::totalMemSize() const
462+
{
463+
return size[0] * step[0];
464+
}
465+
466+
inline
467+
int GpuMatND::type() const
468+
{
469+
return CV_MAT_TYPE(flags);
470+
}
471+
386472
//===================================================================================
387473
// HostMem
388474
//===================================================================================

0 commit comments

Comments
 (0)