Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FastCV Allocator and DSP Initialization Functions #3909

Open
wants to merge 4 commits into
base: 4.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions modules/fastcv/include/opencv2/fastcv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
#include "opencv2/fastcv/thresh.hpp"
#include "opencv2/fastcv/tracking.hpp"
#include "opencv2/fastcv/warp.hpp"
#include "opencv2/fastcv/allocator.hpp"
#include "opencv2/fastcv/dsp_init.hpp"
#include "opencv2/fastcv/sad_dsp.hpp"

/**
* @defgroup fastcv Module-wrapper for FastCV hardware accelerated functions
Expand Down
30 changes: 30 additions & 0 deletions modules/fastcv/include/opencv2/fastcv/allocator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef OPENCV_FASTCV_ALLOCATOR_HPP
#define OPENCV_FASTCV_ALLOCATOR_HPP

#include <opencv2/core.hpp>

namespace cv {
namespace fastcv {

//! @addtogroup fastcv
//! @{

/**
* @brief Gets the default FastCV allocator.
* This function returns a pointer to the default FastCV allocator, which is optimized
* for use with DSP.
*
* @return Pointer to the default FastCV allocator.
*/
CV_EXPORTS cv::MatAllocator* getDefaultFastCVAllocator();
//! @}

} // fastcv::
} // cv::

#endif // OPENCV_FASTCV_ALLOCATOR_HPP
42 changes: 42 additions & 0 deletions modules/fastcv/include/opencv2/fastcv/dsp_init.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef OPENCV_FASTCV_DSP_INIT_HPP
#define OPENCV_FASTCV_DSP_INIT_HPP

#include <opencv2/core.hpp>

namespace cv {
namespace fastcv {
namespace dsp {

//! @addtogroup fastcv
//! @{

/**
* @brief Initializes the FastCV DSP environment.
*
* This function sets up the necessary environment for FastCV DSP operations.
* It ensures that the DSP context is initialized and sets the custom memory allocator
* for FastCV operations.
*
* @return int Returns 0 on success, and a non-zero value on failure.
*/
CV_EXPORTS_W int fastcvq6init();

/**
* @brief Deinitializes the FastCV DSP environment.
*
* This function cleans up the FastCV DSP environment, releasing any resources
* that were allocated during initialization.
*/
CV_EXPORTS_W void fastcvq6deinit();
//! @}

} // dsp::
} // fastcv::
} // cv::

#endif // OPENCV_FASTCV_DSP_INIT_HPP
34 changes: 34 additions & 0 deletions modules/fastcv/include/opencv2/fastcv/sad_dsp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef OPENCV_SAD_HPP
#define OPENCV_SAD_HPP

#include <opencv2/core.hpp>

namespace cv {
namespace fastcv {
namespace dsp {

/**
* @defgroup fastcv Module-wrapper for FastCV hardware accelerated functions
*/

//! @addtogroup fastcv
//! @{
/**
* @brief Sum of absolute differences of an image against an 8x8 template.
* @param _patch The first input image data, type CV_8UC1
* @param _src The input image data, type CV_8UC1
* @param _dst The output image data, type CV_16UC1
*/
CV_EXPORTS_W void sumOfAbsoluteDiffs(cv::InputArray _patch, cv::InputArray _src, cv::OutputArray _dst);
//! @}

}
}
}

#endif
42 changes: 42 additions & 0 deletions modules/fastcv/perf/perf_sad_dsp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include "perf_precomp.hpp"

namespace opencv_test {

typedef std::tuple<cv::Size /*srcSize*/> SumOfAbsDiffsPerfParams;
typedef perf::TestBaseWithParam<SumOfAbsDiffsPerfParams> SumOfAbsDiffsPerfTest;

PERF_TEST_P(SumOfAbsDiffsPerfTest, run,
::testing::Values(cv::Size(640, 480), // VGA
cv::Size(1280, 720), // 720p
cv::Size(1920, 1080)) // 1080p
)
{
// Initialize FastCV DSP
int initStatus = cv::fastcv::dsp::fastcvq6init();
ASSERT_EQ(initStatus, 0) << "Failed to initialize FastCV DSP";

auto p = GetParam();
cv::Size srcSize = std::get<0>(p);

RNG& rng = cv::theRNG();
cv::Mat patch(8, 8, CV_8UC1);
cv::Mat src(srcSize, CV_8UC1);
cvtest::randUni(rng, patch, cv::Scalar::all(0), cv::Scalar::all(255));
cvtest::randUni(rng, src, cv::Scalar::all(0), cv::Scalar::all(255));

cv::Mat dst;
while(next())
{
startTimer();
cv::fastcv::dsp::sumOfAbsoluteDiffs(patch, src, dst);
stopTimer();
}
SANITY_CHECK_NOTHING();
}

} // namespace
100 changes: 100 additions & 0 deletions modules/fastcv/src/allocator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include "precomp.hpp"

