Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

ippiScaleC_8u_C1IR with negative mVal bug ?

Ladislav_K_
Beginner
1,010 Views

Hi,
I would like to achieve image inverse. So [src] = 255-[src]

I use: ippiScaleC_8u_C1IR(pSrc, Width, -1, 255, roiSize, ippAlgHintFast) , but it does not work.
Source image does not changed ...

 

57  
0 Kudos
21 Replies
Igor_A_Intel
Employee
912 Views

Hi Ladislav,

it's better (at least significantly faster) to use the next API (in a loop - row by row)

/* ////////////////////////////////////////////////////////////////////////////
//  Names:       ippsSubCRev
//  Purpose:     Subtracts each element of vector from constant value
//  Arguments:
//    pSrc             Pointer to source vector
//    pSrcDst          Pointer to source and destination vector for in-place operation
//    pDst             Pointer to destination vector
//    val              Scalar value from which vector elements are subtracted
//    len              Number of elements in vector
//    scaleFactor      Scale factor
//  Return:
//    ippStsNullPtrErr At least one of the pointers is NULL
//    ippStsSizeErr    Vectors' length is less than 1
//    ippStsNoErr      No error
//  Note:
//    SubCRev(X,v,Y) :  Y = v - X
*/
IPPAPI(IppStatus, ippsSubCRev_8u_ISfs,   (                     Ipp8u   val, Ipp8u*   pSrcDst, int len, int scaleFactor))
IPPAPI(IppStatus, ippsSubCRev_8u_Sfs,    (const Ipp8u*   pSrc, Ipp8u   val, Ipp8u*   pDst,    int len, int scaleFactor))
 

as regarding ScaleC - please provide compilable reproducer.

regards, Igor

0 Kudos
Ladislav_K_
Beginner
912 Views

Hi Igor,
thank you. Your suggestion works for me!

Regarding ScaleC I can provide only pseudo code in C (as I am developing using Free Pascal):
(source is taken from Scale.c example)

    int main(void)
    {
        IppStatus status = ippStsNoErr;

        IppiSize roiSize = {8, 8}; /* Image sizes */
        Ipp8u pSrc[8*8]={0};       /* Pointers to source images */
        Ipp64f mVal, aVal;

        mVal = -1;
        aVal = 255;

        check_sts( status = ippiScaleC_8u_C1IR(pSrc, roiSize.width, mVal, aVal, roiSize, ippAlgHintFast) )

    EXIT_MAIN
        printf("Exit status %d (%s)\n", (int)status, ippGetStatusString(status));
        return (int)status;
    }

Expected result is 255 in all elements of pSrc

 

0 Kudos
Igor_A_Intel
Employee
912 Views

I haven't faced with any issues:

#include "ipp.h"
#include <stdio.h>
 
int main(void)
    {
        IppStatus status = ippStsNoErr;
        IppiSize roiSize = {8, 8}; /* Image sizes */
        Ipp8u pSrc[8*8]={0};       /* Pointers to source images */
        Ipp64f mVal, aVal;
        mVal = -1;
        aVal = 255;
 
        printf("Before: ");
        for( int i = 0; i < 8*8; i++ ) printf( "%d,", pSrc );
        printf("\n");
        status = ippiScaleC_8u_C1IR(pSrc, roiSize.width, mVal, aVal, roiSize, ippAlgHintFast);
        printf("After: ");
        for( int i = 0; i < 8*8; i++ ) printf( "%d,", pSrc );
        printf("\n");
        printf("Exit status %d (%s)\n", (int)status, ippGetStatusString(status));
        return (int)status;
}
Before: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
After: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Exit status 0 (ippStsNoErr: No errors.)
Press any key to continue . . .
Regards, Igor
0 Kudos
Ladislav_K_
Beginner
912 Views

I link dynamically to DLLs supplied with IPP 2017.2.178 (ippGetLibVersion = ippCore2017.0.2 (r54644))
Interesting is that for "s8" versions it works as expected, but for "p8" and "h9" versions given wrong results.

Try this example please:

int main(void)
    {
        IppStatus status = ippStsNoErr;
        IppiSize roiSize = {8, 8};  /* Image sizes */
        Ipp8u pSrc[8*8]={100};       
        Ipp64f mVal, aVal;
        mVal = 1;
        aVal = 10;

 

        printf("Before: ");
        for( int i = 0; i < roiSize.Width*roiSize.Height; i++ ) printf( "%d,", pSrc );
        printf("\n");
        status = ippiScaleC_8u_C1IR(pSrc, roiSize.width, mVal, aVal, roiSize, ippAlgHintFast);
        printf("After: ");
        for( int i = 0; i < roiSize.Width*roiSize.Height; i++ ) printf( "%d,", pSrc );
        printf("\n");
        printf("Exit status %d (%s)\n", (int)status, ippGetStatusString(status));
        return (int)status;
}

