CMSIS-DSP: Some improvements for sign conversion warnings.

Added new tests for function in utils.h
pull/19/head
Christophe Favergeon 4 years ago
parent dcc48027bd
commit 99bcacd027

@ -27,6 +27,7 @@
#define _ARM_MATH_UTILS_H_
#include "arm_math_types.h"
#include <limits.h>
#ifdef __cplusplus
extern "C"
@ -47,6 +48,7 @@ extern "C"
/**
* @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type.
It should not be used with negative values.
*/
__STATIC_FORCEINLINE uint32_t arm_recip_q31(
q31_t in,
@ -60,11 +62,11 @@ extern "C"
if (in > 0)
{
signBits = ((uint32_t) (__CLZ( in) - 1));
signBits = ((uint32_t) (__CLZ( (uint32_t)in) - 1));
}
else
{
signBits = ((uint32_t) (__CLZ(-in) - 1));
signBits = ((uint32_t) (__CLZ((uint32_t)(-in)) - 1));
}
/* Convert input sample to 1.31 format */
@ -98,6 +100,7 @@ extern "C"
/**
* @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type.
It should not be used with negative values.
*/
__STATIC_FORCEINLINE uint32_t arm_recip_q15(
q15_t in,
@ -105,21 +108,21 @@ extern "C"
const q15_t * pRecipTable)
{
q15_t out = 0;
uint32_t tempVal = 0;
int32_t tempVal = 0;
uint32_t index = 0, i = 0;
uint32_t signBits = 0;
if (in > 0)
{
signBits = ((uint32_t)(__CLZ( in) - 17));
signBits = ((uint32_t)(__CLZ( (uint32_t)in) - 17));
}
else
{
signBits = ((uint32_t)(__CLZ(-in) - 17));
signBits = ((uint32_t)(__CLZ((uint32_t)(-in)) - 17));
}
/* Convert input sample to 1.15 format */
in = (in << signBits);
in = (q15_t)(in << signBits);
/* calculation of index for initial approximated Val */
index = (uint32_t)(in >> 8);
@ -132,8 +135,8 @@ extern "C"
/* running approximation for two iterations */
for (i = 0U; i < 2U; i++)
{
tempVal = (uint32_t) (((q31_t) in * out) >> 15);
tempVal = 0x7FFFu - tempVal;
tempVal = (((q31_t) in * out) >> 15);
tempVal = 0x7FFF - tempVal;
/* 1.15 with exp 1 */
out = (q15_t) (((q31_t) out * tempVal) >> 14);
/* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */
@ -159,13 +162,13 @@ __STATIC_INLINE void arm_norm_64_to_32u(uint64_t in, int32_t * normalized, int3
int32_t hi = (int32_t) (in >> 32);
int32_t lo = (int32_t) ((in << 32) >> 32);
n1 = __CLZ(hi) - 32;
n1 = __CLZ((uint32_t)hi) - 32;
if (!n1)
{
/*
* input fits in 32-bit
*/
n1 = __CLZ(lo);
n1 = __CLZ((uint32_t)lo);
if (!n1)
{
/*
@ -201,13 +204,13 @@ __STATIC_INLINE void arm_norm_64_to_32u(uint64_t in, int32_t * normalized, int3
/*
* 64 bit normalization
*/
*normalized = (((uint32_t) lo) >> n1) | (hi << (32 - n1));
*normalized = (int32_t)(((uint32_t)lo) >> n1) | (hi << (32 - n1));
}
}
__STATIC_INLINE q31_t arm_div_q63_to_q31(q63_t num, q31_t den)
__STATIC_INLINE int32_t arm_div_int64_to_int32(int64_t num, int32_t den)
{
q31_t result;
int32_t result;
uint64_t absNum;
int32_t normalized;
int32_t norm;
@ -216,18 +219,25 @@ __STATIC_INLINE q31_t arm_div_q63_to_q31(q63_t num, q31_t den)
* if sum fits in 32bits
* avoid costly 64-bit division
*/
absNum = num > 0 ? num : -num;
if (num == (int64_t)LONG_MIN)
{
absNum = LONG_MAX;
}
else
{
absNum = (uint64_t) (num > 0 ? num : -num);
}
arm_norm_64_to_32u(absNum, &normalized, &norm);
if (norm > 0)
/*
* 32-bit division
*/
result = (q31_t) num / den;
result = (int32_t) num / den;
else
/*
* 64-bit division
*/
result = (q31_t) (num / den);
result = (int32_t) (num / den);
return result;
}

@ -0,0 +1,28 @@
import cmsisdsp as dsp
import numpy as np
recipQ15=np.array([0x7F03, 0x7D13, 0x7B31, 0x795E, 0x7798, 0x75E0,
0x7434, 0x7294, 0x70FF, 0x6F76, 0x6DF6, 0x6C82,
0x6B16, 0x69B5, 0x685C, 0x670C, 0x65C4, 0x6484,
0x634C, 0x621C, 0x60F3, 0x5FD0, 0x5EB5, 0x5DA0,
0x5C91, 0x5B88, 0x5A85, 0x5988, 0x5890, 0x579E,
0x56B0, 0x55C8, 0x54E4, 0x5405, 0x532B, 0x5255,
0x5183, 0x50B6, 0x4FEC, 0x4F26, 0x4E64, 0x4DA6,
0x4CEC, 0x4C34, 0x4B81, 0x4AD0, 0x4A23, 0x4978,
0x48D1, 0x482D, 0x478C, 0x46ED, 0x4651, 0x45B8,
0x4521, 0x448D, 0x43FC, 0x436C, 0x42DF, 0x4255,
0x41CC, 0x4146, 0x40C2, 0x4040])
s,v=dsp.arm_recip_q15(int(0x2000),recipQ15)
print("1 / 0.25")
print(s)
print("%04X -> %f" % (v,((v<<s)/(1<<15))))
print("----\n")
s,v=dsp.arm_recip_q15(1,recipQ15)
print("1 / (1 << 15)")
print(s)
print("%04X -> %f" % (v,((v<<s)/(1<<15))))
print(1<<15)
print("----\n")

@ -88,7 +88,7 @@ void arm_mean_q31(
blkCnt --;
}
*pResult = arm_div_q63_to_q31(sum, blockSize);
*pResult = arm_div_int64_to_int32(sum, blockSize);
}
#else
void arm_mean_q31(

@ -111,10 +111,10 @@ void arm_var_q15(
/* Compute Mean of squares of the input samples
* and then store the result in a temporary variable, meanOfSquares. */
meanOfSquares = arm_div_q63_to_q31(sumOfSquares, (blockSize - 1U));
meanOfSquares = arm_div_int64_to_int32(sumOfSquares, (blockSize - 1U));
/* Compute square of mean */
squareOfMean = arm_div_q63_to_q31((q63_t)sum * sum, (q31_t)(blockSize * (blockSize - 1U)));
squareOfMean = arm_div_int64_to_int32((q63_t)sum * sum, (q31_t)(blockSize * (blockSize - 1U)));
/* mean of the squares minus the square of the mean. */
*pResult = (meanOfSquares - squareOfMean) >> 15;

@ -277,6 +277,7 @@ endif()
if (FASTMATH)
set(FASTMATHSRC Source/Tests/FastMathF64.cpp
Source/Tests/FastMathF32.cpp
Source/Tests/FastMathQ63.cpp
Source/Tests/FastMathQ31.cpp
Source/Tests/FastMathQ15.cpp)
endif()

@ -202,7 +202,7 @@ void assert_equal(unsigned long nb,AnyPattern<T> &pa, AnyPattern<T> &pb)
}
catch(Error &err)
{
sprintf(id," (nb=%lu)",i+1);
sprintf(id," (nb=%lu)",i);
strcat(err.details,id);
throw(err);
}
@ -258,7 +258,7 @@ void assert_near_equal(unsigned long nb,AnyPattern<T> &pa, AnyPattern<T> &pb, T
}
catch(Error &err)
{
sprintf(id," (nb=%lu)",i+1);
sprintf(id," (nb=%lu)",i);
strcat(err.details,id);
throw(err);
}

@ -69,6 +69,7 @@ FPGA driver. Used to read a C array describing how to drive the test.
virtual void ImportPattern_q31(Testing::PatternID_t,char*,Testing::nbSamples_t nb);
virtual void ImportPattern_q15(Testing::PatternID_t,char*,Testing::nbSamples_t nb);
virtual void ImportPattern_q7(Testing::PatternID_t,char*,Testing::nbSamples_t nb);
virtual void ImportPattern_u64(Testing::PatternID_t,char*,Testing::nbSamples_t nb);
virtual void ImportPattern_u32(Testing::PatternID_t,char*,Testing::nbSamples_t nb);
virtual void ImportPattern_u16(Testing::PatternID_t,char*,Testing::nbSamples_t nb);
virtual void ImportPattern_u8(Testing::PatternID_t,char*,Testing::nbSamples_t nb);
@ -87,6 +88,7 @@ FPGA driver. Used to read a C array describing how to drive the test.
virtual void DumpPattern_q31(Testing::outputID_t,Testing::nbSamples_t nb, q31_t* data);
virtual void DumpPattern_q15(Testing::outputID_t,Testing::nbSamples_t nb, q15_t* data);
virtual void DumpPattern_q7(Testing::outputID_t,Testing::nbSamples_t nb, q7_t* data);
virtual void DumpPattern_u64(Testing::outputID_t,Testing::nbSamples_t nb, uint64_t* data);
virtual void DumpPattern_u32(Testing::outputID_t,Testing::nbSamples_t nb, uint32_t* data);
virtual void DumpPattern_u16(Testing::outputID_t,Testing::nbSamples_t nb, uint16_t* data);
virtual void DumpPattern_u8(Testing::outputID_t,Testing::nbSamples_t nb, uint8_t* data);

@ -68,6 +68,9 @@ q15_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t
template <>
q7_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
template <>
uint64_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
template <>
uint32_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
@ -108,6 +111,9 @@ q15_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
template <>
q7_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
template <>
uint64_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
template <>
uint32_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
@ -126,6 +132,7 @@ extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,q63_t*,Patte
extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,q31_t*,PatternMgr *);
extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,q15_t*,PatternMgr *);
extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,q7_t*,PatternMgr *);
extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,uint64_t*,PatternMgr *);
extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,uint32_t*,PatternMgr *);
extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,uint16_t*,PatternMgr *);
extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,uint8_t*,PatternMgr *);

