mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Merge pull request #29369 from abhishek-gola:fp8_support
FP8 support in core module #29369 Core part of https://github.com/opencv/opencv/issues/29313 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
@@ -332,6 +332,12 @@ convertTo(const _Tp* src, void* dst, int dtype,
|
||||
case CV_16BF:
|
||||
convert_(src, (cv::bfloat*)dst, total, alpha, beta);
|
||||
break;
|
||||
case CV_8F_E4M3FN:
|
||||
convert_(src, (cv::fp8_t*)dst, total, alpha, beta);
|
||||
break;
|
||||
case CV_8F_E4M3FNUZ:
|
||||
convert_(src, (cv::fp8a_t*)dst, total, alpha, beta);
|
||||
break;
|
||||
case CV_Bool:
|
||||
convert_to_bool(src, (bool*)dst, total, alpha, beta);
|
||||
break;
|
||||
@@ -415,6 +421,12 @@ void convert(const Mat& src, cv::OutputArray _dst,
|
||||
case CV_16BF:
|
||||
convertTo((const cv::bfloat*)sptr, dptr, dtype, total, alpha, beta);
|
||||
break;
|
||||
case CV_8F_E4M3FN:
|
||||
convertTo((const cv::fp8_t*)sptr, dptr, dtype, total, alpha, beta);
|
||||
break;
|
||||
case CV_8F_E4M3FNUZ:
|
||||
convertTo((const cv::fp8a_t*)sptr, dptr, dtype, total, alpha, beta);
|
||||
break;
|
||||
default:
|
||||
CV_Error(cv::Error::StsNotImplemented, "unknown/unsupported depth");
|
||||
}
|
||||
@@ -2251,6 +2263,15 @@ int check( const Mat& a, double fmin, double fmax, vector<int>* _idx )
|
||||
// success_err_level is maximum allowed difference, idx is the index of the first
|
||||
// element for which difference is >success_err_level
|
||||
// (or index of element with the maximum difference)
|
||||
static inline double decodeFP8(const uchar* p, int depth)
|
||||
{
|
||||
switch (depth)
|
||||
{
|
||||
case CV_8F_E4M3FN: return (double)(float)*reinterpret_cast<const cv::fp8_t*>(p);
|
||||
default: return (double)(float)*reinterpret_cast<const cv::fp8a_t*>(p);
|
||||
}
|
||||
}
|
||||
|
||||
int cmpEps( const Mat& arr_, const Mat& refarr_, double* _realmaxdiff,
|
||||
double success_err_level, vector<int>* _idx,
|
||||
bool element_wise_relative_error )
|
||||
@@ -2375,6 +2396,38 @@ int cmpEps( const Mat& arr_, const Mat& refarr_, double* _realmaxdiff,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CV_8F_E4M3FN:
|
||||
case CV_8F_E4M3FNUZ:
|
||||
for( j = 0; j < total; j++ )
|
||||
{
|
||||
if( ((uchar*)sptr1)[j] == ((uchar*)sptr2)[j] )
|
||||
continue;
|
||||
double a_val = decodeFP8((const uchar*)sptr1 + j, depth);
|
||||
double b_val = decodeFP8((const uchar*)sptr2 + j, depth);
|
||||
double threshold;
|
||||
if( cvIsNaN(a_val) || cvIsInf(a_val) )
|
||||
{
|
||||
result = CMP_EPS_INVALID_TEST_DATA;
|
||||
idx = startidx + j;
|
||||
break;
|
||||
}
|
||||
if( cvIsNaN(b_val) || cvIsInf(b_val) )
|
||||
{
|
||||
result = CMP_EPS_INVALID_REF_DATA;
|
||||
idx = startidx + j;
|
||||
break;
|
||||
}
|
||||
a_val = fabs(a_val - b_val);
|
||||
threshold = element_wise_relative_error ? fabs(b_val) + 1 : maxval;
|
||||
if( a_val > threshold*success_err_level )
|
||||
{
|
||||
realmaxdiff = a_val/threshold;
|
||||
if( idx == 0 )
|
||||
idx = startidx + j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CV_32F:
|
||||
for( j = 0; j < total; j++ )
|
||||
{
|
||||
@@ -3404,6 +3457,14 @@ static void writeElems(std::ostream& out, const void* data, int nelems, int dept
|
||||
writeElems<cv::bfloat, float>(out, data, nelems, starpos);
|
||||
out.precision(pp);
|
||||
}
|
||||
else if(depth == CV_8F_E4M3FN || depth == CV_8F_E4M3FNUZ)
|
||||
{
|
||||
std::streamsize pp = out.precision();
|
||||
out.precision(4);
|
||||
if(depth == CV_8F_E4M3FN) writeElems<cv::fp8_t, float>(out, data, nelems, starpos);
|
||||
else writeElems<cv::fp8a_t, float>(out, data, nelems, starpos);
|
||||
out.precision(pp);
|
||||
}
|
||||
else if(depth == CV_32F)
|
||||
{
|
||||
std::streamsize pp = out.precision();
|
||||
|
||||
Reference in New Issue
Block a user