All values of 8x8 array are initialised to 100, then ScaleC should add 10 to each element.
I get for first 16 values result 110 which is Ok, but next values are 120, which is NOT ok (seems like some bytes are processed twice!)

0 Kudos
Igor_A_Intel
Employee
912 Views

Hi Ladislav,

you example is not compilable - compiler doesn't know Width and Height... I extended my example with dispatching for all supported ia32 architectures - see result below:

#include "ipp.h"
#include <stdio.h>
 
static void libInfo( void ){
    const IppLibraryVersion *lib;
 
    lib = ippiGetLibVersion();
    printf( "CPU       : %s\n", lib->targetCpu );
    printf( "Name      : %s\n", lib->Name );
    printf( "Version   : %s\n", lib->Version );
}
 
static void ScaleC(void)
    {
        IppStatus status = ippStsNoErr;
        IppiSize roiSize = {8, 8};  /* Image sizes */
        Ipp8u pSrc[8*8];      
        Ipp64f mVal, aVal;
        mVal = 1;
        aVal = 10;
        int i;
 
        for( i = 0; i < roiSize.width*roiSize.height; i++ ) pSrc = 100;
        printf("Before: ");
        for( i = 0; i < roiSize.width*roiSize.height; i++ ) printf( "%d,", pSrc );
        printf("\n");
        status = ippiScaleC_8u_C1IR(pSrc, roiSize.width, mVal, aVal, roiSize, ippAlgHintFast);
        printf("After: ");
        for( i = 0; i < roiSize.width*roiSize.height; i++ ) printf( "%d,", pSrc );
        printf("\n");
        printf("Exit status %d (%s)\n", (int)status, ippGetStatusString(status));
}
 
int main( void ){
    Ipp64u features[] = { ippCPUID_SSE, ippCPUID_SSE2, ippCPUID_SSSE3, ippCPUID_SSE42, ippCPUID_AVX, ippCPUID_AVX2 };
    int i;
 
    for( i = 0; i < sizeof(features)/sizeof(features[0]); i++ ){
        ippSetCpuFeatures( features );
        libInfo();
        ScaleC();
    }
    return 0;
}

CPU       : px
Name      : ippIP PX (px)
Version   : 2017.0.2 (r54644)
Before: 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
After: 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
Exit status 0 (ippStsNoErr: No errors.)
CPU       : w7
Name      : ippIP SSE2 (w7)
Version   : 2017.0.2 (r54644)
Before: 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
After: 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
Exit status 0 (ippStsNoErr: No errors.)
CPU       : s8
Name      : ippIP Atom (s8)
Version   : 2017.0.2 (r54644)
Before: 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
After: 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
Exit status 0 (ippStsNoErr: No errors.)
CPU       : p8
Name      : ippIP SSE4.2 (p8)
Version   : 2017.0.2 (r54644)
Before: 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
After: 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
Exit status 0 (ippStsNoErr: No errors.)
CPU       : g9
Name      : ippIP AVX (g9)
Version   : 2017.0.2 (r54644)
Before: 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
After: 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
Exit status 0 (ippStsNoErr: No errors.)
CPU       : h9
Name      : ippIP AVX2 (h9)
Version   : 2017.0.2 (r54644)
Before: 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
After: 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
Exit status 0 (ippStsNoErr: No errors.)
Press any key to continue . . .

regards, Igor.

 

PS regarding Threshold - if you use

                  ippiThreshold_LTVal_8u_C1IR and  ippiThreshold_GTVal_8u_C1IR

​in a row by row loop with roi.height=1 - (or several rows at once with condition roi.height*roi.width < 32K (L0 size)) - you'll get the same performance as if it is ippiThreshold_LTValGTVal_8u_C1IR()

0 Kudos
Ladislav_K_
Beginner
912 Views

Thank you Igor,

can you please download and test my test program: http://uschovna.zoznam.sk/download?code=1342688553904-hUpDpkVrWZRcJfSiiYkL
(there are ZIPed also DLLs which I use)
What result do you get ?

I get in 1st case: all 110,... as expected
But in 2nd case: 16x 110 followed by 120: 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,120,...

This is Pascal source code compiled:

