From 7115f60b91b5717d90f643fd692010905c7004db Mon Sep 17 00:00:00 2001 From: Bryan Galdrikian Date: Thu, 31 May 2018 11:36:08 -0700 Subject: Blast 1.1.3. See docs/release_notes.txt. --- test/src/perf/BlastBasePerfTest.h | 788 +++++++++++++++++++------------------- test/src/perf/DamagePerfTests.cpp | 572 +++++++++++++-------------- test/src/perf/SolverPerfTests.cpp | 404 +++++++++---------- 3 files changed, 882 insertions(+), 882 deletions(-) mode change 100644 => 100755 test/src/perf/BlastBasePerfTest.h mode change 100644 => 100755 test/src/perf/DamagePerfTests.cpp mode change 100644 => 100755 test/src/perf/SolverPerfTests.cpp (limited to 'test/src/perf') diff --git a/test/src/perf/BlastBasePerfTest.h b/test/src/perf/BlastBasePerfTest.h old mode 100644 new mode 100755 index 55285f1..8eff9ba --- a/test/src/perf/BlastBasePerfTest.h +++ b/test/src/perf/BlastBasePerfTest.h @@ -1,394 +1,394 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef BLASTBASEPERFTEST_H -#define BLASTBASEPERFTEST_H - - -#include "BlastBaseTest.h" -#include - -#include -#include - - -template -class DataCollection -{ -public: - struct Stats - { - double m_mean; - double m_sdev; - double m_min; - double m_max; - - Stats() - { - reset(); - } - - void reset() - { - m_mean = 0.0; - m_sdev = 0.0; - m_min = std::numeric_limits().max(); - m_max = -std::numeric_limits().max(); - } - }; - - struct DataSet - { - std::vector m_data; - Stats m_stats; - - void calculateStats() - { - m_stats.reset(); - if (m_data.size() > 0) - { - if (m_data.size() > 1) // Remove top half of values to eliminate outliers - { - std::sort(m_data.begin(), m_data.end()); - m_data.resize(m_data.size() / 2); - } - for (size_t i = 0; i < m_data.size(); ++i) - { - m_stats.m_mean += m_data[i]; - m_stats.m_min = std::min(m_stats.m_min, (double)m_data[i]); - m_stats.m_max = std::max(m_stats.m_max, (double)m_data[i]); - } - m_stats.m_mean /= m_data.size(); - if (m_data.size() > 1) - { - for (size_t i = 0; i < m_data.size(); ++i) - { - m_stats.m_sdev += pow(m_data[i] - m_stats.m_mean, 2); - } - m_stats.m_sdev = sqrt(m_stats.m_sdev / (m_data.size() - 1)); - } - } - } - }; - - DataSet& getDataSet(const std::string& name) - { - auto entry = m_lookup.find(name); - if (entry != m_lookup.end()) - { - return m_dataSets[entry->second]; - } - m_lookup[name] = m_dataSets.size(); - m_dataSets.push_back(DataSet()); - return m_dataSets.back(); - } - - bool dataSetExists(const std::string& name) const - { - return m_lookup.find(name) != m_lookup.end(); - } - - void calculateStats() - { - for (size_t i = 0; i < m_dataSets.size(); ++i) - { - m_dataSets[i].calculateStats(); - } - } - - void test(DataCollection& calibration, double relativeThreshold = 0.10, double tickThreshold = 100.0) - { - for (auto entry = m_lookup.begin(); entry != m_lookup.end(); ++entry) - { - const std::string& name = entry->first; - DataCollection::DataSet& data = m_dataSets[entry->second]; - data.calculateStats(); - - if (!calibration.dataSetExists(name)) - { - FAIL() << "PerfTest is not calibrated!" << std::endl << "Missing DataSet: " << name << std::endl; - } - const DataCollection::DataSet& cal = calibration.getDataSet(name); - const double calMin = cal.m_stats.m_min; - - if (data.m_stats.m_min > (1.0 + relativeThreshold) * calMin && data.m_stats.m_min - calMin > tickThreshold) - { - std::cout << name << ":" << std::endl; - std::cout << "PERF - : Timing (" << data.m_stats.m_min << ") exceeds recorded min (" << calMin << ") by more than allowed relative threshold (" << relativeThreshold*100 << "%) and absolute threshold (" << tickThreshold << " ticks)." << std::endl; - EXPECT_FALSE(data.m_stats.m_min > (1.0 + relativeThreshold) * calMin && data.m_stats.m_min - calMin > tickThreshold) - << name << ":" << std::endl - << "PERF - : Timing (" << data.m_stats.m_min << ") exceeds recorded min (" << calMin << ") by more than allowed relative threshold (" << relativeThreshold * 100 << "%) and absolute threshold (" << tickThreshold << " ticks)." << std::endl; - } - else - if (data.m_stats.m_min < (1.0 - relativeThreshold) * calMin && data.m_stats.m_min - calMin < -tickThreshold) - { - std::cout << name << ":" << std::endl; - std::cout << "PERF + : Timing (" << data.m_stats.m_min << ") is less than the recorded min (" << calMin << ") by more than the relative threshold (" << relativeThreshold * 100 << "%) and absolute threshold (" << tickThreshold << " ticks)." << std::endl; - } - } - } - - size_t size() const - { - return m_dataSets.size(); - } - - void clear() - { - m_lookup.clear(); - m_dataSets.clear(); - } - - template - friend std::istream& operator >> (std::istream& stream, DataCollection& c); - - template - friend std::ostream& operator << (std::ostream& stream, const DataCollection& c); - -private: - std::map m_lookup; - std::vector< DataSet > m_dataSets; -}; - -template -std::istream& operator >> (std::istream& stream, DataCollection& c) -{ - std::string name; - while (!stream.eof()) - { - std::getline(stream >> std::ws, name); - typename DataCollection::DataSet& dataSet = c.getDataSet(name); - stream >> dataSet.m_stats.m_mean >> dataSet.m_stats.m_sdev >> dataSet.m_stats.m_min >> dataSet.m_stats.m_max >> std::ws; - } - return stream; -} - -template -std::ostream& operator << (std::ostream& stream, const DataCollection& c) -{ - for (auto entry = c.m_lookup.begin(); entry != c.m_lookup.end(); ++entry) - { - const std::string& name = entry->first; - stream << name.c_str() << std::endl; - const typename DataCollection::DataSet& data = c.m_dataSets[entry->second]; - stream << data.m_stats.m_mean << " " << data.m_stats.m_sdev << " " << data.m_stats.m_min << " " << data.m_stats.m_max << std::endl; - } - return stream; -} - - -static const char* getPlatformSuffix() -{ -#if NV_WIN32 - return "win32"; -#elif NV_WIN64 - return "win64"; -#elif NV_XBOXONE - return "xb1"; -#elif NV_PS4 - return "ps4"; -#elif NV_LINUX - #if NV_X64 - return "linux64"; - #else - return "linux32"; - #endif -#else - return "gen"; -#endif -} - -static const char* getPlatformRoot() -{ -#if NV_PS4 - return "/app0/"; -#elif NV_XBOXONE - return "G:/"; -#elif NV_LINUX - return "../../"; -#else - return "../../../"; -#endif -} - -static std::string defaultRelativeDataPath() -{ - const char* dataDir = "test/data/"; - - std::string rootDir = getPlatformRoot(); - return rootDir + dataDir + getPlatformSuffix() + "/"; -} - -class PerfTestEngine -{ -public: - PerfTestEngine(const char* collectionName) : m_calibrate(false) - { - m_filename = defaultRelativeDataPath() + std::string(collectionName) + "_" + getPlatformSuffix() + ".cal"; - - auto argvs = testing::internal::GetArgvs(); - size_t argCount = argvs.size(); - - for (size_t argNum = 0; argNum < argCount; ++argNum) - { - if (argvs[argNum] == "-calibrate") - { - m_calibrate = true; - } - else - if (argvs[argNum] == "-calPath") - { - if (++argNum < argCount) - { - m_filename = argvs[argNum]; - } - } - } - - if (!m_calibrate) - { - std::ifstream in; - in.open(m_filename); - if (in.is_open()) - { - std::string name; - std::getline(in, name); // Eat header - std::getline(in, name); // Eat header (2 lines) - in >> m_dataCalibration; - in.close(); - } - m_calibrate = m_dataCalibration.size() == 0; - } - - if (m_calibrate) - { - std::ofstream out; - out.open(m_filename); - if (out.is_open()) - { - out << "Format: timing name (whole line)" << std::endl << "timing mean s.d. min max" << std::endl; // Header (2 lines) - out.close(); - } - } - - if (m_calibrate) - { - std::cout << "******** Calibration Mode ********\n"; - } - else - { - std::cout << "******** Test Mode ********\n"; - std::cout << "Read calibration data from " << m_filename << std::endl; - } - } - - void endTest() - { - if (m_calibrate) - { - m_dataTempCollection.calculateStats(); - std::ofstream out; - out.open(m_filename, std::ofstream::app); - if (out.is_open()) - { - out << m_dataTempCollection; - out.close(); - std::cout << "Calibration stats written to " << m_filename << std::endl; - } - else - { - std::cout << "Failed to open calibration file " << m_filename << ". Stats not written." << std::endl; - FAIL() << "Failed to open calibration file " << m_filename << ". Stats not written." << std::endl; - } - } - else - { - m_dataTempCollection.test(m_dataCalibration); - } - m_dataTempCollection.clear(); - } - - void reportData(const std::string& name, int64_t data) - { - m_dataTempCollection.getDataSet(name).m_data.push_back(data); - } - -private: - std::string m_filename; - bool m_calibrate; - DataCollection m_dataTempCollection; - DataCollection m_dataCalibration; -}; - - -template -class BlastBasePerfTest : public BlastBaseTest -{ -public: - /** - This function allows to create/destroy and get PerfTestEngine in local static variable (works header only). - It allows to have PeftTestEngine alive through life span of gtest TestCase. - */ - static PerfTestEngine* getEngineDeadOrAlive(bool alive = true) - { - static PerfTestEngine* engine = nullptr; - if (alive && !engine) - { - engine = new PerfTestEngine(::testing::UnitTest::GetInstance()->current_test_case()->name()); - } - else if (!alive && engine) - { - delete engine; - engine = nullptr; - } - return engine; - } - - static void SetUpTestCase() - { - getEngineDeadOrAlive(); - } - - static void TearDownTestCase() - { - getEngineDeadOrAlive(false); - } - - void TearDown() override - { - getEngineDeadOrAlive()->endTest(); - } - - void reportData(const std::string& name, int64_t data) - { - getEngineDeadOrAlive()->reportData(name, data); - } -}; - - -#endif // #ifndef BLASTBASEPERFTEST_H +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. + + +#ifndef BLASTBASEPERFTEST_H +#define BLASTBASEPERFTEST_H + + +#include "BlastBaseTest.h" +#include + +#include +#include + + +template +class DataCollection +{ +public: + struct Stats + { + double m_mean; + double m_sdev; + double m_min; + double m_max; + + Stats() + { + reset(); + } + + void reset() + { + m_mean = 0.0; + m_sdev = 0.0; + m_min = std::numeric_limits().max(); + m_max = -std::numeric_limits().max(); + } + }; + + struct DataSet + { + std::vector m_data; + Stats m_stats; + + void calculateStats() + { + m_stats.reset(); + if (m_data.size() > 0) + { + if (m_data.size() > 1) // Remove top half of values to eliminate outliers + { + std::sort(m_data.begin(), m_data.end()); + m_data.resize(m_data.size() / 2); + } + for (size_t i = 0; i < m_data.size(); ++i) + { + m_stats.m_mean += m_data[i]; + m_stats.m_min = std::min(m_stats.m_min, (double)m_data[i]); + m_stats.m_max = std::max(m_stats.m_max, (double)m_data[i]); + } + m_stats.m_mean /= m_data.size(); + if (m_data.size() > 1) + { + for (size_t i = 0; i < m_data.size(); ++i) + { + m_stats.m_sdev += pow(m_data[i] - m_stats.m_mean, 2); + } + m_stats.m_sdev = sqrt(m_stats.m_sdev / (m_data.size() - 1)); + } + } + } + }; + + DataSet& getDataSet(const std::string& name) + { + auto entry = m_lookup.find(name); + if (entry != m_lookup.end()) + { + return m_dataSets[entry->second]; + } + m_lookup[name] = m_dataSets.size(); + m_dataSets.push_back(DataSet()); + return m_dataSets.back(); + } + + bool dataSetExists(const std::string& name) const + { + return m_lookup.find(name) != m_lookup.end(); + } + + void calculateStats() + { + for (size_t i = 0; i < m_dataSets.size(); ++i) + { + m_dataSets[i].calculateStats(); + } + } + + void test(DataCollection& calibration, double relativeThreshold = 0.10, double tickThreshold = 100.0) + { + for (auto entry = m_lookup.begin(); entry != m_lookup.end(); ++entry) + { + const std::string& name = entry->first; + DataCollection::DataSet& data = m_dataSets[entry->second]; + data.calculateStats(); + + if (!calibration.dataSetExists(name)) + { + FAIL() << "PerfTest is not calibrated!" << std::endl << "Missing DataSet: " << name << std::endl; + } + const DataCollection::DataSet& cal = calibration.getDataSet(name); + const double calMin = cal.m_stats.m_min; + + if (data.m_stats.m_min > (1.0 + relativeThreshold) * calMin && data.m_stats.m_min - calMin > tickThreshold) + { + std::cout << name << ":" << std::endl; + std::cout << "PERF - : Timing (" << data.m_stats.m_min << ") exceeds recorded min (" << calMin << ") by more than allowed relative threshold (" << relativeThreshold*100 << "%) and absolute threshold (" << tickThreshold << " ticks)." << std::endl; + EXPECT_FALSE(data.m_stats.m_min > (1.0 + relativeThreshold) * calMin && data.m_stats.m_min - calMin > tickThreshold) + << name << ":" << std::endl + << "PERF - : Timing (" << data.m_stats.m_min << ") exceeds recorded min (" << calMin << ") by more than allowed relative threshold (" << relativeThreshold * 100 << "%) and absolute threshold (" << tickThreshold << " ticks)." << std::endl; + } + else + if (data.m_stats.m_min < (1.0 - relativeThreshold) * calMin && data.m_stats.m_min - calMin < -tickThreshold) + { + std::cout << name << ":" << std::endl; + std::cout << "PERF + : Timing (" << data.m_stats.m_min << ") is less than the recorded min (" << calMin << ") by more than the relative threshold (" << relativeThreshold * 100 << "%) and absolute threshold (" << tickThreshold << " ticks)." << std::endl; + } + } + } + + size_t size() const + { + return m_dataSets.size(); + } + + void clear() + { + m_lookup.clear(); + m_dataSets.clear(); + } + + template + friend std::istream& operator >> (std::istream& stream, DataCollection& c); + + template + friend std::ostream& operator << (std::ostream& stream, const DataCollection& c); + +private: + std::map m_lookup; + std::vector< DataSet > m_dataSets; +}; + +template +std::istream& operator >> (std::istream& stream, DataCollection& c) +{ + std::string name; + while (!stream.eof()) + { + std::getline(stream >> std::ws, name); + typename DataCollection::DataSet& dataSet = c.getDataSet(name); + stream >> dataSet.m_stats.m_mean >> dataSet.m_stats.m_sdev >> dataSet.m_stats.m_min >> dataSet.m_stats.m_max >> std::ws; + } + return stream; +} + +template +std::ostream& operator << (std::ostream& stream, const DataCollection& c) +{ + for (auto entry = c.m_lookup.begin(); entry != c.m_lookup.end(); ++entry) + { + const std::string& name = entry->first; + stream << name.c_str() << std::endl; + const typename DataCollection::DataSet& data = c.m_dataSets[entry->second]; + stream << data.m_stats.m_mean << " " << data.m_stats.m_sdev << " " << data.m_stats.m_min << " " << data.m_stats.m_max << std::endl; + } + return stream; +} + + +static const char* getPlatformSuffix() +{ +#if NV_WIN32 + return "win32"; +#elif NV_WIN64 + return "win64"; +#elif NV_XBOXONE + return "xb1"; +#elif NV_PS4 + return "ps4"; +#elif NV_LINUX + #if NV_X64 + return "linux64"; + #else + return "linux32"; + #endif +#else + return "gen"; +#endif +} + +static const char* getPlatformRoot() +{ +#if NV_PS4 + return "/app0/"; +#elif NV_XBOXONE + return "G:/"; +#elif NV_LINUX + return "../../"; +#else + return "../../../"; +#endif +} + +static std::string defaultRelativeDataPath() +{ + const char* dataDir = "test/data/"; + + std::string rootDir = getPlatformRoot(); + return rootDir + dataDir + getPlatformSuffix() + "/"; +} + +class PerfTestEngine +{ +public: + PerfTestEngine(const char* collectionName) : m_calibrate(false) + { + m_filename = defaultRelativeDataPath() + std::string(collectionName) + "_" + getPlatformSuffix() + ".cal"; + + auto argvs = testing::internal::GetArgvs(); + size_t argCount = argvs.size(); + + for (size_t argNum = 0; argNum < argCount; ++argNum) + { + if (argvs[argNum] == "-calibrate") + { + m_calibrate = true; + } + else + if (argvs[argNum] == "-calPath") + { + if (++argNum < argCount) + { + m_filename = argvs[argNum]; + } + } + } + + if (!m_calibrate) + { + std::ifstream in; + in.open(m_filename); + if (in.is_open()) + { + std::string name; + std::getline(in, name); // Eat header + std::getline(in, name); // Eat header (2 lines) + in >> m_dataCalibration; + in.close(); + } + m_calibrate = m_dataCalibration.size() == 0; + } + + if (m_calibrate) + { + std::ofstream out; + out.open(m_filename); + if (out.is_open()) + { + out << "Format: timing name (whole line)" << std::endl << "timing mean s.d. min max" << std::endl; // Header (2 lines) + out.close(); + } + } + + if (m_calibrate) + { + std::cout << "******** Calibration Mode ********\n"; + } + else + { + std::cout << "******** Test Mode ********\n"; + std::cout << "Read calibration data from " << m_filename << std::endl; + } + } + + void endTest() + { + if (m_calibrate) + { + m_dataTempCollection.calculateStats(); + std::ofstream out; + out.open(m_filename, std::ofstream::app); + if (out.is_open()) + { + out << m_dataTempCollection; + out.close(); + std::cout << "Calibration stats written to " << m_filename << std::endl; + } + else + { + std::cout << "Failed to open calibration file " << m_filename << ". Stats not written." << std::endl; + FAIL() << "Failed to open calibration file " << m_filename << ". Stats not written." << std::endl; + } + } + else + { + m_dataTempCollection.test(m_dataCalibration); + } + m_dataTempCollection.clear(); + } + + void reportData(const std::string& name, int64_t data) + { + m_dataTempCollection.getDataSet(name).m_data.push_back(data); + } + +private: + std::string m_filename; + bool m_calibrate; + DataCollection m_dataTempCollection; + DataCollection m_dataCalibration; +}; + + +template +class BlastBasePerfTest : public BlastBaseTest +{ +public: + /** + This function allows to create/destroy and get PerfTestEngine in local static variable (works header only). + It allows to have PeftTestEngine alive through life span of gtest TestCase. + */ + static PerfTestEngine* getEngineDeadOrAlive(bool alive = true) + { + static PerfTestEngine* engine = nullptr; + if (alive && !engine) + { + engine = new PerfTestEngine(::testing::UnitTest::GetInstance()->current_test_case()->name()); + } + else if (!alive && engine) + { + delete engine; + engine = nullptr; + } + return engine; + } + + static void SetUpTestCase() + { + getEngineDeadOrAlive(); + } + + static void TearDownTestCase() + { + getEngineDeadOrAlive(false); + } + + void TearDown() override + { + getEngineDeadOrAlive()->endTest(); + } + + void reportData(const std::string& name, int64_t data) + { + getEngineDeadOrAlive()->reportData(name, data); + } +}; + + +#endif // #ifndef BLASTBASEPERFTEST_H diff --git a/test/src/perf/DamagePerfTests.cpp b/test/src/perf/DamagePerfTests.cpp old mode 100644 new mode 100755 index 86707ec..9c7ab0e --- a/test/src/perf/DamagePerfTests.cpp +++ b/test/src/perf/DamagePerfTests.cpp @@ -1,286 +1,286 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "BlastBasePerfTest.h" -#include "NvBlastExtDamageShaders.h" -#include "NvBlastExtSerialization.h" -#include "NvBlastTime.h" -#include "PxVec3.h" -#include "PxBounds3.h" -#include -#include -#include - -using namespace Nv::Blast; -using namespace physx; - -static void blast -( - std::set& actorsToDamage, - GeneratorAsset* testAsset, - NvBlastExtDamageAccelerator* accelerator, - GeneratorAsset::Vec3 localPos, - float minRadius, float maxRadius, - float compressiveDamage, - std::vector& history, - NvBlastTimers& timers) -{ - std::vector chunkEvents; /* num lower-support chunks + bonds */ - std::vector bondEvents; /* num lower-support chunks + bonds */ - chunkEvents.resize(testAsset->solverChunks.size()); - bondEvents.resize(testAsset->solverBonds.size()); - - NvBlastExtRadialDamageDesc damage = { - compressiveDamage, - { localPos.x, localPos.y, localPos.z }, - minRadius, - maxRadius - }; - - NvBlastExtMaterial material; - - NvBlastExtProgramParams programParams = - { - &damage, - &material, - accelerator - }; - - NvBlastDamageProgram program = { - NvBlastExtFalloffGraphShader, - nullptr - }; - - std::vector splitScratch; - std::vector newActors(testAsset->solverChunks.size()); - - size_t totalNewActorsCount = 0; - for (std::set::iterator k = actorsToDamage.begin(); k != actorsToDamage.end();) - { - NvBlastActor* actor = *k; - - NvBlastFractureBuffers events = { (uint32_t)bondEvents.size(), (uint32_t)chunkEvents.size(), bondEvents.data(), chunkEvents.data() }; - - NvBlastActorGenerateFracture(&events, actor, program, &programParams, nullptr, &timers); - NvBlastActorApplyFracture(nullptr, actor, &events, nullptr, &timers); - - bool removeActor = false; - - if (events.bondFractureCount + events.chunkFractureCount > 0) - { - history.push_back(events.bondFractureCount + events.chunkFractureCount); - - splitScratch.resize((size_t)NvBlastActorGetRequiredScratchForSplit(actor, nullptr)); - NvBlastActorSplitEvent result; - result.deletedActor = nullptr; - result.newActors = &newActors[totalNewActorsCount]; - const size_t bufferSize = newActors.size() - totalNewActorsCount; - const size_t newActorsCount = NvBlastActorSplit(&result, actor, (uint32_t)bufferSize, splitScratch.data(), nullptr, &timers); - totalNewActorsCount += newActorsCount; - removeActor = newActorsCount > 0; - } - - if (removeActor) - { - k = actorsToDamage.erase(k); - } - else - { - ++k; - } - } - - for (size_t i = 0; i < totalNewActorsCount; ++i) - { - actorsToDamage.insert(newActors[i]); - } -} - -typedef BlastBasePerfTest BlastBasePerfTestStrict; - - -struct PerfResults -{ - int64_t totalTime; - int64_t createTime; -}; - -class PerfTest : public BlastBasePerfTestStrict -{ -public: - - NvBlastAsset* loadAsset(const char* path, ExtSerialization* ser) - { - std::ifstream infileStream(path, std::ios::binary); - if (!infileStream.is_open()) - { - return nullptr; - } - const std::vector inBuffer((std::istreambuf_iterator(infileStream)), std::istreambuf_iterator()); - infileStream.close(); - - NvBlastAsset* asset = static_cast(ser->deserializeFromBuffer(inBuffer.data(), inBuffer.size())); - - return asset; - } - - PerfResults damageLeafSupportActors(const char* testName, uint32_t assetCount, uint32_t familyCount, uint32_t damageCount, int accelType, std::vector& history) - { - PerfResults results; - results.totalTime = 0; - results.createTime = 0; - - const float compressiveDamage = 1.0f; - const uint32_t minChunkCount = 1000; - const uint32_t maxChunkCount = 100000; - - srand(0); - - for (uint32_t assetNum = 0; assetNum < assetCount; ++assetNum) - { - GeneratorAsset cube; - NvBlastAssetDesc desc; - generateRandomCube(cube, desc, minChunkCount, maxChunkCount); - - { - std::vector scratch; - physx::PxBounds3 bounds = physx::PxBounds3::empty(); -#if 1 - scratch.resize((size_t)NvBlastGetRequiredScratchForCreateAsset(&desc, messageLog)); - void* mem = alignedZeroedAlloc(NvBlastGetAssetMemorySize(&desc, messageLog)); - NvBlastAsset* asset = NvBlastCreateAsset(mem, &desc, scratch.data(), messageLog); - EXPECT_TRUE(asset != nullptr); - bounds = physx::PxBounds3::centerExtents(physx::PxVec3(0, 0, 0), physx::PxVec3(cube.extents.x, cube.extents.y, cube.extents.z)); -#else - // load asset - NvBlastAsset* asset = nullptr; - ExtSerialization* ser = NvBlastExtSerializationCreate(); - for (int s = 0; s < 5 && !asset; s++) - { - asset = loadAsset(&"../../../../../test/assets/table.blast"[s * 3], ser); - } - EXPECT_TRUE(asset != nullptr); - ser->release(); - uint32_t bc = NvBlastAssetGetBondCount(asset, messageLog); - const NvBlastBond* bonds = NvBlastAssetGetBonds(asset, messageLog); - for (uint32_t i = 0; i < bc; i++) - { - bounds.include(reinterpret_cast(bonds[i].centroid)); - } -#endif - - Nv::Blast::Time t; - NvBlastExtDamageAccelerator* accelerator = NvBlastExtDamageAcceleratorCreate(asset, accelType); - results.createTime += t.getElapsedTicks(); - - // Generate familes - for (uint32_t familyNum = 0; familyNum < familyCount; ++familyNum) - { - // create actor - NvBlastActorDesc actorDesc; - actorDesc.initialBondHealths = nullptr; - actorDesc.uniformInitialBondHealth = 1.0f; - actorDesc.initialSupportChunkHealths = nullptr; - actorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; - void* mem = alignedZeroedAlloc(NvBlastAssetGetFamilyMemorySize(asset, messageLog)); - NvBlastFamily* family = NvBlastAssetCreateFamily(mem, asset, messageLog); - scratch.resize((size_t)NvBlastFamilyGetRequiredScratchForCreateFirstActor(family, messageLog)); - EXPECT_TRUE(family != nullptr); - NvBlastActor* actor = NvBlastFamilyCreateFirstActor(family, &actorDesc, scratch.data(), messageLog); - EXPECT_TRUE(actor != nullptr); - - // Generate damage - std::set actors; - actors.insert(actor); - for (uint32_t damageNum = 0; damageNum < damageCount; ++damageNum) - { - GeneratorAsset::Vec3 localPos = GeneratorAsset::Vec3((float)rand() / RAND_MAX - 0.5f, (float)rand() / RAND_MAX - 0.5f, (float)rand() / RAND_MAX - 0.5f) * 2; - localPos.x *= bounds.getExtents().x; - localPos.y *= bounds.getExtents().y; - localPos.z *= bounds.getExtents().z; - const float relativeDamageRadius = (float)rand() / RAND_MAX * bounds.getExtents().maxElement(); - - NvBlastTimers timers; - NvBlastTimersReset(&timers); - blast(actors, &cube, accelerator, localPos, relativeDamageRadius, relativeDamageRadius*1.2f, compressiveDamage, history, timers); - const std::string timingName = std::string(testName) + " asset " + std::to_string(assetNum) + " family " + std::to_string(familyNum) + " damage " + std::to_string(damageNum) + " accel " + std::to_string(accelType); - BlastBasePerfTestStrict::reportData(timingName + " material", timers.material); - history.push_back((uint32_t)actors.size()); - results.totalTime += timers.material; - history.push_back(0); // separator - } - - // Release remaining actors - std::for_each(actors.begin(), actors.end(), [](NvBlastActor* a) { NvBlastActorDeactivate(a, messageLog); }); - actors.clear(); - - alignedFree(family); - } - - if (accelerator) - accelerator->release(); - - // Release asset data - alignedFree(asset); - } - } - - return results; - } -}; - - -// Tests -TEST_F(PerfTest, DISABLED_DamageRadialSimple) -{ - const int trialCount = 10; - std::cout << "Trial (of " << trialCount << "): "; - for (int trial = 1; trial <= trialCount; ++trial) - { - if (trial % 100 == 0) - { - std::cout << trial << ".. "; - std::cout.flush(); - } - std::vector history1, history2; - - uint32_t assetCount = 4; - uint32_t familyCount = 4; - uint32_t damageCount = 4; - - PerfResults results0 = damageLeafSupportActors(test_info_->name(), assetCount, familyCount, damageCount, 0, history1); - BlastBasePerfTestStrict::reportData("DamageRadialSimple total0 " , results0.totalTime); - BlastBasePerfTestStrict::reportData("DamageRadialSimple create0 ", results0.createTime); - PerfResults results1 = damageLeafSupportActors(test_info_->name(), assetCount, familyCount, damageCount, 1, history2); - BlastBasePerfTestStrict::reportData("DamageRadialSimple total1 ", results1.totalTime); - BlastBasePerfTestStrict::reportData("DamageRadialSimple create1 ", results1.createTime); - - EXPECT_TRUE(history1 == history2); - } - std::cout << "done." << std::endl; -} +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. + + +#include "BlastBasePerfTest.h" +#include "NvBlastExtDamageShaders.h" +#include "NvBlastExtSerialization.h" +#include "NvBlastTime.h" +#include "PxVec3.h" +#include "PxBounds3.h" +#include +#include +#include + +using namespace Nv::Blast; +using namespace physx; + +static void blast +( + std::set& actorsToDamage, + GeneratorAsset* testAsset, + NvBlastExtDamageAccelerator* accelerator, + GeneratorAsset::Vec3 localPos, + float minRadius, float maxRadius, + float compressiveDamage, + std::vector& history, + NvBlastTimers& timers) +{ + std::vector chunkEvents; /* num lower-support chunks + bonds */ + std::vector bondEvents; /* num lower-support chunks + bonds */ + chunkEvents.resize(testAsset->solverChunks.size()); + bondEvents.resize(testAsset->solverBonds.size()); + + NvBlastExtRadialDamageDesc damage = { + compressiveDamage, + { localPos.x, localPos.y, localPos.z }, + minRadius, + maxRadius + }; + + NvBlastExtMaterial material; + + NvBlastExtProgramParams programParams = + { + &damage, + &material, + accelerator + }; + + NvBlastDamageProgram program = { + NvBlastExtFalloffGraphShader, + nullptr + }; + + std::vector splitScratch; + std::vector newActors(testAsset->solverChunks.size()); + + size_t totalNewActorsCount = 0; + for (std::set::iterator k = actorsToDamage.begin(); k != actorsToDamage.end();) + { + NvBlastActor* actor = *k; + + NvBlastFractureBuffers events = { (uint32_t)bondEvents.size(), (uint32_t)chunkEvents.size(), bondEvents.data(), chunkEvents.data() }; + + NvBlastActorGenerateFracture(&events, actor, program, &programParams, nullptr, &timers); + NvBlastActorApplyFracture(nullptr, actor, &events, nullptr, &timers); + + bool removeActor = false; + + if (events.bondFractureCount + events.chunkFractureCount > 0) + { + history.push_back(events.bondFractureCount + events.chunkFractureCount); + + splitScratch.resize((size_t)NvBlastActorGetRequiredScratchForSplit(actor, nullptr)); + NvBlastActorSplitEvent result; + result.deletedActor = nullptr; + result.newActors = &newActors[totalNewActorsCount]; + const size_t bufferSize = newActors.size() - totalNewActorsCount; + const size_t newActorsCount = NvBlastActorSplit(&result, actor, (uint32_t)bufferSize, splitScratch.data(), nullptr, &timers); + totalNewActorsCount += newActorsCount; + removeActor = newActorsCount > 0; + } + + if (removeActor) + { + k = actorsToDamage.erase(k); + } + else + { + ++k; + } + } + + for (size_t i = 0; i < totalNewActorsCount; ++i) + { + actorsToDamage.insert(newActors[i]); + } +} + +typedef BlastBasePerfTest BlastBasePerfTestStrict; + + +struct PerfResults +{ + int64_t totalTime; + int64_t createTime; +}; + +class PerfTest : public BlastBasePerfTestStrict +{ +public: + + NvBlastAsset* loadAsset(const char* path, ExtSerialization* ser) + { + std::ifstream infileStream(path, std::ios::binary); + if (!infileStream.is_open()) + { + return nullptr; + } + const std::vector inBuffer((std::istreambuf_iterator(infileStream)), std::istreambuf_iterator()); + infileStream.close(); + + NvBlastAsset* asset = static_cast(ser->deserializeFromBuffer(inBuffer.data(), inBuffer.size())); + + return asset; + } + + PerfResults damageLeafSupportActors(const char* testName, uint32_t assetCount, uint32_t familyCount, uint32_t damageCount, int accelType, std::vector& history) + { + PerfResults results; + results.totalTime = 0; + results.createTime = 0; + + const float compressiveDamage = 1.0f; + const uint32_t minChunkCount = 1000; + const uint32_t maxChunkCount = 100000; + + srand(0); + + for (uint32_t assetNum = 0; assetNum < assetCount; ++assetNum) + { + GeneratorAsset cube; + NvBlastAssetDesc desc; + generateRandomCube(cube, desc, minChunkCount, maxChunkCount); + + { + std::vector scratch; + physx::PxBounds3 bounds = physx::PxBounds3::empty(); +#if 1 + scratch.resize((size_t)NvBlastGetRequiredScratchForCreateAsset(&desc, messageLog)); + void* mem = alignedZeroedAlloc(NvBlastGetAssetMemorySize(&desc, messageLog)); + NvBlastAsset* asset = NvBlastCreateAsset(mem, &desc, scratch.data(), messageLog); + EXPECT_TRUE(asset != nullptr); + bounds = physx::PxBounds3::centerExtents(physx::PxVec3(0, 0, 0), physx::PxVec3(cube.extents.x, cube.extents.y, cube.extents.z)); +#else + // load asset + NvBlastAsset* asset = nullptr; + ExtSerialization* ser = NvBlastExtSerializationCreate(); + for (int s = 0; s < 5 && !asset; s++) + { + asset = loadAsset(&"../../../../../test/assets/table.blast"[s * 3], ser); + } + EXPECT_TRUE(asset != nullptr); + ser->release(); + uint32_t bc = NvBlastAssetGetBondCount(asset, messageLog); + const NvBlastBond* bonds = NvBlastAssetGetBonds(asset, messageLog); + for (uint32_t i = 0; i < bc; i++) + { + bounds.include(reinterpret_cast(bonds[i].centroid)); + } +#endif + + Nv::Blast::Time t; + NvBlastExtDamageAccelerator* accelerator = NvBlastExtDamageAcceleratorCreate(asset, accelType); + results.createTime += t.getElapsedTicks(); + + // Generate familes + for (uint32_t familyNum = 0; familyNum < familyCount; ++familyNum) + { + // create actor + NvBlastActorDesc actorDesc; + actorDesc.initialBondHealths = nullptr; + actorDesc.uniformInitialBondHealth = 1.0f; + actorDesc.initialSupportChunkHealths = nullptr; + actorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; + void* mem = alignedZeroedAlloc(NvBlastAssetGetFamilyMemorySize(asset, messageLog)); + NvBlastFamily* family = NvBlastAssetCreateFamily(mem, asset, messageLog); + scratch.resize((size_t)NvBlastFamilyGetRequiredScratchForCreateFirstActor(family, messageLog)); + EXPECT_TRUE(family != nullptr); + NvBlastActor* actor = NvBlastFamilyCreateFirstActor(family, &actorDesc, scratch.data(), messageLog); + EXPECT_TRUE(actor != nullptr); + + // Generate damage + std::set actors; + actors.insert(actor); + for (uint32_t damageNum = 0; damageNum < damageCount; ++damageNum) + { + GeneratorAsset::Vec3 localPos = GeneratorAsset::Vec3((float)rand() / RAND_MAX - 0.5f, (float)rand() / RAND_MAX - 0.5f, (float)rand() / RAND_MAX - 0.5f) * 2; + localPos.x *= bounds.getExtents().x; + localPos.y *= bounds.getExtents().y; + localPos.z *= bounds.getExtents().z; + const float relativeDamageRadius = (float)rand() / RAND_MAX * bounds.getExtents().maxElement(); + + NvBlastTimers timers; + NvBlastTimersReset(&timers); + blast(actors, &cube, accelerator, localPos, relativeDamageRadius, relativeDamageRadius*1.2f, compressiveDamage, history, timers); + const std::string timingName = std::string(testName) + " asset " + std::to_string(assetNum) + " family " + std::to_string(familyNum) + " damage " + std::to_string(damageNum) + " accel " + std::to_string(accelType); + BlastBasePerfTestStrict::reportData(timingName + " material", timers.material); + history.push_back((uint32_t)actors.size()); + results.totalTime += timers.material; + history.push_back(0); // separator + } + + // Release remaining actors + std::for_each(actors.begin(), actors.end(), [](NvBlastActor* a) { NvBlastActorDeactivate(a, messageLog); }); + actors.clear(); + + alignedFree(family); + } + + if (accelerator) + accelerator->release(); + + // Release asset data + alignedFree(asset); + } + } + + return results; + } +}; + + +// Tests +TEST_F(PerfTest, DISABLED_DamageRadialSimple) +{ + const int trialCount = 10; + std::cout << "Trial (of " << trialCount << "): "; + for (int trial = 1; trial <= trialCount; ++trial) + { + if (trial % 100 == 0) + { + std::cout << trial << ".. "; + std::cout.flush(); + } + std::vector history1, history2; + + uint32_t assetCount = 4; + uint32_t familyCount = 4; + uint32_t damageCount = 4; + + PerfResults results0 = damageLeafSupportActors(test_info_->name(), assetCount, familyCount, damageCount, 0, history1); + BlastBasePerfTestStrict::reportData("DamageRadialSimple total0 " , results0.totalTime); + BlastBasePerfTestStrict::reportData("DamageRadialSimple create0 ", results0.createTime); + PerfResults results1 = damageLeafSupportActors(test_info_->name(), assetCount, familyCount, damageCount, 1, history2); + BlastBasePerfTestStrict::reportData("DamageRadialSimple total1 ", results1.totalTime); + BlastBasePerfTestStrict::reportData("DamageRadialSimple create1 ", results1.createTime); + + EXPECT_TRUE(history1 == history2); + } + std::cout << "done." << std::endl; +} diff --git a/test/src/perf/SolverPerfTests.cpp b/test/src/perf/SolverPerfTests.cpp old mode 100644 new mode 100755 index cad7928..ac04432 --- a/test/src/perf/SolverPerfTests.cpp +++ b/test/src/perf/SolverPerfTests.cpp @@ -1,203 +1,203 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "BlastBasePerfTest.h" -#include "TestAssets.h" -#include "NvBlastExtDamageShaders.h" -#include - - -static void blast -( - std::set& actorsToDamage, - GeneratorAsset* testAsset, - GeneratorAsset::Vec3 localPos, - float minRadius, float maxRadius, - float compressiveDamage, - NvBlastTimers& timers -) -{ - std::vector chunkEvents; /* num lower-support chunks + bonds */ - std::vector bondEvents; /* num lower-support chunks + bonds */ - chunkEvents.resize(testAsset->solverChunks.size()); - bondEvents.resize(testAsset->solverBonds.size()); - - NvBlastExtRadialDamageDesc damage[] = { - compressiveDamage, - { localPos.x, localPos.y, localPos.z }, - minRadius, - maxRadius - }; - - NvBlastExtProgramParams programParams = - { - damage, - nullptr - }; - - NvBlastDamageProgram program = { - NvBlastExtFalloffGraphShader, - nullptr - }; - - std::vector splitScratch; - std::vector newActors(testAsset->solverChunks.size()); - - size_t totalNewActorsCount = 0; - for (std::set::iterator k = actorsToDamage.begin(); k != actorsToDamage.end();) - { - NvBlastActor* actor = *k; - - NvBlastFractureBuffers events = { (uint32_t)bondEvents.size(), (uint32_t)chunkEvents.size(), bondEvents.data(), chunkEvents.data() }; - - NvBlastActorGenerateFracture(&events, actor, program, &programParams, nullptr, &timers); - NvBlastActorApplyFracture(&events, actor, &events, nullptr, &timers); - - bool removeActor = false; - - if (events.bondFractureCount + events.chunkFractureCount > 0) - { - splitScratch.resize((size_t)NvBlastActorGetRequiredScratchForSplit(actor, nullptr)); - NvBlastActorSplitEvent result; - result.deletedActor = nullptr; - result.newActors = &newActors[totalNewActorsCount]; - const size_t bufferSize = newActors.size() - totalNewActorsCount; - const size_t newActorsCount = NvBlastActorSplit(&result, actor, (uint32_t)bufferSize, splitScratch.data(), nullptr, &timers); - totalNewActorsCount += newActorsCount; - removeActor = newActorsCount > 0; - } - - if (removeActor) - { - k = actorsToDamage.erase(k); - } - else - { - ++k; - } - } - - for (size_t i = 0; i < totalNewActorsCount; ++i) - { - actorsToDamage.insert(newActors[i]); - } -} - -typedef BlastBasePerfTest BlastBasePerfTestStrict; - -class PerfTest : public BlastBasePerfTestStrict -{ -public: - void damageLeafSupportActors(const char* testName, uint32_t assetCount, uint32_t familyCount, uint32_t damageCount) - { - const float relativeDamageRadius = 0.2f; - const float compressiveDamage = 1.0f; - const uint32_t minChunkCount = 100; - const uint32_t maxChunkCount = 10000; - - srand(0); - - for (uint32_t assetNum = 0; assetNum < assetCount; ++assetNum) - { - GeneratorAsset cube; - NvBlastAssetDesc desc; - generateRandomCube(cube, desc, minChunkCount, maxChunkCount); - - { - std::vector scratch; - scratch.resize((size_t)NvBlastGetRequiredScratchForCreateAsset(&desc, messageLog)); - void* mem = alignedZeroedAlloc(NvBlastGetAssetMemorySize(&desc, messageLog)); - NvBlastAsset* asset = NvBlastCreateAsset(mem, &desc, scratch.data(), messageLog); - EXPECT_TRUE(asset != nullptr); - - // Generate familes - for (uint32_t familyNum = 0; familyNum < familyCount; ++familyNum) - { - // create actor - NvBlastActorDesc actorDesc; - actorDesc.initialBondHealths = nullptr; - actorDesc.uniformInitialBondHealth = 1.0f; - actorDesc.initialSupportChunkHealths = nullptr; - actorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; - void* mem = alignedZeroedAlloc(NvBlastAssetGetFamilyMemorySize(asset, messageLog)); - NvBlastFamily* family = NvBlastAssetCreateFamily(mem, asset, messageLog); - scratch.resize((size_t)NvBlastFamilyGetRequiredScratchForCreateFirstActor(family, messageLog)); - EXPECT_TRUE(family != nullptr); - NvBlastActor* actor = NvBlastFamilyCreateFirstActor(family, &actorDesc, scratch.data(), messageLog); - EXPECT_TRUE(actor != nullptr); - - // Generate damage - std::set actors; - actors.insert(actor); - for (uint32_t damageNum = 0; damageNum < damageCount; ++damageNum) - { - GeneratorAsset::Vec3 localPos = cube.extents*GeneratorAsset::Vec3((float)rand() / RAND_MAX - 0.5f, (float)rand() / RAND_MAX - 0.5f, (float)rand() / RAND_MAX - 0.5f); - - NvBlastTimers timers; - NvBlastTimersReset(&timers); - blast(actors, &cube, localPos, relativeDamageRadius, relativeDamageRadius*1.2f, compressiveDamage, timers); - const std::string timingName = std::string(testName) + " asset " + std::to_string(assetNum) + " family " + std::to_string(familyNum) + " damage " + std::to_string(damageNum); - BlastBasePerfTestStrict::reportData(timingName + " material", timers.material); - BlastBasePerfTestStrict::reportData(timingName + " fracture", timers.fracture); - BlastBasePerfTestStrict::reportData(timingName + " island", timers.island); - BlastBasePerfTestStrict::reportData(timingName + " partition", timers.partition); - BlastBasePerfTestStrict::reportData(timingName + " visibility", timers.visibility); - } - - // Release remaining actors - std::for_each(actors.begin(), actors.end(), [](NvBlastActor* a){ NvBlastActorDeactivate(a, messageLog); }); - actors.clear(); - - alignedFree(family); - } - - // Release asset data - alignedFree(asset); - } - } - } -}; - -#if 0 -// Tests -TEST_F(PerfTest, DamageLeafSupportActorsTestVisibility) -{ - const int trialCount = 1000; - std::cout << "Trial (of " << trialCount << "): "; - for (int trial = 1; trial <= trialCount; ++trial) - { - if (trial % 100 == 0) - { - std::cout << trial << ".. "; - std::cout.flush(); - } - damageLeafSupportActors(test_info_->name(), 4, 4, 5); - } - std::cout << "done." << std::endl; -} +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. + + +#include "BlastBasePerfTest.h" +#include "TestAssets.h" +#include "NvBlastExtDamageShaders.h" +#include + + +static void blast +( + std::set& actorsToDamage, + GeneratorAsset* testAsset, + GeneratorAsset::Vec3 localPos, + float minRadius, float maxRadius, + float compressiveDamage, + NvBlastTimers& timers +) +{ + std::vector chunkEvents; /* num lower-support chunks + bonds */ + std::vector bondEvents; /* num lower-support chunks + bonds */ + chunkEvents.resize(testAsset->solverChunks.size()); + bondEvents.resize(testAsset->solverBonds.size()); + + NvBlastExtRadialDamageDesc damage[] = { + compressiveDamage, + { localPos.x, localPos.y, localPos.z }, + minRadius, + maxRadius + }; + + NvBlastExtProgramParams programParams = + { + damage, + nullptr + }; + + NvBlastDamageProgram program = { + NvBlastExtFalloffGraphShader, + nullptr + }; + + std::vector splitScratch; + std::vector newActors(testAsset->solverChunks.size()); + + size_t totalNewActorsCount = 0; + for (std::set::iterator k = actorsToDamage.begin(); k != actorsToDamage.end();) + { + NvBlastActor* actor = *k; + + NvBlastFractureBuffers events = { (uint32_t)bondEvents.size(), (uint32_t)chunkEvents.size(), bondEvents.data(), chunkEvents.data() }; + + NvBlastActorGenerateFracture(&events, actor, program, &programParams, nullptr, &timers); + NvBlastActorApplyFracture(&events, actor, &events, nullptr, &timers); + + bool removeActor = false; + + if (events.bondFractureCount + events.chunkFractureCount > 0) + { + splitScratch.resize((size_t)NvBlastActorGetRequiredScratchForSplit(actor, nullptr)); + NvBlastActorSplitEvent result; + result.deletedActor = nullptr; + result.newActors = &newActors[totalNewActorsCount]; + const size_t bufferSize = newActors.size() - totalNewActorsCount; + const size_t newActorsCount = NvBlastActorSplit(&result, actor, (uint32_t)bufferSize, splitScratch.data(), nullptr, &timers); + totalNewActorsCount += newActorsCount; + removeActor = newActorsCount > 0; + } + + if (removeActor) + { + k = actorsToDamage.erase(k); + } + else + { + ++k; + } + } + + for (size_t i = 0; i < totalNewActorsCount; ++i) + { + actorsToDamage.insert(newActors[i]); + } +} + +typedef BlastBasePerfTest BlastBasePerfTestStrict; + +class PerfTest : public BlastBasePerfTestStrict +{ +public: + void damageLeafSupportActors(const char* testName, uint32_t assetCount, uint32_t familyCount, uint32_t damageCount) + { + const float relativeDamageRadius = 0.2f; + const float compressiveDamage = 1.0f; + const uint32_t minChunkCount = 100; + const uint32_t maxChunkCount = 10000; + + srand(0); + + for (uint32_t assetNum = 0; assetNum < assetCount; ++assetNum) + { + GeneratorAsset cube; + NvBlastAssetDesc desc; + generateRandomCube(cube, desc, minChunkCount, maxChunkCount); + + { + std::vector scratch; + scratch.resize((size_t)NvBlastGetRequiredScratchForCreateAsset(&desc, messageLog)); + void* mem = alignedZeroedAlloc(NvBlastGetAssetMemorySize(&desc, messageLog)); + NvBlastAsset* asset = NvBlastCreateAsset(mem, &desc, scratch.data(), messageLog); + EXPECT_TRUE(asset != nullptr); + + // Generate familes + for (uint32_t familyNum = 0; familyNum < familyCount; ++familyNum) + { + // create actor + NvBlastActorDesc actorDesc; + actorDesc.initialBondHealths = nullptr; + actorDesc.uniformInitialBondHealth = 1.0f; + actorDesc.initialSupportChunkHealths = nullptr; + actorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; + void* mem = alignedZeroedAlloc(NvBlastAssetGetFamilyMemorySize(asset, messageLog)); + NvBlastFamily* family = NvBlastAssetCreateFamily(mem, asset, messageLog); + scratch.resize((size_t)NvBlastFamilyGetRequiredScratchForCreateFirstActor(family, messageLog)); + EXPECT_TRUE(family != nullptr); + NvBlastActor* actor = NvBlastFamilyCreateFirstActor(family, &actorDesc, scratch.data(), messageLog); + EXPECT_TRUE(actor != nullptr); + + // Generate damage + std::set actors; + actors.insert(actor); + for (uint32_t damageNum = 0; damageNum < damageCount; ++damageNum) + { + GeneratorAsset::Vec3 localPos = cube.extents*GeneratorAsset::Vec3((float)rand() / RAND_MAX - 0.5f, (float)rand() / RAND_MAX - 0.5f, (float)rand() / RAND_MAX - 0.5f); + + NvBlastTimers timers; + NvBlastTimersReset(&timers); + blast(actors, &cube, localPos, relativeDamageRadius, relativeDamageRadius*1.2f, compressiveDamage, timers); + const std::string timingName = std::string(testName) + " asset " + std::to_string(assetNum) + " family " + std::to_string(familyNum) + " damage " + std::to_string(damageNum); + BlastBasePerfTestStrict::reportData(timingName + " material", timers.material); + BlastBasePerfTestStrict::reportData(timingName + " fracture", timers.fracture); + BlastBasePerfTestStrict::reportData(timingName + " island", timers.island); + BlastBasePerfTestStrict::reportData(timingName + " partition", timers.partition); + BlastBasePerfTestStrict::reportData(timingName + " visibility", timers.visibility); + } + + // Release remaining actors + std::for_each(actors.begin(), actors.end(), [](NvBlastActor* a){ NvBlastActorDeactivate(a, messageLog); }); + actors.clear(); + + alignedFree(family); + } + + // Release asset data + alignedFree(asset); + } + } + } +}; + +#if 0 +// Tests +TEST_F(PerfTest, DamageLeafSupportActorsTestVisibility) +{ + const int trialCount = 1000; + std::cout << "Trial (of " << trialCount << "): "; + for (int trial = 1; trial <= trialCount; ++trial) + { + if (trial % 100 == 0) + { + std::cout << trial << ".. "; + std::cout.flush(); + } + damageLeafSupportActors(test_info_->name(), 4, 4, 5); + } + std::cout << "done." << std::endl; +} #endif \ No newline at end of file -- cgit v1.2.3