From 1f3476ccddf5adfc6bc4de2d51b6ebb62af83dbf Mon Sep 17 00:00:00 2001 From: David Butcher Date: Wed, 11 Apr 2012 12:42:13 +0100 Subject: [PATCH] Adding missing header file --- headers/unit_test_x_operation_x_tolerant.h | 211 +++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 headers/unit_test_x_operation_x_tolerant.h diff --git a/headers/unit_test_x_operation_x_tolerant.h b/headers/unit_test_x_operation_x_tolerant.h new file mode 100644 index 0000000..5aa19b1 --- /dev/null +++ b/headers/unit_test_x_operation_x_tolerant.h @@ -0,0 +1,211 @@ +/* + * Copyright 2011-12 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * NE10 Library : headers/unit_test_x_operation_x.h + */ + +#include "./unit_test_common.h" + +// This function signature applies the operations with the format "*c_*_*" (e.g. 'add'c_'float'_'neon') +typedef arm_result_t (*arm_func_4args_t)(void * dst, void * src1, void * src2, unsigned int count); +arm_func_4args_t ftbl[ OP_COUNT * IMPL_COUNT ]; + + +// this function is implemented in the unit test source files +// it is meant to initialise the function table defined above. +extern void init_ftbl(); + + +unsigned int i = 0; // loop iterator +unsigned int max = 0; // number of iterations in each function +int opcode = -1; // the operation which will be tested (a single unit can have any number of operations/functions) +int impl = -1; // selects which particular implementation of the chosen operation must run +int mute = 0; // 0 == print output; 1 == do not print anything; + +struct timeval before, after, lapsed, dummy; +double dt_test_overhead = 0.0; +double dt_test_sample = 0.0; +double elapsed = 0.0; +struct timezone zone; + +// there is a max of "4" components in a vec +#define MAX_VEC_COMPONENTS 4 + +arm_float_t * thesrc1 = NULL; +arm_float_t * thesrc2 = NULL; +arm_float_t * thedst[IMPL_COUNT]; // output from different implementations are stored in separate arrays for varification +int done_init = 0; + +arm_result_t test_operation() +{ + // initialize if not done so + if ( 0 == done_init ) + { + thesrc1 = (arm_float_t*) malloc( ARRLEN * sizeof(arm_float_t) * MAX_VEC_COMPONENTS ); + FILL_FLOAT_ARRAY_LIMIT( thesrc1, ARRLEN * MAX_VEC_COMPONENTS ); // random initialization + + thesrc2 = (arm_float_t*) malloc( ARRLEN * sizeof(arm_float_t) * MAX_VEC_COMPONENTS ); + FILL_FLOAT_ARRAY_LIMIT( thesrc2, ARRLEN * MAX_VEC_COMPONENTS ); // random initialization + + for ( i = 0; i OP_COUNT + || impl < 0 || impl > IMPL_COUNT ) + { + fprintf ( stderr, "\t WARNING: Operation number %d and/or implementaion number %d are not acceptable values. \n", opcode, impl ); + exit( NE10_ERR ); + } + + if ( impl == 0 ) // run all implementations and verify + { + // first, make sure all of the implementations do exist + for ( i = FTBL_IDX(opcode, 1); i <= FTBL_IDX(opcode, IMPL_COUNT); i++ ) + { + if ( NULL == ftbl[i] ) + { + fprintf ( stderr, "\t WARNING: One or more implementations of operation number %d were not found. \n", opcode ); + exit( NE10_ERR ); + } + } + + // try all the implementatins here.. + mute = 1; // do not print anything + + // opcode remains the same but we iterate through different implementations here.. + for ( impl= 1; impl <= IMPL_COUNT; impl ++ ) + { + test_operation(); + } + + // now verify + arm_float_t * _output = NULL; // [ IMPL_COUNT * MAX_VEC_COMPONENTS ]; // one for each implementation, c, asm, neon... + int warns = 0; + int item_width = opcode; // there's no easy way to guess the actual number of an item's components but using the opcode (1=float, 2=vec2, ...) + _output = (arm_float_t*) malloc( IMPL_COUNT * sizeof(arm_float_t) * item_width ); + for ( i = 0; i < ARRLEN; i++ ) + { + for ( impl= 1; impl <= IMPL_COUNT; impl ++ ) + { + memcpy ( &_output[ (impl-1) * item_width ], &thedst[ impl-1 ][ i * item_width ], sizeof(arm_float_t) * item_width ); + } + + int pos = 0; + for ( impl = 2; impl <= IMPL_COUNT; impl ++ ) // compare the output from the 2nd, 3rd, 4th, etc. to the first one so start at 2 + { + for ( pos = 0; pos < item_width; pos++ ) // compare corresponding components of the items + { + assert ( _output[ ((1-1)*item_width)+pos ] == _output[ ((1-1)*item_width)+pos ] ); // check for not-a-number + assert ( _output[ ((impl-1)*item_width)+pos ] == _output[ ((impl-1)*item_width)+pos ] ); // check for not-a-number + + if ( ! EQUALS_FLOAT( _output[ ((1-1)*item_width)+pos ] , _output[ ((impl-1)*item_width)+pos ], ERROR_MARGIN_LARGE ) ) // accept larger errors + { fprintf( stderr, "\t\t WARNING: In opcode [%d], implementation [1] != implemenation [%d] on item [%d -> %d]\n", + opcode, impl, i, pos+1 ); + warns++; } + + // stop after 10 warnings + if ( warns >= ACCEPTABLE_WARNS ) + { fprintf ( stderr, "\t WARNING: One or more mismatching values were found. \n" ); + exit( NE10_ERR ); + } + } + } + } + free( _output ); _output = (arm_float_t *) NULL; + + if ( 0 == warns ) + { + return NE10_OK; + } + + fprintf ( stderr, "\t WARNING: One or more mismatching values were found. \n" ); + exit( NE10_ERR ); + } + else // run a particular implementation + { + if ( !mute ) printf( "opcode=%d;impl=%d;%d;%d;", opcode, impl, ARRLEN, max ); + + // ge the overhead + MEASURE( dt_test_overhead, + for ( i = 0 ; i < max; i++ ) + { + } + ); + + test_operation(); + } + + + + // free any allocated memory... + free( thesrc1 ); + free( thesrc2 ); + for ( i = 0; i