namespace cv {
namespace fastcv {

struct FastCVAllocator: public cv::MatAllocator
{
public:
FastCVAllocator();
~FastCVAllocator();

cv::UMatData* allocate(int dims, const int* sizes, int type, void* data, size_t* step, cv::AccessFlag flags, cv::UMatUsageFlags usageFlags) const CV_OVERRIDE;
bool allocate(cv::UMatData* u, cv::AccessFlag accessFlags, cv::UMatUsageFlags usageFlags) const CV_OVERRIDE;
void deallocate(cv::UMatData* u) const CV_OVERRIDE;
};

FastCVAllocator::FastCVAllocator()
{
}

FastCVAllocator::~FastCVAllocator()
{
}

cv::UMatData* FastCVAllocator::allocate(int dims, const int* sizes, int type,
void* data0, size_t* step, cv::AccessFlag flags,
cv::UMatUsageFlags usageFlags) const
{
CV_UNUSED(flags);
CV_UNUSED(usageFlags);

size_t total = CV_ELEM_SIZE(type);
for( int i = dims-1; i >= 0; i-- )
{
if( step )
{
if( data0 && step[i] != CV_AUTOSTEP )
{
CV_Assert(total <= step[i]);
total = step[i];
}
else
step[i] = total;
}
total *= sizes[i];
}
uchar* data = data0 ? (uchar*)data0 : (uchar*)fcvHwMemAlloc(total, 16);
cv::UMatData* u = new cv::UMatData(this);
u->data = u->origdata = data;
u->size = total;
if(data0)
u->flags |= cv::UMatData::USER_ALLOCATED;

u->userdata = new std::string("QCOM");
return u;
}

bool FastCVAllocator::allocate(cv::UMatData* u, cv::AccessFlag accessFlags, cv::UMatUsageFlags usageFlags) const
{
CV_UNUSED(accessFlags);
CV_UNUSED(usageFlags);

return u != nullptr;
}

void FastCVAllocator::deallocate(cv::UMatData* u) const
{
if(!u)
return;

CV_Assert(u->urefcount == 0);
CV_Assert(u->refcount == 0);
if( !(u->flags & cv::UMatData::USER_ALLOCATED) )
{
fcvHwMemFree(u->origdata);
u->origdata = 0;
}

if (u->userdata)
{
delete static_cast<std::string*>(u->userdata);
u->userdata = nullptr;
}

delete u;
}

cv::MatAllocator* getDefaultFastCVAllocator()
{
static cv::MatAllocator* allocator = new FastCVAllocator;
return allocator;
}

}
}
49 changes: 49 additions & 0 deletions modules/fastcv/src/dsp_init.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include "precomp.hpp"

namespace cv {
namespace fastcv {
namespace dsp {

int fastcvq6init()
{
// Get the DSP context
FastCvDspContext& context = FastCvDspContext::getContext();

// Check if DSP is initialized
if (!context.isDspInitialized)
{
CV_Error(cv::Error::StsBadArg, cv::format("DSP initialization failed!"));
return 1;
}

// Get custom allocator
cv::MatAllocator* allocator = cv::fastcv::getDefaultFastCVAllocator();

// Ensure the allocator is not the standard one
CV_Assert(allocator != cv::Mat::getStdAllocator());

// Check if the current allocator is already set to the custom allocator
if (cv::Mat::getDefaultAllocator() != allocator)
{
// Set the custom allocator
cv::Mat::setDefaultAllocator(allocator);
}

return 0;
}

void fastcvq6deinit()
{
// Deinitialize the DSP environment
fcvQ6DeInit();
}


} // namespace dsp
} // namespace fastcv
} // namespace cv
46 changes: 44 additions & 2 deletions modules/fastcv/src/precomp.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

Expand All @@ -10,11 +10,12 @@
#include <opencv2/imgproc.hpp>
#include "opencv2/core/private.hpp"
#include "opencv2/core/utils/logger.hpp"

#include <opencv2/core/core_c.h>
#include <opencv2/fastcv.hpp>
#include <map>

#include "fastcv.h"
#include "fastcvDsp.h"

namespace cv {
namespace fastcv {
Expand All @@ -30,6 +31,7 @@ namespace fastcv {

#define FCV_KernelSize_SHIFT 3
#define FCV_MAKETYPE(ksize,depth) ((ksize<<FCV_KernelSize_SHIFT) + depth)
#define MIN_REMOTE_BUF_SIZE 176*144*sizeof(uint8_t)

const std::map<fcvStatus, std::string> fcvStatusStrings =
{
Expand Down Expand Up @@ -72,6 +74,46 @@ struct FastCvContext
bool isInitialized;
};

namespace dsp {

#define IS_FASTCV_ALLOCATED(mat) \
((mat.u && mat.u->userdata && \
*static_cast<std::string*>(mat.u->userdata) == "QCOM") ? true : \
(std::cerr << "Allocation check failed for " #mat \
<< ". Please ensure that cv::fastcv::dsp::fastcvq6init() has been called." \
<< std::endl, false))

struct FastCvDspContext
{
public:
// Initialize at first call
// Defines a static local variable context.
static FastCvDspContext& getContext()
{
//Instance is created only once.
static FastCvDspContext context;
return context;
}

//Constructor is called when the FastCvDspContext instance is created
FastCvDspContext()
{
if (fcvQ6Init() != 0)
{
CV_LOG_WARNING(NULL, "Failed to switch FastCV DSP operation mode");
isDspInitialized = false;
}
else
{
CV_LOG_INFO(NULL, "FastCV DSP Operation Mode Switched");
isDspInitialized = true;
}
}

bool isDspInitialized;
};

} // namespace dsp
} // namespace fastcv
} // namespace cv

Expand Down
Loading