diff --git a/NeoMathEngine/test/src/inference/VectorBenchmark.cpp b/NeoMathEngine/test/src/inference/VectorBenchmark.cpp index 1bb9a7221..a8dbca7bb 100644 --- a/NeoMathEngine/test/src/inference/VectorBenchmark.cpp +++ b/NeoMathEngine/test/src/inference/VectorBenchmark.cpp @@ -35,76 +35,118 @@ static const char* vectorFunctionsNames[]{ "VectorHSwish" }; -static void vectorBenchmark( int function, int testCount, int vectorSize, const CInterval& vectorValuesInterval, - int seed, IPerformanceCounters& counters, std::ofstream& fout ) +//------------------------------------------------------------------------------------------------------------ + +class VectorBenchmarkParams final { +public: + int Function = -2; + int TestCount = -1; + int VectorSize = -1; + IPerformanceCounters* Counters = nullptr; + std::ofstream FOut{}; + + VectorBenchmarkParams( int function, int testCount, int vectorSize, + const CInterval& valuesInterval, int seed ); + ~VectorBenchmarkParams() { delete Counters; } + + void SetNextSeedForFunction( int function, int seed ); + + CFloatWrapper GetInputBuffer() { return CFloatWrapper( MathEngine(), input.data(), VectorSize ); } + CFloatWrapper GetSecondBuffer() { return CFloatWrapper( MathEngine(), second.data(), VectorSize ); } + CFloatWrapper GetResultBuffer() { return CFloatWrapper( MathEngine(), result.data(), VectorSize ); } + CFloatWrapper GetZeroVal() { float zero = 0; return CFloatWrapper( MathEngine(), &zero, 1 ); } + CFloatWrapper GetMulVal() { + float multiplier = static_cast( random.Uniform( 1, valuesInterval.End ) ); + return CFloatWrapper( MathEngine(), &multiplier, 1 ); + } + +private: + const CInterval& valuesInterval; + CRandom random; + + std::vector input; + std::vector second; + std::vector result; +}; + +VectorBenchmarkParams::VectorBenchmarkParams( int function, int testCount, int vectorSize, + const CInterval& valuesInterval, int seed ) : + Function( function ), + TestCount( testCount ), + VectorSize( vectorSize ), + Counters( MathEngine().CreatePerformanceCounters() ), + FOut( std::ofstream( "VectorBenchmarkTest.csv", std::ios::app ) ), + valuesInterval( valuesInterval ) +{ + FOut << "\n---------------------------" << std::endl; + input.resize( vectorSize ); + second.resize( vectorSize ); + result.resize( vectorSize ); + SetNextSeedForFunction( function, seed ); +} + +void VectorBenchmarkParams::SetNextSeedForFunction( int function, int seed ) { - CRandom random( seed ); - CREATE_FILL_FLOAT_ARRAY( input, vectorValuesInterval.Begin, vectorValuesInterval.End, vectorSize, random ) - CREATE_FILL_FLOAT_ARRAY( second, vectorValuesInterval.Begin, vectorValuesInterval.End, vectorSize, random ) - std::vector result( vectorSize, 0 ); - - float zero = 0; - float multiplier = static_cast( random.Uniform( 1, vectorValuesInterval.End ) ); - CFloatWrapper zeroVal( MathEngine(), &zero, 1 ); - CFloatWrapper mulVal( MathEngine(), &multiplier, 1 ); - ASSERT_EXPR( ( ( CConstFloatHandle )mulVal ).GetValueAt( 0 ) > 0 ); - - if( function == -1 ) { // warm-up - return; + Function = function; + random = CRandom( seed ); + for( int i = 0; i < VectorSize; ++i ) { + input[i] = static_cast( random.Uniform( valuesInterval.Begin, valuesInterval.End ) ); + second[i] = static_cast( random.Uniform( valuesInterval.Begin, valuesInterval.End ) ); + result[i] = 0; + } +} + +//------------------------------------------------------------------------------------------------------------ + +static double vectorBenchmark( VectorBenchmarkParams& params ) +{ + CFloatWrapper zeroVal = params.GetInputBuffer(); + CFloatWrapper mulVal = params.GetMulVal(); + CConstFloatHandle mulHandle = mulVal; + ASSERT_EXPR( mulHandle.GetValueAt( 0 ) > 0 ); + + CFloatWrapper input = params.GetInputBuffer(); + CFloatWrapper second = params.GetSecondBuffer(); + CFloatWrapper result = params.GetResultBuffer(); + const int vectorSize = params.VectorSize; + + if( params.Function == -1 ) { // warm-up + MathEngine().VectorCopy( result, input, vectorSize ); + MathEngine().VectorFill( result, vectorSize, mulVal ); + MathEngine().VectorAdd( input, second, result, vectorSize ); + MathEngine().VectorAddValue( input, result, vectorSize, mulVal ); + MathEngine().VectorMultiply( input, second, vectorSize, mulVal ); + MathEngine().VectorEltwiseMultiply( input, second, result, vectorSize ); + MathEngine().VectorEltwiseMultiplyAdd( input, second, result, vectorSize ); + MathEngine().VectorReLU( input, result, vectorSize, zeroVal ); //Threshold == 0 + MathEngine().VectorReLU( input, result, vectorSize, mulVal ); //Threshold > 0 + MathEngine().VectorHSwish( input, result, vectorSize ); + return 0; } - counters.Synchronise(); - - for( int i = 0; i < testCount; ++i ) { - switch( function ) { - case 0: - MathEngine().VectorCopy( CARRAY_FLOAT_WRAPPER( result ), CARRAY_FLOAT_WRAPPER( input ), vectorSize ); - break; - case 1: - MathEngine().VectorFill( CARRAY_FLOAT_WRAPPER( result ), vectorSize, mulVal ); - break; - case 2: - MathEngine().VectorAdd( CARRAY_FLOAT_WRAPPER( input ), CARRAY_FLOAT_WRAPPER( second ), - CARRAY_FLOAT_WRAPPER( result ), vectorSize ); - break; - case 3: - MathEngine().VectorAddValue( CARRAY_FLOAT_WRAPPER( input ), CARRAY_FLOAT_WRAPPER( result ), - vectorSize, mulVal ); - break; - case 4: - MathEngine().VectorMultiply( CARRAY_FLOAT_WRAPPER( input ), - CARRAY_FLOAT_WRAPPER( second ), vectorSize, mulVal ); - break; - case 5: - MathEngine().VectorEltwiseMultiply( CARRAY_FLOAT_WRAPPER( input ), - CARRAY_FLOAT_WRAPPER( second ), CARRAY_FLOAT_WRAPPER( result ), vectorSize ); - break; - case 6: - MathEngine().VectorEltwiseMultiplyAdd( CARRAY_FLOAT_WRAPPER( input ), - CARRAY_FLOAT_WRAPPER( second ), CARRAY_FLOAT_WRAPPER( result ), vectorSize ); - break; - case 7: - MathEngine().VectorReLU( CARRAY_FLOAT_WRAPPER( input ), CARRAY_FLOAT_WRAPPER( result ), - vectorSize, zeroVal ); //Threshold == 0 - break; - case 8: - MathEngine().VectorReLU( CARRAY_FLOAT_WRAPPER( input ), CARRAY_FLOAT_WRAPPER( result ), - vectorSize, mulVal ); //Threshold > 0 - break; - case 9: - MathEngine().VectorHSwish( CARRAY_FLOAT_WRAPPER( input ), CARRAY_FLOAT_WRAPPER( result ), - vectorSize ); - break; + params.Counters->Synchronise(); + + for( int i = 0; i < params.TestCount; ++i ) { + switch( params.Function ) { + case 0: MathEngine().VectorCopy( result, input, vectorSize ); break; + case 1: MathEngine().VectorFill( result, vectorSize, mulVal ); break; + case 2: MathEngine().VectorAdd( input, second, result, vectorSize ); break; + case 3: MathEngine().VectorAddValue( input, result, vectorSize, mulVal ); break; + case 4: MathEngine().VectorMultiply( input, second, vectorSize, mulVal ); break; + case 5: MathEngine().VectorEltwiseMultiply( input, second, result, vectorSize ); break; + case 6: MathEngine().VectorEltwiseMultiplyAdd( input, second, result, vectorSize ); break; + case 7: MathEngine().VectorReLU( input, result, vectorSize, zeroVal ); break; //Threshold == 0 + case 8: MathEngine().VectorReLU( input, result, vectorSize, mulVal ); break; //Threshold > 0 + case 9: MathEngine().VectorHSwish( input, result, vectorSize ); break; default: ASSERT_EXPR( false ); } } - counters.Synchronise(); - const double time = double( counters[0].Value ) / 1000000 / testCount; // average time in milliseconds - - GTEST_LOG_( INFO ) << vectorFunctionsNames[function] << ", " << time; - fout << vectorFunctionsNames[function] << "," << time << "\n"; + params.Counters->Synchronise(); + const double time = double( ( *params.Counters )[0].Value ) / 1000000 / params.TestCount; // average time in milliseconds + params.FOut << time << ","; + return time; } } // namespace NeoMLTest @@ -129,9 +171,9 @@ INSTANTIATE_TEST_CASE_P( CMathEngineVectorBenchmarkTestInstantiation, CMathEngin "VectorValues = (-10..10);" ), CTestParams( - "TestCount = 100000;" + "TestCount = 1000;" "RepeatCount = 10;" - "VectorSize = 11796480;" + "VectorSize = 1179648;" "VectorValues = (-1..1);" ) ) @@ -139,24 +181,24 @@ INSTANTIATE_TEST_CASE_P( CMathEngineVectorBenchmarkTestInstantiation, CMathEngin TEST_P( CMathEngineVectorBenchmarkTest, DISABLED_Random ) { - CTestParams params = GetParam(); - - const int testCount = params.GetValue( "TestCount" ); - const int repeatCount = params.GetValue( "RepeatCount" ); - const int vectorSize = params.GetValue( "VectorSize" ); - const CInterval vectorValuesInterval = params.GetInterval( "VectorValues" ); + CTestParams testParams = GetParam(); + const int testCount = testParams.GetValue( "TestCount" ); + const int repeatCount = testParams.GetValue( "RepeatCount" ); + const int vectorSize = testParams.GetValue( "VectorSize" ); + const CInterval valuesInterval = testParams.GetInterval( "VectorValues" ); - IPerformanceCounters* counters = MathEngine().CreatePerformanceCounters(); - std::ofstream fout( "VectorBenchmarkTest.csv", std::ios::app ); - fout << "---------------------------\n"; - - vectorBenchmark( /*warm-up*/-1, testCount, vectorSize, vectorValuesInterval, 282, *counters, fout); + VectorBenchmarkParams params( /*warm-up*/-1, testCount, vectorSize, valuesInterval, 282 ); + vectorBenchmark( params ); for( int function = 0; function < 10; ++function ) { + params.FOut << std::endl << vectorFunctionsNames[function] << ","; + + double timeSum = 0; for( int test = 0; test < repeatCount; ++test ) { const int seed = 282 + test * 10000 + test % 3; - vectorBenchmark( function, testCount, vectorSize, vectorValuesInterval, seed, *counters, fout ); + params.SetNextSeedForFunction( function, seed ); + timeSum += vectorBenchmark( params ); } + GTEST_LOG_( INFO ) << vectorFunctionsNames[function] << "\t" << timeSum; } - delete counters; }