diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-02-04 15:19:48 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-04 15:19:48 -0500 |
| commit | 17c6c6044965629a3ae7e8ef004cc0b2ca657c55 (patch) | |
| tree | 5b78004808354b32d09ba13c0ec4e32a44f345ab /tools/slang-test/slang-test-main.cpp | |
| parent | b415760d7f166eaad7fa27daa09edc9a8964c37e (diff) | |
CUDA/C++ backend improvements (#1198)
* WIP with vector float test.
* vector-float test working.
* Fixed remaing tests broken with init changes.
* Improve 64bit-type-support.md
* Disable tests broken on CI system for Dx.
* WIP: Make type available for comparison.
* Moved type conversion into TypeTextUtil.
* Add text/type conversions from DownstreamCompiler to TypeTextUtil.
* Allow compaison taking into account type.
* Removed quantize in vector-float.slang test.
Diffstat (limited to 'tools/slang-test/slang-test-main.cpp')
| -rw-r--r-- | tools/slang-test/slang-test-main.cpp | 179 |
1 files changed, 154 insertions, 25 deletions
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index a6ad0cff3..85425130d 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -4,6 +4,7 @@ #include "../../source/core/slang-token-reader.h" #include "../../source/core/slang-std-writers.h" #include "../../source/core/slang-hex-dump-util.h" +#include "../../source/core/slang-type-text-util.h" #include "../../slang-com-helper.h" @@ -708,7 +709,7 @@ static SlangResult _extractSlangCTestRequirements(const CommandLine& cmdLine, Te String passThrough; if (SLANG_SUCCEEDED(_extractArg(cmdLine, "-pass-through", passThrough))) { - ioRequirements->addUsedBackEnd(DownstreamCompiler::getPassThroughFromName(passThrough.getUnownedSlice())); + ioRequirements->addUsedBackEnd(TypeTextUtil::asPassThrough(passThrough.getUnownedSlice())); } } @@ -1995,6 +1996,147 @@ TestResult runPerformanceProfile(TestContext* context, TestInput& input) return TestResult::Pass; } + +static double _textToDouble(const UnownedStringSlice& slice) +{ + Index size = Index(slice.size()); + // We have to zero terminate to be able to use atof + const Index maxSize = 80; + char buffer[maxSize + 1]; + + size = (size > maxSize) ? maxSize : size; + + memcpy(buffer, slice.begin(), size); + buffer[size] = 0; + + return atof(buffer); +} + +static bool _areNearlyEqual(double a, double b, double epsilon) +{ + // If they are equal then we are done + if (a == b) + { + return true; + } + + const double absA = abs(a); + const double absB = abs(b); + const double diff = abs(a - b); + + // https://en.wikipedia.org/wiki/Double_precision_floating-point_format + // + const double minNormal = 2.2250738585072014e10-308; + + // Either a or b are very close to being zero, so doing relative comparison isn't really appropriate + if (a == 0.0 || b == 0.0 || (absA + absB < minNormal)) + { + return diff < (epsilon * minNormal); + } + else + { + // Calculate a relative relative error + return diff < epsilon * (absA + absB); + } +} + +static void _calcLines(const UnownedStringSlice& slice, List<UnownedStringSlice>& outLines) +{ + StringUtil::calcLines(slice, outLines); + + // Remove any trailing empty lines + while (outLines.getCount()) + { + if (outLines.getLast().trim() == UnownedStringSlice()) + { + outLines.removeLast(); + } + else + { + break; + } + } +} + +static SlangResult _compareWithType(const UnownedStringSlice& actual, const UnownedStringSlice& ref, double differenceThreshold = 0.001) +{ + typedef slang::TypeReflection::ScalarType ScalarType; + + ScalarType scalarType = ScalarType::None; + + // We just do straight comparison if there is no type + + List<UnownedStringSlice> linesActual, linesRef; + + _calcLines(actual, linesActual); + _calcLines(ref, linesRef); + + // If there are more lines in actual, we just ignore them, to keep same behavior as before + if (linesRef.getCount() < linesActual.getCount()) + { + linesActual.setCount(linesRef.getCount()); + } + + if (linesActual.getCount() != linesRef.getCount()) + { + return SLANG_FAIL; + } + + for (Index i = 0; i < linesActual.getCount(); ++i) + { + const UnownedStringSlice lineActual = linesActual[i]; + const UnownedStringSlice lineRef = linesRef[i]; + + if (lineActual.startsWith(UnownedStringSlice::fromLiteral("type:"))) + { + if (lineActual != lineRef) + { + return SLANG_FAIL; + } + // Get the type + List<UnownedStringSlice> split; + StringUtil::split(lineActual, ':', split); + + if (split.getCount() != 2) + { + return SLANG_FAIL; + } + + scalarType = TypeTextUtil::asScalarType(split[1].trim()); + continue; + } + + switch (scalarType) + { + default: + { + if (lineActual.trim() != lineRef.trim()) + { + return SLANG_FAIL; + } + break; + } + case ScalarType::Float16: + case ScalarType::Float32: + case ScalarType::Float64: + { + + // Compare as double + double valueA = _textToDouble(lineActual); + double valueB = _textToDouble(lineRef); + + if (!_areNearlyEqual(valueA, valueB, differenceThreshold)) + { + return SLANG_FAIL; + } + break; + } + } + } + + return SLANG_OK; +} + TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, const char *const* langOpts, size_t numLangOpts) { // TODO: delete any existing files at the output path(s) to avoid stale outputs leading to a false pass @@ -2035,8 +2177,8 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons return TestResult::Pass; } - const String referenceOutput = findExpectedPath(input, ".expected.txt"); - if (referenceOutput.getLength() <= 0) + const String referenceOutputFile = findExpectedPath(input, ".expected.txt"); + if (referenceOutputFile.getLength() <= 0) { return TestResult::Fail; } @@ -2060,33 +2202,20 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons printf("render-test output:\n%s\n", actualOutput.getBuffer()); return TestResult::Fail; } - if (!File::exists(referenceOutput)) + if (!File::exists(referenceOutputFile)) { - printf("referenceOutput %s not found.\n", referenceOutput.getBuffer()); + printf("referenceOutput %s not found.\n", referenceOutputFile.getBuffer()); return TestResult::Fail; } auto actualOutputContent = File::readAllText(actualOutputFile); - auto actualProgramOutput = Split(actualOutputContent, '\n'); - auto referenceProgramOutput = Split(File::readAllText(referenceOutput), '\n'); - auto printOutput = [&]() - { - context->reporter->messageFormat(TestMessageType::TestFailure, "output mismatch! actual output: {\n%s\n}, \n%s\n", actualOutputContent.getBuffer(), actualOutput.getBuffer()); - }; - if (actualProgramOutput.getCount() < referenceProgramOutput.getCount()) + auto referenceOutputContent = File::readAllText(referenceOutputFile); + + if (SLANG_FAILED(_compareWithType(actualOutputContent.getUnownedSlice(), referenceOutputContent.getUnownedSlice()))) { - printOutput(); - return TestResult::Fail; + context->reporter->messageFormat(TestMessageType::TestFailure, "output mismatch! actual output: {\n%s\n}, \n%s\n", actualOutputContent.getBuffer(), referenceOutputContent.getBuffer()); + return TestResult::Fail; } - for (Index i = 0; i < referenceProgramOutput.getCount(); i++) - { - auto reference = String(referenceProgramOutput[i].trim()); - auto actual = String(actualProgramOutput[i].trim()); - if (actual != reference) - { - printOutput(); - return TestResult::Fail; - } - } + return TestResult::Pass; } @@ -2536,7 +2665,7 @@ static void _calcSynthesizedTests(TestContext* context, RenderApiType synthRende { // const auto& language = srcTest.options.args[index + 1]; - SlangSourceLanguage sourceLanguage = DownstreamCompiler::getSourceLanguageFromName(language.getUnownedSlice()); + SlangSourceLanguage sourceLanguage = TypeTextUtil::asSourceLanguage(language.getUnownedSlice()); bool isCrossCompile = true; |