const
  CpuFeatures: array[0..1] of Ipp64u = (
    ippCPUID_MMX+ippCPUID_SSE+ippCPUID_SSE2+ippCPUID_SSE3+ippCPUID_SSSE3,
    ippCPUID_MMX+ippCPUID_SSE+ippCPUID_SSE2+ippCPUID_SSE3+ippCPUID_SSSE3+ippCPUID_SSE41+ippCPUID_SSE42+ippCPUID_AVX+ippCPUID_AVX2);

var
  lv: PIppLibraryVersion;
  b: array[0..8*8] of byte;
  j,i: integer;
  roiSize: ippiSize;

begin
  writeln('ippInit=',ippInit);
  for j:=low(CpuFeatures) to high(CpuFeatures) do begin
    writeln;
    writeln('ippSetCpuFeatures=', ippSetCpuFeatures(CpuFeatures));
    lv := ippGetLibVersion;
    writeln('ippGetLibVersion=', lv^.Name, lv^.Version, lv^.targetCpu);

    roiSize.width:=8;
    roiSize.height:=8;
    writeln('ROI=',roiSize.width,'x',roiSize.Height);
    FillByte(b[0], Length(b), 100);
    write('Before:');
    for i:=0 to 40 do write(b:3,',');
    writeln;
    writeln('ippiScaleC_8u=', ippiScaleC_8u_C1IR(@b[0], roiSize.Width, 1, 10, roiSize, ippAlgHintFast));
    write('After :');
    for i:=0 to 40 do write(b:3,',');
    writeln;
  end;
  readln;
end.

 

PS:

regarding ippiThreshold_LTValGTVal_8u_C1IR() why is there strange limitiation, that thresholdLT must be <= thresholdGT?
(without this limitation it will be usable for binarization and efficient at least as as are two calls to Threshold_LTVal and Threshold_GTVal)

0 Kudos
Ladislav_K_
Beginner
912 Views

Can anyone please download my example program from above mentioned link and check/report results ?

0 Kudos
Igor_A_Intel
Employee
912 Views

Hi Ladislav,

I don't have Pascal installed. Could you provide an output in the same manner as I've provided - Src content before ScaleC and then after + library version - in order to check if we are playing with the same IPP build and src/dst content is as you've described.

Regards, Igor

0 Kudos
Adriaan_van_Os
New Contributor I
912 Views

I would like to achieve image inverse. So [src] = 255-[src]

I wonder if that couldn't be done with ippsSubCRev_8u_ISfs, but I didn't try it out myself.

Regards,

Adriaan van Os

0 Kudos
Ladislav_K_
Beginner
912 Views

@Igor: on this link https://moja.uschovna.zoznam.sk/link/586b2b9b-23e2-4f8c-91a6-57de4bd84444  is already compiled program + DLLs which I use.
Output is:

ippInit=ippStsNoErr

ippSetCpuFeatures=ippStsNoErr
ippiGetLibVersion=ippIP Atom (s8)2017.0.2 (r54644)s8
ROI=8x8
Before:100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
ippiScaleC_8u=ippStsNoErr
After /*here is all as expected */:
110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,

ippSetCpuFeatures=ippStsNoErr
ippiGetLibVersion=ippIP AVX2 (h9)2017.0.2 (r54644)h9
ROI=8x8
Before:100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
ippiScaleC_8u=ippStsNoErr
After /*here is only first 16 bytes as expected, next are wrong ... seems like they are processed twice*/ :
110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,

@Adrian: Yes  ippsSubCRev_8u_ISfs works and I use it for now (as workaround). But I wonder why does not work for me ippiScaleC_8u

0 Kudos
Ladislav_K_
Beginner
911 Views

Can somebody test using dynamically loaded distributed DLLs. My results:

For Win32 "w7" and "s8" gives correct results, while others not (with same program code)

Win32:
------
ippSetCpuFeatures=ippStsNoErr
ippiGetLibVersion=ippIP SSE2 (w7)2017.0.2 (r54644)w7
ROI=8x8
Before:100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
ippiScaleC_8u=ippStsNoErr
After :110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,

ippSetCpuFeatures=ippStsNoErr
ippiGetLibVersion=ippIP Atom (s8)2017.0.2 (r54644)s8
ROI=8x8
Before:100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
ippiScaleC_8u=ippStsNoErr
After :110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,

ippSetCpuFeatures=ippStsNoErr
ippiGetLibVersion=ippIP SSE4.2 (p8)2017.0.2 (r54644)p8
ROI=8x8
Before:100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
ippiScaleC_8u=ippStsNoErr
After :110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,

ippSetCpuFeatures=ippStsNoErr
ippiGetLibVersion=ippIP AVX2 (h9)2017.0.2 (r54644)h9
ROI=8x8
Before:100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
ippiScaleC_8u=ippStsNoErr
After :110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,