@ -74,6 +74,7 @@ Semihosting driver. Used to read a text file describing how to drive the test.
virtual void ImportPattern_q31(Testing::PatternID_t,char*,Testing::nbSamples_t nb=0);
virtual void ImportPattern_q15(Testing::PatternID_t,char*,Testing::nbSamples_t nb=0);
virtual void ImportPattern_q7(Testing::PatternID_t,char*,Testing::nbSamples_t nb=0);
virtual void ImportPattern_u64(Testing::PatternID_t,char*,Testing::nbSamples_t nb=0);
virtual void ImportPattern_u32(Testing::PatternID_t,char*,Testing::nbSamples_t nb=0);
virtual void ImportPattern_u16(Testing::PatternID_t,char*,Testing::nbSamples_t nb=0);
virtual void ImportPattern_u8(Testing::PatternID_t,char*,Testing::nbSamples_t nb=0);
@ -93,6 +94,7 @@ Semihosting driver. Used to read a text file describing how to drive the test.
virtual void DumpPattern_q31(Testing::outputID_t,Testing::nbSamples_t nb, q31_t*);
virtual void DumpPattern_q15(Testing::outputID_t,Testing::nbSamples_t nb, q15_t*);
virtual void DumpPattern_q7(Testing::outputID_t,Testing::nbSamples_t nb, q7_t*);
virtual void DumpPattern_u64(Testing::outputID_t,Testing::nbSamples_t nb, uint64_t*);
virtual void DumpPattern_u32(Testing::outputID_t,Testing::nbSamples_t nb, uint32_t*);
virtual void DumpPattern_u16(Testing::outputID_t,Testing::nbSamples_t nb, uint16_t*);
virtual void DumpPattern_u8(Testing::outputID_t,Testing::nbSamples_t nb, uint8_t*);