Win64:
------
ippSetCpuFeatures=ippStsNoErr
ippiGetLibVersion=ippIP SSE4.2 (y8)2017.0.2 (r54644)y8
ROI=8x8
Before:100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
ippiScaleC_8u=ippStsNoErr
After :110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,

ippSetCpuFeatures=ippStsNoErr
ippiGetLibVersion=ippIP AVX2 (l9)2017.0.2 (r54644)l9
ROI=8x8
Before:100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
ippiScaleC_8u=ippStsNoErr
After :110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,

0 Kudos
Igor_A_Intel
Employee
911 Views

Hi Ladislav,

your link shows "Stránka sa nenašla" (404)

regards, Igor

0 Kudos
Ladislav_K_
Beginner
912 Views

Hi Igor,
uploaded file probably expired. I have uploaded it again: https://moja.uschovna.zoznam.sk/link/2fda80c2-7e14-4c80-9b7c-d48e9df0a0a5
Please check ...

0 Kudos
Igor_A_Intel
Employee
912 Views

Hi Ladislav,

got it "Zadarma" :)

Please don't expect the quick diagnose - I've reproduced your issue with your executable - even when replaced dlls with the latest ones from trunk. You see that there is no such issue if I use "my" test - therefore I need to build debug version of the library in order to understand the root of the issue.

regards, Igor

0 Kudos
Igor_A_Intel
Employee
912 Views

Hi Ladislav,

thank you that you've insisted on this bug investigation. This is real bug in IPP code that will be fixed in the next IPP version. It can't be reproduced "by default" with MSVC and my C-test and only your Pascal example has caught it with so simple test-case. There are two problems in the function code: (1) wrong test for "invalid" flag in mxcsr register and (2) wrong approach for in-place flavor of this function if "invalid" is raised up. For performance purpose there is no test for integer overflow in the main loop - I guess it's clear that in 99.999999% of cases there will be no overflow: the optimized (SSE,AVX) version loads 8u data, converts it to 32s, then to 32f (if "fast" hint is set), then scales it with mpy and add factors. If these factors are huge - the conversion back to 32s may overflow and raise "invalid" mxcsr flag. In this case, after the main loop, this flag is analyzed, and if it is set - the function goes to the second loop, that performs source vector processing from the beginning with correct saturation. This approach works correctly for out-of-place case, but fails for in-place (your case, bug #1), The difference between Pascal and MSVC is that MSVC masks all FP exceptions, while Pascal - doesn't. Because of the bug #2 - wrong analysis of "invalid" flag and mask combination - if "invalid" mask == 0 (your case - default settings for Pascal) - the code of the main loop of ScaleC function always detects "overflow" case and starts the second "saturation" loop. The main loop works with aligned on 0x20 data 32 elements at once, your vector is aligned on 0x10 - therefore the first 16 elements are calculated correctly in prolog code that always checks overflow. The same is true for epilog.

regards, Igor

0 Kudos
Ladislav_K_
Beginner
912 Views

Hi Igor,
thank you very much for your investigation. I will wait for next release and retest. Do you think, that also some other IPP function can be affected by different masking of FP exceptions in Pascal ?

0 Kudos
Adriaan_van_Os
New Contributor I
912 Views

Note that you can call 

SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision])

 

to get the same (buggy) behaviour as in C. The macpas.pp unit (in the FreePascal runtime) even does this automatically, because of the many bugs in Mac OS X. See http://bugs.freepascal.org/view.php?id=11516.

Regards,

Adriaan van Os

0 Kudos
Adriaan_van_Os
New Contributor I
912 Views

@Igor

I don't know if you have an internal test-suite for IPP. If you have, I suggest to run it (or run it too) with unmasked floating-point exceptions (by unmasking them manually at the start of the test-suite). Ot maybe add such a masking/unmasking call to IPP.

Regards,

Adriaan van Os

0 Kudos
Ladislav_K_
Beginner
912 Views

@Adriaan: Thank you. I can confirm, that when I add Math unit and SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]) then my test program gives correct results.

0 Kudos
Igor_A_Intel
Employee
855 Views

Hi Ladislav and Adriaan,

of course IPP is thoroughly tested - each function has Badarg, algorithm, thread-safe, misalign, mem-bound, numeric-boundary, performance and some other special tests (for example for PIC and non-PIC cases on Linux, 1-DLL/so/dylib for unresolved symbols, correct dispatching, etc.). And of course we create regression tests for each reported/detected bug, that is not caught by our existing test suite - therefore we'll add testing for un-masked FP exceptions after this case.

regards, Igor

0 Kudos
Reply