@ -306,6 +306,7 @@ API of Memory managers used in the test framework
virtual void ImportPattern_q31(Testing::PatternID_t,char*,Testing::nbSamples_t nb=MAX_NB_SAMPLES)=0;
virtual void ImportPattern_q15(Testing::PatternID_t,char*,Testing::nbSamples_t nb=MAX_NB_SAMPLES)=0;
virtual void ImportPattern_q7(Testing::PatternID_t,char*,Testing::nbSamples_t nb=MAX_NB_SAMPLES)=0;
virtual void ImportPattern_u64(Testing::PatternID_t,char*,Testing::nbSamples_t nb=MAX_NB_SAMPLES)=0;
virtual void ImportPattern_u32(Testing::PatternID_t,char*,Testing::nbSamples_t nb=MAX_NB_SAMPLES)=0;
virtual void ImportPattern_u16(Testing::PatternID_t,char*,Testing::nbSamples_t nb=MAX_NB_SAMPLES)=0;
virtual void ImportPattern_u8(Testing::PatternID_t,char*,Testing::nbSamples_t nb=MAX_NB_SAMPLES)=0;
@ -338,6 +339,7 @@ API of Memory managers used in the test framework
virtual void DumpPattern_q31(Testing::outputID_t,Testing::nbSamples_t nb, q31_t*)=0;
virtual void DumpPattern_q15(Testing::outputID_t,Testing::nbSamples_t nb, q15_t*)=0;
virtual void DumpPattern_q7(Testing::outputID_t,Testing::nbSamples_t nb, q7_t*)=0;
virtual void DumpPattern_u64(Testing::outputID_t,Testing::nbSamples_t nb, uint64_t*)=0;
virtual void DumpPattern_u32(Testing::outputID_t,Testing::nbSamples_t nb, uint32_t*)=0;
virtual void DumpPattern_u16(Testing::outputID_t,Testing::nbSamples_t nb, uint16_t*)=0;
virtual void DumpPattern_u8(Testing::outputID_t,Testing::nbSamples_t nb, uint8_t*)=0;
@ -421,6 +423,7 @@ public:
q15_t *load_q15(Testing::PatternID_t,Testing::nbSamples_t&,Testing::nbSamples_t maxSamples=MAX_NB_SAMPLES);
q7_t *load_q7(Testing::PatternID_t,Testing::nbSamples_t&,Testing::nbSamples_t maxSamples=MAX_NB_SAMPLES);
uint64_t *load_u64(Testing::PatternID_t,Testing::nbSamples_t&,Testing::nbSamples_t maxSamples=MAX_NB_SAMPLES);
uint32_t *load_u32(Testing::PatternID_t,Testing::nbSamples_t&,Testing::nbSamples_t maxSamples=MAX_NB_SAMPLES);
uint16_t *load_u16(Testing::PatternID_t,Testing::nbSamples_t&,Testing::nbSamples_t maxSamples=MAX_NB_SAMPLES);
uint8_t *load_u8(Testing::PatternID_t,Testing::nbSamples_t&,Testing::nbSamples_t maxSamples=MAX_NB_SAMPLES);
@ -441,6 +444,7 @@ public:
q15_t *local_q15(Testing::nbSamples_t);
q7_t *local_q7(Testing::nbSamples_t);
uint64_t *local_u64(Testing::nbSamples_t);
uint32_t *local_u32(Testing::nbSamples_t);
uint16_t *local_u16(Testing::nbSamples_t);
uint8_t *local_u8(Testing::nbSamples_t);
@ -459,6 +463,7 @@ public:
void dumpPattern_q15(Testing::outputID_t,Testing::nbSamples_t,q15_t*);
void dumpPattern_q7(Testing::outputID_t,Testing::nbSamples_t,q7_t*);
void dumpPattern_u64(Testing::outputID_t,Testing::nbSamples_t,uint64_t*);
void dumpPattern_u32(Testing::outputID_t,Testing::nbSamples_t,uint32_t*);
void dumpPattern_u16(Testing::outputID_t,Testing::nbSamples_t,uint16_t*);
void dumpPattern_u8(Testing::outputID_t,Testing::nbSamples_t,uint8_t*);

@ -265,7 +265,7 @@ void assert_relative_error(unsigned long nb,AnyPattern<float64_t> &pa, AnyPatter
}
catch(Error &err)
{
sprintf(id," (nb=%lu)",i+1);
sprintf(id," (nb=%lu)",i);
strcat(err.details,id);
throw(err);
}
@ -296,7 +296,7 @@ void assert_relative_error(unsigned long nb,AnyPattern<float32_t> &pa, AnyPatter
}
catch(Error &err)
{
sprintf(id," (nb=%lu)",i+1);
sprintf(id," (nb=%lu)",i);
strcat(err.details,id);
throw(err);
}
@ -328,7 +328,7 @@ void assert_relative_error(unsigned long nb,AnyPattern<float16_t> &pa, AnyPatter
}
catch(Error &err)
{
sprintf(id," (nb=%lu)",i+1);
sprintf(id," (nb=%lu)",i);
strcat(err.details,id);
throw(err);
}
@ -371,7 +371,7 @@ void assert_close_error(unsigned long nb,AnyPattern<float64_t> &pref, AnyPattern
}
catch(Error &err)
{
sprintf(id," (nb=%lu)",i+1);
sprintf(id," (nb=%lu)",i);
strcat(err.details,id);
throw(err);
}
@ -414,7 +414,7 @@ void assert_close_error(unsigned long nb,AnyPattern<float32_t> &pref, AnyPattern
}
catch(Error &err)
{
sprintf(id," (nb=%lu)",i+1);
sprintf(id," (nb=%lu)",i);
strcat(err.details,id);
throw(err);
}
@ -458,7 +458,7 @@ void assert_close_error(unsigned long nb,AnyPattern<float16_t> &pref, AnyPattern
}
catch(Error &err)
{
sprintf(id," (nb=%lu)",i+1);
sprintf(id," (nb=%lu)",i);
strcat(err.details,id);
throw(err);
}

@ -100,9 +100,6 @@ namespace Client
delete(this->outputNames);
}
/** Read word 64 from C array
*/
/** Read word 32 from C array
@ -642,6 +639,26 @@ namespace Client
}
}
void FPGA::ImportPattern_u64(Testing::PatternID_t id,char* p,Testing::nbSamples_t nb)
{
unsigned long offset,i;
offset=this->getPatternOffset(id);
const char *patternStart = this->m_patterns + offset;
const uint64_t *src = (const uint64_t*)patternStart;
uint64_t *dst = (uint64_t*)p;
if (dst)
{
for(i=0; i < nb; i++)
{
*dst++ = *src++;
}
}
}
void FPGA::ImportPattern_u32(Testing::PatternID_t id,char* p,Testing::nbSamples_t nb)
{
unsigned long offset,i;
@ -842,6 +859,26 @@ namespace Client
}
}
void FPGA::DumpPattern_u64(Testing::outputID_t id,Testing::nbSamples_t nb, uint64_t* data)
{
std::string fileName = this->getOutputPath(id);
if (data)
{
printf("D: %s\n",fileName.c_str());
Testing::nbSamples_t i=0;
uint64_t t;
uint64_t v;
for(i=0; i < nb; i++)
{
v = data[i];
t = (uint64_t)v;
printf("D: 0x%016llx\n",t);
}
printf("D: END\n");
}
}
void FPGA::DumpPattern_u32(Testing::outputID_t id,Testing::nbSamples_t nb, uint32_t* data)
{
std::string fileName = this->getOutputPath(id);

@ -79,6 +79,13 @@ q7_t *loadPattern(Testing::PatternID_t id, Client::PatternMgr *mgr,Testing::nbSa
return(mgr->load_q7(id,nb,maxSamples));
}
template <>
uint64_t *loadPattern(Testing::PatternID_t id, Client::PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples)
{
return(mgr->load_u64(id,nb,maxSamples));
}
template <>
uint32_t *loadPattern(Testing::PatternID_t id, Client::PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples)
{
@ -142,6 +149,12 @@ q7_t *localPattern(Testing::PatternID_t id, Client::PatternMgr *mgr)
return(mgr->local_q7(id));
}
template <>
uint64_t *localPattern(Testing::PatternID_t id, Client::PatternMgr *mgr)
{
return(mgr->local_u64(id));
}
template <>
uint32_t *localPattern(Testing::PatternID_t id, Client::PatternMgr *mgr)
{
@ -197,6 +210,11 @@ void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t nbSamples,q7_t* dat
mgr->dumpPattern_q7(id,nbSamples,data);
}
void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t nbSamples,uint64_t* data,PatternMgr *mgr)
{
mgr->dumpPattern_u64(id,nbSamples,data);
}
void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t nbSamples,uint32_t* data,PatternMgr *mgr)
{
mgr->dumpPattern_u32(id,nbSamples,data);

@ -55,6 +55,7 @@ LOCAL(q63_t,q63)
LOCAL(q31_t,q31)
LOCAL(q15_t,q15)
LOCAL(q7_t,q7)
LOCAL(uint64_t,u64)
LOCAL(uint32_t,u32)
LOCAL(uint16_t,u16)
LOCAL(uint8_t,u8)
@ -185,6 +186,23 @@ q7_t *PatternMgr::load_q7(Testing::PatternID_t id,Testing::nbSamples_t& nbSample
return((q7_t*)b);
}
uint64_t *PatternMgr::load_u64(Testing::PatternID_t id,Testing::nbSamples_t& nbSamples,Testing::nbSamples_t maxSamples)
{
nbSamples=m_io->GetPatternSize(id);
if ((maxSamples != MAX_NB_SAMPLES) && (maxSamples < nbSamples))
{
nbSamples = maxSamples;
}
char *b = m_mem->NewBuffer(sizeof(uint64_t)*nbSamples);
if (b != NULL)
{
m_io->ImportPattern_u64(id,b,nbSamples);
}
return((uint64_t*)b);
}
uint32_t *PatternMgr::load_u32(Testing::PatternID_t id,Testing::nbSamples_t& nbSamples,Testing::nbSamples_t maxSamples)
{
nbSamples=m_io->GetPatternSize(id);
@ -274,6 +292,11 @@ void PatternMgr::dumpPattern_q7(Testing::outputID_t id,Testing::nbSamples_t nbSa
m_io->DumpPattern_q7(id,nbSamples,data);
}
void PatternMgr::dumpPattern_u64(Testing::outputID_t id,Testing::nbSamples_t nbSamples,uint64_t* data)
{
m_io->DumpPattern_u64(id,nbSamples,data);
}
void PatternMgr::dumpPattern_u32(Testing::outputID_t id,Testing::nbSamples_t nbSamples,uint32_t* data)
{
m_io->DumpPattern_u32(id,nbSamples,data);

@ -865,6 +865,44 @@ namespace Client
}
void Semihosting::ImportPattern_u64(Testing::PatternID_t id,char* p,Testing::nbSamples_t nb)
{
char tmp[256];
Testing::nbSamples_t len;
Testing::nbSamples_t i=0;
uint64_t val;
uint64_t *ptr=(uint64_t*)p;
std::string fileName = this->getPatternPath(id);
FILE *pattern=fopen(fileName.c_str(), "r");
// Ignore word size format
fgets(tmp,256,pattern);
// Get nb of samples
fgets(tmp,256,pattern);
len=atoi(tmp);
if ((nb != MAX_NB_SAMPLES) && (nb < len))
{
len = nb;
}
if (ptr)
{
for(i=0;i<len;i++)
{
// Ignore comment
fgets(tmp,256,pattern);
fscanf(pattern,"0x%016llX\n",&val);
*ptr = val;
ptr++;
}
}
fclose(pattern);
}
void Semihosting::ImportPattern_u32(Testing::PatternID_t id,char* p,Testing::nbSamples_t nb)
{
char tmp[256];
@ -1103,6 +1141,24 @@ namespace Client
fclose(f);
}
}
void Semihosting::DumpPattern_u64(Testing::outputID_t id,Testing::nbSamples_t nb, uint64_t* data)
{
std::string fileName = this->getOutputPath(id);
if (data)
{
FILE *f = fopen(fileName.c_str(),"w");
Testing::nbSamples_t i=0;
uint64_t t;
for(i=0; i < nb; i++)
{
t = (uint64_t)data[i];
fprintf(f,"0x%016llx\n",t);
}
fclose(f);
}
}
void Semihosting::DumpPattern_u32(Testing::outputID_t id,Testing::nbSamples_t nb, uint32_t* data)
{
std::string fileName = this->getOutputPath(id);

@ -21,7 +21,6 @@ class FastMathQ15:public Client::Suite
Client::LocalPattern<q15_t> output;
Client::LocalPattern<int16_t> shift;
// Reference patterns are not loaded when we are in dump mode
Client::RefPattern<q15_t> ref;
Client::RefPattern<int16_t> refShift;

@ -0,0 +1,31 @@
#include "Test.h"
#include "Pattern.h"
#include "dsp/fast_math_functions.h"
class FastMathQ63:public Client::Suite
{
public:
FastMathQ63(Testing::testID_t id);
virtual void setUp(Testing::testID_t,std::vector<Testing::param_t>& paramsArgs,Client::PatternMgr *mgr);
virtual void tearDown(Testing::testID_t,Client::PatternMgr *mgr);
private:
#include "FastMathQ63_decl.h"
Client::Pattern<q63_t> input;
Client::Pattern<uint64_t> inputU64;
Client::Pattern<int64_t> inputS64;
Client::Pattern<int32_t> inputS32;
Client::LocalPattern<int32_t> outputVals;
Client::LocalPattern<int16_t> outputNorms;
// Reference patterns are not loaded when we are in dump mode
Client::RefPattern<int32_t> refVal;
Client::RefPattern<int16_t> refNorm;
};

@ -94,6 +94,12 @@ def initLogValues(format):
ref = ref / 16.0
return(vals,ref)
def normalizeToOne(x):
s = 0
while (abs(x)>1):
x = x /2.0
s = s + 1
return(int(s),x)
def writeTests(config,format):
@ -143,7 +149,7 @@ def writeTests(config,format):
resultValue=[x[0] for x in result]
resultShift=[x[1] for x in result]
config.setOverwrite(True)
config.setOverwrite(False)
config.writeInput(1, numerator,"Numerator")
config.writeInput(1, denominator,"Denominator")
config.writeReference(1, resultValue,"DivisionValue")
@ -185,9 +191,88 @@ def writeTests(config,format):
config.setOverwrite(False)
if format == Tools.Q31 or format == Tools.Q15:
if format == Tools.Q31:
theInput=np.array([1.0-1e-6,0.6,0.5,0.3,0.25,0.1,1.0/(1<<31)])
if format == Tools.Q15:
theInput=np.array([1.0-1e-6,0.6,0.5,0.3,0.25,0.1,1.0/(1<<15)])
ref=1.0 / theInput
shiftAndScaled=np.array([normalizeToOne(x) for x in ref]).transpose()
shiftValues=shiftAndScaled[0].astype(np.int16)
scaledValues=shiftAndScaled[1]
#print(shiftAndScaled)
config.writeInput(1, np.array(theInput),"RecipInput")
config.writeReference(1, scaledValues,"RecipRef")
config.writeReferenceS16(1, shiftValues,"RecipShift")
def tocint32(x):
if x < 0:
return((0x10000000000000000 + x) & 0xFFFFFFFF)
else:
return(x & 0xFFFFFFFF)
# C and Python are not rounding the integer division
# in the same way
def cdiv(a,b):
sign = 1
if ((a<0) and (b>0)) or ((a>0) and (b<0)):
sign = -1
a= abs(a)
b = abs(b)
d = sign*(a // b)
return(d)
def testInt64(config):
theInput=[0x1000000080000000,
0x0000000080000000,
0x0000000020000000,
0x0000000000000000]
ref=[0x40000002,
0x40000000,
0x40000000,
0
]
norms=[-30,-1,1,0]
config.writeInputU64(1,np.array(theInput),"Norm64To32_Input")
config.writeReferenceS16(1,norms,"RefNorm64To32_Norms")
config.writeReferenceS32(1,ref,"RefNorm64To32_Vals")
config.setOverwrite(False)
allCombinations=[(0x7FFFFFFFFFFFFFFF,2),
(-0x7FFFFFFFFFFFFFFF-1,2),
( 0x4000000000000000,0x7FFFFFFF),
( -0x4000000000000000,0x7FFFFFFF),
( 0x2000000000000000,0x7FFFFFFF),
( -0x2000000000000000,0x7FFFFFFF),
( 0x1000000000000000,0x7FFFFFFF),
( -0x1000000000000000,0x7FFFFFFF),
( 0x0000000080000000,2),
( -0x0000000080000000,2),
( 0x0000000040000000,2),
( -0x0000000080000000,2)
]
res = [tocint32(cdiv(x,y)) for (x,y) in allCombinations]
allCombinations=np.array(allCombinations,dtype=np.int64).flatten()
config.writeInputS64(1,allCombinations[0::2],"DivDenInput")
config.writeInputS32(1,allCombinations[1::2],"DivNumInput")
config.writeReferenceU32(1, res,"DivRef")
config.setOverwrite(False)
def writeTestsFloat(config,format):
@ -226,12 +311,16 @@ def generatePatterns():
configq31=Tools.Config(PATTERNDIR,PARAMDIR,"q31")
configq15=Tools.Config(PATTERNDIR,PARAMDIR,"q15")
configq64=Tools.Config(PATTERNDIR,PARAMDIR,"q63")
configf64.setOverwrite(False)
configf32.setOverwrite(False)
configf16.setOverwrite(False)
configq31.setOverwrite(False)
configq15.setOverwrite(False)
configq64.setOverwrite(False)
writeTestsFloat(configf64,Tools.F64)
writeTestsFloat(configf32,0)
@ -239,6 +328,8 @@ def generatePatterns():
writeTests(configq31,31)
writeTests(configq15,15)
testInt64(configq64)
if __name__ == '__main__':
generatePatterns()

@ -13,6 +13,7 @@ BODYANDTAIL = 3
F64 = 64
F32 = 0
F16 = 16
Q63 = 63
Q31 = 31
Q15 = 15
Q7 = 7
@ -20,7 +21,7 @@ Q7 = 7
def loopnb(format,loopkind):
nb = 0
if loopkind == TAILONLY:
if format == 64:
if format == 64 or format == Tools.Q63:
nb = 2
if format == 0 or format == 31:
nb = 3
@ -29,7 +30,7 @@ def loopnb(format,loopkind):
if format == 7:
nb = 15
if loopkind == BODYONLY:
if format == 64:
if format == 64 or format == Tools.Q63:
nb = 4
if format == 0 or format == 31:
nb = 8
@ -38,7 +39,7 @@ def loopnb(format,loopkind):
if format == 7:
nb = 32
if loopkind == BODYANDTAIL:
if format == 64:
if format == 64 or format == Tools.Q63:
nb = 5
if format == 0 or format == 31:
nb = 11 # 9
@ -146,15 +147,30 @@ def to_q7(v):
def s8(r):
return ("0x%s" % format(struct.unpack('<B', struct.pack('<b', r))[0],'02X'))
def u8(r):
return ("0x%s" % format(struct.unpack('<B', struct.pack('<B', r))[0],'02X'))
def s16(r):
return ("0x%s" % format(struct.unpack('<H', struct.pack('<h', r))[0],'04X'))
def u16(r):
return ("0x%s" % format(struct.unpack('<H', struct.pack('<H', r))[0],'04X'))
def s32(r):
return ("0x%s" % format(struct.unpack('<I', struct.pack('<i', r))[0],'08X'))
def u32(r):
return ("0x%s" % format(struct.unpack('<I', struct.pack('<I', r))[0],'08X'))
def s64(r):
return ("0x%s" % format(struct.unpack('<Q', struct.pack('<q', r))[0],'016X'))
def u32(r):
return ("0x%s" % format(struct.unpack('<I', struct.pack('<I', r))[0],'08X'))
def u64(r):
return ("0x%s" % format(struct.unpack('<Q', struct.pack('<Q', r))[0],'016X'))
class Config:
def __init__(self,patternDir,paramDir,ext):
self._patternDir = "%s%s" % (patternDir,ext.upper())
@ -186,6 +202,22 @@ class Config:
else:
return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,self._ext)))
def inputS64P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"s64")))
else:
return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"s64")))
def inputS32P(self,i,name=None):
""" Path to a reference pattern from the ID
@ -261,6 +293,21 @@ class Config:
else:
return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"f16")))
def inputQ63P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"q63")))
else:
return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"q63")))
def inputQ31P(self,i,name=None):
""" Path to a reference pattern from the ID
@ -306,6 +353,23 @@ class Config:
else:
return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"q7")))
def inputU64P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"u64")))
else:
return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"u64")))
def inputU32P(self,i,name=None):
""" Path to a reference pattern from the ID
@ -321,6 +385,39 @@ class Config:
else:
return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"u32")))
def inputU16P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"u16")))
else:
return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"u16")))
def inputU8P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"u8")))
else:
return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"u8")))
def refP(self,i,name=None):
""" Path to a reference pattern from the ID
@ -351,6 +448,22 @@ class Config:
else:
return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s8")))
def refU8P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"u8")))
else:
return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"u8")))
def refS16P(self,i,name=None):
""" Path to a reference pattern from the ID
@ -366,6 +479,22 @@ class Config:
else:
return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s16")))
def refU16P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"u16")))
else:
return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"u16")))
def refS32P(self,i,name=None):
""" Path to a reference pattern from the ID
@ -381,6 +510,55 @@ class Config:
else:
return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s32")))
def refU32P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"u32")))
else:
return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"u32")))
def refS64P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"s64")))
else:
return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s64")))
def refU64P(self,i,name=None):
""" Path to a reference pattern from the ID
Args:
i (int): ID to the reference pattern
Raises:
Nothing
Returns:
str : path to the file where to generate the pattern data
"""
if name:
return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"u64")))
else:
return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"u64")))
def refQ63P(self,i,name=None):
""" Path to a reference pattern from the ID
@ -638,6 +816,85 @@ class Config:
f.write("// %d\n" % v)
f.write("%s\n" % s16(v))
def _writeVectorU16(self,i,data):
""" Write pattern data
The format is recognized by the text framework script.
First line is the sample width (B,H or W for 8,16 or 32 bits)
Second line is number of samples
Other lines are hexadecimal representation of the samples in format
which can be read on big endian ARM.
Args:
j (int): ID of pattern file
data (array): Vector containing the data
Raises:
Nothing
Returns:
Nothing
"""
if self.canOverwrite(i):
with open(i,"w") as f:
# Write sample dimension nb sample header
#np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
f.write("H\n%d\n" % len(data))
for v in data:
f.write("// %d\n" % v)
f.write("%s\n" % u16(v))
def _writeVectorS64(self,i,data):
""" Write pattern data
The format is recognized by the text framework script.
First line is the sample width (B,H or W for 8,16 or 32 bits)
Second line is number of samples
Other lines are hexadecimal representation of the samples in format
which can be read on big endian ARM.
Args:
j (int): ID of pattern file
data (array): Vector containing the data
Raises:
Nothing
Returns:
Nothing
"""
if self.canOverwrite(i):
with open(i,"w") as f:
# Write sample dimension nb sample header
#np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
f.write("D\n%d\n" % len(data))
for v in data:
f.write("// %d\n" % v)
f.write("%s\n" % s64(v))
def _writeVectorU64(self,i,data):
""" Write pattern data
The format is recognized by the text framework script.
First line is the sample width (B,H or W for 8,16 or 32 bits)
Second line is number of samples
Other lines are hexadecimal representation of the samples in format
which can be read on big endian ARM.
Args:
j (int): ID of pattern file
data (array): Vector containing the data
Raises:
Nothing
Returns:
Nothing
"""
if self.canOverwrite(i):
with open(i,"w") as f:
# Write sample dimension nb sample header
#np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
f.write("D\n%d\n" % len(data))
for v in data:
f.write("// %d\n" % v)
f.write("%s\n" % u64(v))
def _writeVectorS32(self,i,data):
""" Write pattern data
@ -742,6 +999,32 @@ class Config:
f.write("// %d\n" % v)
f.write("%s\n" % s8(v))
def _writeVectorU8(self,i,data):
""" Write pattern data
The format is recognized by the text framework script.
First line is the sample width (B,H or W for 8,16 or 32 bits)
Second line is number of samples
Other lines are hexadecimal representation of the samples in format
which can be read on big endian ARM.
Args:
j (int): ID of pattern file
data (array): Vector containing the data
Raises:
Nothing
Returns:
Nothing
"""
if self.canOverwrite(i):
with open(i,"w") as f:
# Write sample dimension nb sample header
#np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
f.write("B\n%d\n" % len(data))
for v in data:
f.write("// %d\n" % v)
f.write("%s\n" % u8(v))
def writeReference(self,j,data,name=None):
if (self._ext == "f64"):
self._writeVectorF64(self.refP(j,name),data)
@ -757,10 +1040,22 @@ class Config:
self._writeVectorQ15(self.refP(j,name),data)
if (self._ext == "q7"):
self._writeVectorQ7(self.refP(j,name),data)
if (self._ext == "s64"):
self._writeVectorS64(self.refP(j,name),data)
if (self._ext == "u64"):
self._writeVectorU64(self.refP(j,name),data)
if (self._ext == "s32"):
self._writeVectorS32(self.refP(j,name),data)
if (self._ext == "u32"):
self._writeVectorU32(self.refP(j,name),data)
if (self._ext == "s16"):
self._writeVectorS16(self.refP(j,name),data)
if (self._ext == "u16"):
self._writeVectorU16(self.refP(j,name),data)
if (self._ext == "s8"):
self._writeVectorS8(self.refP(j,name),data)
if (self._ext == "u8"):
self._writeVectorU8(self.refP(j,name),data)
def writeReferenceQ63(self,j,data,name=None):
self._writeVectorQ63(self.refQ63P(j,name),data)
@ -777,6 +1072,21 @@ class Config:
def writeReferenceS32(self,j,data,name=None):
self._writeVectorS32(self.refS32P(j,name),data)
def writeReferenceS64(self,j,data,name=None):
self._writeVectorS64(self.refS64P(j,name),data)
def writeReferenceU8(self,j,data,name=None):
self._writeVectorU8(self.refU8P(j,name),data)
def writeReferenceU16(self,j,data,name=None):
self._writeVectorU16(self.refU16P(j,name),data)
def writeReferenceU32(self,j,data,name=None):
self._writeVectorU32(self.refU32P(j,name),data)
def writeReferenceU64(self,j,data,name=None):
self._writeVectorU64(self.refU64P(j,name),data)
def writeReferenceF32(self,j,data,name=None):
self._writeVectorF32(self.refF32P(j,name),data)
@ -790,16 +1100,26 @@ class Config:
self._writeVectorF32(self.inputP(j,name),data)
if (self._ext == "f16"):
self._writeVectorF16(self.inputP(j,name),data)
if (self._ext == "q63"):
self._writeVectorQ63(self.inputP(j,name),data)
if (self._ext == "q31"):
self._writeVectorQ31(self.inputP(j,name),data)
if (self._ext == "q15"):
self._writeVectorQ15(self.inputP(j,name),data)
if (self._ext == "q7"):
self._writeVectorQ7(self.inputP(j,name),data)
if (self._ext == "s64"):
self._writeVectorS64(self.inputP(j,name),data)
if (self._ext == "u64"):
self._writeVectorU64(self.inputP(j,name),data)
if (self._ext == "s32"):
self._writeVectorS32(self.inputP(j,name),data)
if (self._ext == "u32"):
self._writeVectorU32(self.inputP(j,name),data)
if (self._ext == "s8"):
self._writeVectorS8(self.inputP(j,name),data)
if (self._ext == "u8"):
self._writeVectorU8(self.inputP(j,name),data)
def writeInputF32(self,j,data,name=None):
self._writeVectorF32(self.inputF32P(j,name),data)
@ -807,6 +1127,9 @@ class Config:
def writeInputF16(self,j,data,name=None):
self._writeVectorF16(self.inputF16P(j,name),data)
def writeInputQ63(self,j,data,name=None):
self._writeVectorQ63(self.inputQ63P(j,name),data)
def writeInputQ31(self,j,data,name=None):
self._writeVectorQ31(self.inputQ31P(j,name),data)
@ -816,6 +1139,9 @@ class Config:
def writeInputQ7(self,j,data,name=None):
self._writeVectorQ7(self.inputQ7P(j,name),data)
def writeInputS64(self,j,data,name=None):
self._writeVectorS64(self.inputS64P(j,name),data)
def writeInputS32(self,j,data,name=None):
self._writeVectorS32(self.inputS32P(j,name),data)
@ -825,9 +1151,18 @@ class Config:
def writeInputS8(self,j,data,name=None):
self._writeVectorS8(self.inputS8P(j,name),data)
def writeInputU64(self,j,data,name=None):
self._writeVectorU64(self.inputU64P(j,name),data)
def writeInputU32(self,j,data,name=None):
self._writeVectorU32(self.inputU32P(j,name),data)
def writeInputU16(self,j,data,name=None):
self._writeVectorU16(self.inputU16P(j,name),data)
def writeInputU8(self,j,data,name=None):
self._writeVectorU8(self.inputU8P(j,name),data)
def writeParam(self,j,data,name=None):
""" Write pattern data

@ -0,0 +1,16 @@
H
7
// 0.999999
0x7FFF
// 0.600000
0x4CCD
// 0.500000
0x4000
// 0.300000
0x2666
// 0.250000
0x2000
// 0.100000
0x0CCD
// 0.000031
0x0001

@ -0,0 +1,16 @@
H
7
// 0.500001
0x4000
// 0.833333
0x6AAB
// 1.000000
0x7FFF
// 0.833333
0x6AAB
// 1.000000
0x7FFF
// 0.625000
0x5000
// 1.000000
0x7FFF

@ -0,0 +1,16 @@
H
7
// 1
0x0001
// 1
0x0001
// 1
0x0001
// 2
0x0002
// 2
0x0002
// 4
0x0004
// 15
0x000F

@ -0,0 +1,16 @@
W
7
// 0.999999
0x7FFFF79D
// 0.600000
0x4CCCCCCD
// 0.500000
0x40000000
// 0.300000
0x26666666
// 0.250000
0x20000000
// 0.100000
0x0CCCCCCD
// 0.000000
0x00000001

@ -0,0 +1,16 @@
W
7
// 0.500001
0x40000432
// 0.833333
0x6AAAAAAB
// 1.000000
0x7FFFFFFF
// 0.833333
0x6AAAAAAB
// 1.000000
0x7FFFFFFF
// 0.625000
0x50000000
// 1.000000
0x7FFFFFFF

@ -0,0 +1,16 @@
H
7
// 1
0x0001
// 1
0x0001
// 1
0x0001
// 2
0x0002
// 2
0x0002
// 4
0x0004
// 31
0x001F

@ -0,0 +1,26 @@
D
12
// 9223372036854775807
0x7FFFFFFFFFFFFFFF
// -9223372036854775808
0x8000000000000000
// 4611686018427387904
0x4000000000000000
// -4611686018427387904
0xC000000000000000
// 2305843009213693952
0x2000000000000000
// -2305843009213693952
0xE000000000000000
// 1152921504606846976
0x1000000000000000
// -1152921504606846976
0xF000000000000000
// 2147483648
0x0000000080000000
// -2147483648
0xFFFFFFFF80000000
// 1073741824
0x0000000040000000
// -2147483648
0xFFFFFFFF80000000

@ -0,0 +1,26 @@
W
12
// 2
0x00000002
// 2
0x00000002
// 2147483647
0x7FFFFFFF
// 2147483647
0x7FFFFFFF
// 2147483647
0x7FFFFFFF
// 2147483647
0x7FFFFFFF
// 2147483647
0x7FFFFFFF
// 2147483647
0x7FFFFFFF
// 2
0x00000002
// 2
0x00000002
// 2
0x00000002
// 2
0x00000002

@ -0,0 +1,26 @@
W
12
// 4294967295
0xFFFFFFFF
// 0
0x00000000
// 2147483649
0x80000001
// 2147483647
0x7FFFFFFF
// 1073741824
0x40000000
// 3221225472
0xC0000000
// 536870912
0x20000000
// 3758096384
0xE0000000
// 1073741824
0x40000000
// 3221225472
0xC0000000
// 536870912
0x20000000
// 3221225472
0xC0000000

@ -0,0 +1,10 @@
D
4
// 1152921506754330624
0x1000000080000000
// 2147483648
0x0000000080000000
// 536870912
0x0000000020000000
// 0
0x0000000000000000

@ -0,0 +1,10 @@
H
4
// -30
0xFFE2
// -1
0xFFFF
// 1
0x0001
// 0
0x0000

@ -0,0 +1,10 @@
W
4
// 1073741826
0x40000002
// 1073741824
0x40000000
// 1073741824
0x40000000
// 0
0x00000000

@ -3,7 +3,8 @@
#include "Error.h"
#include "Test.h"
#include "arm_common_tables.h"
#include "dsp/utils.h"
#define SNR_THRESHOLD 69
/*
@ -19,6 +20,7 @@ a double precision computation.
#define LOG_ABS_ERROR ((q15_t)3)
#define ABS_ATAN_ERROR ((q15_t)3)
#define DIV_ERROR ((q15_t)2)
#define RECIP_ERROR ((q15_t)2)
void FastMathQ15::test_vlog_q15()
@ -131,6 +133,24 @@ a double precision computation.
}
void FastMathQ15::test_recip_q15()
{
const q15_t *inp = input.ptr();
q15_t *outp = output.ptr();
int16_t *shiftp = shift.ptr();
for(unsigned long i=0; i < ref.nbSamples(); i++)
{
shiftp[i] = arm_recip_q15(inp[i],&outp[i],armRecipTableQ15);
}
ASSERT_SNR(ref,output,(float32_t)SNR_THRESHOLD);
ASSERT_NEAR_EQ(ref,output,RECIP_ERROR);
ASSERT_EQ(refShift,shift);
}
void FastMathQ15::setUp(Testing::testID_t id,std::vector<Testing::param_t>& paramsArgs,Client::PatternMgr *mgr)
{
@ -222,6 +242,19 @@ a double precision computation.
}
break;
case FastMathQ15::TEST_RECIP_Q15_10:
{
input.reload(FastMathQ15::RECIPINPUT1_Q15_ID,mgr);
ref.reload(FastMathQ15::RECIP_VAL_Q15_ID,mgr);
refShift.reload(FastMathQ15::RECIP_SHIFT_S16_ID,mgr);
output.create(ref.nbSamples(),FastMathQ15::OUT_Q15_ID,mgr);
shift.create(ref.nbSamples(),FastMathQ15::SHIFT_S16_ID,mgr);
}
break;
}
}

@ -3,6 +3,8 @@
#include "Error.h"
#include "Test.h"
#include "arm_common_tables.h"
#include "dsp/utils.h"
#define SNR_THRESHOLD 100
/*
@ -18,6 +20,7 @@ a double precision computation.
#define LOG_ABS_ERROR ((q31_t)2)
#define ABS_ATAN_ERROR ((q31_t)3)
#define RECIP_ERROR ((q31_t)10)
void FastMathQ31::test_atan2_scalar_q31()
{
@ -127,6 +130,24 @@ a double precision computation.
}
void FastMathQ31::test_recip_q31()
{
const q31_t *inp = input.ptr();
q31_t *outp = output.ptr();
int16_t *shiftp = shift.ptr();
for(unsigned long i=0; i < ref.nbSamples(); i++)
{
shiftp[i] = arm_recip_q31(inp[i],&outp[i],armRecipTableQ31);
}
ASSERT_SNR(ref,output,(float32_t)SNR_THRESHOLD);
ASSERT_NEAR_EQ(ref,output,RECIP_ERROR);
ASSERT_EQ(refShift,shift);
}
void FastMathQ31::setUp(Testing::testID_t id,std::vector<Testing::param_t>& paramsArgs,Client::PatternMgr *mgr)
{
@ -218,6 +239,19 @@ a double precision computation.
}
break;
case FastMathQ31::TEST_RECIP_Q31_10:
{
input.reload(FastMathQ31::RECIPINPUT1_Q31_ID,mgr);
ref.reload(FastMathQ31::RECIP_VAL_Q31_ID,mgr);
refShift.reload(FastMathQ31::RECIP_SHIFT_S16_ID,mgr);
output.create(ref.nbSamples(),FastMathQ31::OUT_Q31_ID,mgr);
shift.create(ref.nbSamples(),FastMathQ31::SHIFT_S16_ID,mgr);
}
break;
}
}

@ -0,0 +1,102 @@
#include "FastMathQ63.h"
#include <stdio.h>
#include "Error.h"
#include "Test.h"
#include "arm_common_tables.h"
#include "dsp/utils.h"
#define SNR_THRESHOLD 100
/*
Reference patterns are generated with
a double precision computation.
*/
#define ABS_ERROR ((q63_t)0)
void FastMathQ63::test_norm_64_to_32u()
{
const uint64_t *inp = inputU64.ptr();
int32_t *outValp = outputVals.ptr();
int16_t *outNormp = outputNorms.ptr();
unsigned long i;
for(i=0; i < refVal.nbSamples(); i++)
{
int32_t val;
int32_t norm;
arm_norm_64_to_32u(inp[i],&val,&norm);
outValp[i]=val;
outNormp[i]=norm;
}
ASSERT_EQ(refVal,outputVals);
ASSERT_EQ(refNorm,outputNorms);
}
void FastMathQ63::test_div_int64_to_int32()
{
const int64_t *denp = inputS64.ptr();
const int32_t *nump = inputS32.ptr();
int32_t *outValp = outputVals.ptr();
unsigned long i;
for(i=0; i < refVal.nbSamples(); i++)
{
int32_t val;
val = arm_div_int64_to_int32(denp[i],nump[i]);
outValp[i]=val;
}
ASSERT_EQ(refVal,outputVals);
}
void FastMathQ63::setUp(Testing::testID_t id,std::vector<Testing::param_t>& paramsArgs,Client::PatternMgr *mgr)
{
(void)paramsArgs;
switch(id)
{
case FastMathQ63::TEST_NORM_64_TO_32U_1:
{
inputU64.reload(FastMathQ63::NORMINPUT1_U64_ID,mgr);
refVal.reload(FastMathQ63::NORM_REF_VALS_S32_ID,mgr);
refNorm.reload(FastMathQ63::NORM_REF_S16_ID,mgr);
outputVals.create(refVal.nbSamples(),FastMathQ63::OUT_S32_ID,mgr);
outputNorms.create(refNorm.nbSamples(),FastMathQ63::NORMS_S16_ID,mgr);
}
break;
case FastMathQ63::TEST_DIV_INT64_TO_INT32_2:
{
inputS64.reload(FastMathQ63::DIV_DEN_INPUT1_S64_ID,mgr);
inputS32.reload(FastMathQ63::DIV_NUM_INPUT1_S32_ID,mgr);
refVal.reload(FastMathQ63::DIV_REF_S32_ID,mgr);
outputVals.create(refVal.nbSamples(),FastMathQ63::OUT_S32_ID,mgr);
}
break;
}
}
void FastMathQ63::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
{
(void)id;
(void)mgr;
//output.dump(mgr);
}

@ -1831,6 +1831,10 @@ group Root {
Pattern ATAN2INPUT1_Q31_ID : Atan2Input1_q31.txt
Pattern ATAN2_Q31_ID : Atan2Ref1_q31.txt
Pattern RECIPINPUT1_Q31_ID : RecipInput1_q31.txt
Pattern RECIP_VAL_Q31_ID : RecipRef1_q31.txt
Pattern RECIP_SHIFT_S16_ID : RecipShift1_s16.txt
Pattern COS1_Q31_ID : Cos1_q31.txt
Pattern SIN1_Q31_ID : Sin1_q31.txt
Pattern SQRT1_Q31_ID : Sqrt1_q31.txt
@ -1856,6 +1860,7 @@ group Root {
test_vlog_q31 nb=4n:test_vlog_q31
test_vlog_q31 nb=4n+1:test_vlog_q31
test_atan2_scalar_q31:test_atan2_scalar_q31
test_recip_q31:test_recip_q31
}
}
@ -1880,6 +1885,10 @@ group Root {
Pattern ATAN2INPUT1_Q15_ID : Atan2Input1_q15.txt
Pattern ATAN2_Q15_ID : Atan2Ref1_q15.txt
Pattern RECIPINPUT1_Q15_ID : RecipInput1_q15.txt
Pattern RECIP_VAL_Q15_ID : RecipRef1_q15.txt
Pattern RECIP_SHIFT_S16_ID : RecipShift1_s16.txt
Output OUT_Q15_ID : Output
Output SHIFT_S16_ID : Output
@ -1893,6 +1902,28 @@ group Root {
test_vlog_q15 nb=4n:test_vlog_q15
test_vlog_q15 nb=4n+1:test_vlog_q15
test_atan2_scalar_q15:test_atan2_scalar_q15
test_recip_q15:test_recip_q15
}
}
suite Fast Maths Q63 {
class = FastMathQ63
folder = FastMathQ63
Pattern NORMINPUT1_U64_ID : Norm64To32_Input1_u64.txt
Pattern NORM_REF_S16_ID : RefNorm64To32_Norms1_s16.txt
Pattern NORM_REF_VALS_S32_ID : RefNorm64To32_Vals1_s32.txt
Pattern DIV_DEN_INPUT1_S64_ID : DivDenInput1_s64.txt
Pattern DIV_NUM_INPUT1_S32_ID : DivNumInput1_s32.txt
Pattern DIV_REF_S32_ID : DivRef1_u32.txt
Output OUT_S32_ID : Output
Output NORMS_S16_ID : Output
Functions {
test_norm_64_to_32u:test_norm_64_to_32u
test_div_int64_to_int32:test_div_int64_to_int32
}
}
}

Loading…
Cancel
Save