summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/core/slang-nvrtc-compiler.cpp5
-rw-r--r--tests/compute/rw-texture-simple.slang3
-rw-r--r--tests/hlsl-intrinsic/wave-equality.slang3
-rw-r--r--tests/hlsl-intrinsic/wave-multi-prefix.slang3
-rw-r--r--tools/render-test/cuda/cuda-compute-util.cpp117
-rw-r--r--tools/render-test/render-test-main.cpp25
-rw-r--r--tools/slang-test/slang-test-main.cpp37
7 files changed, 159 insertions, 34 deletions
diff --git a/source/core/slang-nvrtc-compiler.cpp b/source/core/slang-nvrtc-compiler.cpp
index db4e4f32f..5d5a1ce0f 100644
--- a/source/core/slang-nvrtc-compiler.cpp
+++ b/source/core/slang-nvrtc-compiler.cpp
@@ -309,7 +309,12 @@ SlangResult NVRTCDownstreamCompiler::compile(const CompileOptions& options, RefP
cmdLine.addArg("-w");
//
+#if 0
cmdLine.addArg("-arch=compute_70");
+#else
+ // Needed for Warp intrinsics
+ cmdLine.addArg("-arch=compute_30");
+#endif
}
nvrtcProgram program = nullptr;
diff --git a/tests/compute/rw-texture-simple.slang b/tests/compute/rw-texture-simple.slang
index 3598cadeb..a6632a143 100644
--- a/tests/compute/rw-texture-simple.slang
+++ b/tests/compute/rw-texture-simple.slang
@@ -6,7 +6,8 @@
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile cs_6_0 -use-dxil -output-using-type
// TODO(JS): Doesn't work on vk currently, because createTextureView not implemented on vk renderer
//DISABLE_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -output-using-type
-//TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute -output-using-type
+// TODO(JS): Doesn't work on certain CI systems.
+//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute -output-using-type
//TEST_INPUT: RWTexture1D(format=R_Float32, size=4, content = one):name rwt1D
RWTexture1D<float> rwt1D;
diff --git a/tests/hlsl-intrinsic/wave-equality.slang b/tests/hlsl-intrinsic/wave-equality.slang
index d12d8cfbc..eb9e3e6a3 100644
--- a/tests/hlsl-intrinsic/wave-equality.slang
+++ b/tests/hlsl-intrinsic/wave-equality.slang
@@ -2,7 +2,8 @@
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil -profile cs_6_0
//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
-//TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute
+// TODO(JS): Requires compute_7_0 which isn't available on all CI systems with CUDA
+//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
RWStructuredBuffer<int> outputBuffer;
diff --git a/tests/hlsl-intrinsic/wave-multi-prefix.slang b/tests/hlsl-intrinsic/wave-multi-prefix.slang
index 3eee16e31..fb649d6ef 100644
--- a/tests/hlsl-intrinsic/wave-multi-prefix.slang
+++ b/tests/hlsl-intrinsic/wave-multi-prefix.slang
@@ -5,7 +5,8 @@
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil -profile sm_6_5
// Disabled because we don't have GLSL intrinsics for these it seems
//DISABLE_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
-//TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute
+// TODO(JS): Disabled because requires compute_7_0 which isn't available on all CI with CUDA
+//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute
//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer
RWStructuredBuffer<int> outputBuffer;
diff --git a/tools/render-test/cuda/cuda-compute-util.cpp b/tools/render-test/cuda/cuda-compute-util.cpp
index 96b4e3b3e..af7c0e6c2 100644
--- a/tools/render-test/cuda/cuda-compute-util.cpp
+++ b/tools/render-test/cuda/cuda-compute-util.cpp
@@ -18,14 +18,96 @@ using namespace Slang;
SLANG_FORCE_INLINE static bool _isError(CUresult result) { return result != 0; }
SLANG_FORCE_INLINE static bool _isError(cudaError_t result) { return result != 0; }
-#if 0
-#define SLANG_CUDA_RETURN_ON_FAIL(x) { auto _res = x; if (_isError(_res)) return SLANG_FAIL; }
+// A enum used to control if errors are reported on failure of CUDA call.
+enum class CUDAReportStyle
+{
+ Normal,
+ Silent,
+};
+
+struct CUDAErrorInfo
+{
+ CUDAErrorInfo(const char* filePath, int lineNo, const char* errorName = nullptr, const char* errorString = nullptr):
+ m_filePath(filePath),
+ m_lineNo(lineNo),
+ m_errorName(errorName),
+ m_errorString(errorString)
+ {
+ }
+ SlangResult handle() const
+ {
+ StringBuilder builder;
+ builder << "Error: " << m_filePath << " (" << m_lineNo << ") :";
+
+ if (m_errorName)
+ {
+ builder << m_errorName << " : ";
+ }
+ if (m_errorString)
+ {
+ builder << m_errorString;
+ }
+
+ StdWriters::getError().put(builder.getUnownedSlice());
+
+ //Slang::signalUnexpectedError(builder.getBuffer());
+ return SLANG_FAIL;
+ }
+
+ const char* m_filePath;
+ int m_lineNo;
+ const char* m_errorName;
+ const char* m_errorString;
+};
+
+#if 1
+// If this code path is enabled, CUDA errors will be reported directly to StdWriter::out stream.
+
+static SlangResult _handleCUDAError(CUresult cuResult, const char* file, int line)
+{
+ CUDAErrorInfo info(file, line);
+ cuGetErrorString(cuResult, &info.m_errorString);
+ cuGetErrorName(cuResult, &info.m_errorName);
+ return info.handle();
+}
+
+static SlangResult _handleCUDAError(cudaError_t error, const char* file, int line)
+{
+ return CUDAErrorInfo(file, line, cudaGetErrorName(error), cudaGetErrorString(error)).handle();
+}
+
+#define SLANG_CUDA_HANDLE_ERROR(x) _handleCUDAError(_res, __FILE__, __LINE__)
+
#else
+// If this code path is enabled, errors are not reported, but can have an assert enabled
-#define SLANG_CUDA_RETURN_ON_FAIL(x) { auto _res = x; if (_isError(_res)) { SLANG_ASSERT(!"Failed CUDA call"); return SLANG_FAIL; } }
+static SlangResult _handleCUDAError(CUresult cuResult)
+{
+ SLANG_UNUSED(cuResult);
+ //SLANG_ASSERT(!"Failed CUDA call");
+ return SLANG_FAIL;
+}
+static SlangResult _handleCUDAError(cudaError_t error)
+{
+ SLANG_UNUSED(error);
+ //SLANG_ASSERT(!"Failed CUDA call");
+ return SLANG_FAIL;
+}
+
+#define SLANG_CUDA_HANDLE_ERROR(x) _handleCUDAError(_res)
#endif
+#define SLANG_CUDA_RETURN_ON_FAIL(x) { auto _res = x; if (_isError(_res)) return SLANG_CUDA_HANDLE_ERROR(_res); }
+#define SLANG_CUDA_RETURN_WITH_REPORT_ON_FAIL(x, r) \
+ { \
+ auto _res = x; \
+ if (_isError(_res)) \
+ { \
+ return (r == CUDAReportStyle::Normal) ? SLANG_CUDA_HANDLE_ERROR(_res) : SLANG_FAIL; \
+ } \
+ } \
+
#define SLANG_CUDA_ASSERT_ON_FAIL(x) { auto _res = x; if (_isError(_res)) { SLANG_ASSERT(!"Failed CUDA call"); }; }
class MemoryCUDAResource : public CUDAResource
@@ -282,11 +364,10 @@ static SlangResult _findMaxFlopsDeviceId(int* outDevice)
return SLANG_OK;
}
-static SlangResult _initCuda()
+static SlangResult _initCuda(CUDAReportStyle reportType = CUDAReportStyle::Normal)
{
static CUresult res = cuInit(0);
- SLANG_CUDA_RETURN_ON_FAIL(res);
-
+ SLANG_CUDA_RETURN_WITH_REPORT_ON_FAIL(res, reportType);
return SLANG_OK;
}
@@ -295,39 +376,35 @@ class ScopeCUDAContext
public:
ScopeCUDAContext() : m_context(nullptr) {}
- SlangResult init(unsigned int flags, CUdevice device)
+ SlangResult init(unsigned int flags, CUdevice device, CUDAReportStyle reportType = CUDAReportStyle::Normal)
{
- SLANG_RETURN_ON_FAIL(_initCuda());
+ SLANG_RETURN_ON_FAIL(_initCuda(reportType));
if (m_context)
{
cuCtxDestroy(m_context);
m_context = nullptr;
}
- if (_isError(cuCtxCreate(&m_context, flags, device)))
- {
- return SLANG_FAIL;
- }
+
+ SLANG_CUDA_RETURN_WITH_REPORT_ON_FAIL(cuCtxCreate(&m_context, flags, device), reportType);
return SLANG_OK;
}
- SlangResult init(unsigned int flags)
+ SlangResult init(unsigned int flags, CUDAReportStyle reportType = CUDAReportStyle::Normal)
{
- SLANG_RETURN_ON_FAIL(_initCuda());
+ SLANG_RETURN_ON_FAIL(_initCuda(reportType));
int deviceId;
SLANG_RETURN_ON_FAIL(_findMaxFlopsDeviceId(&deviceId));
- SLANG_CUDA_RETURN_ON_FAIL(cudaSetDevice(deviceId));
+ SLANG_CUDA_RETURN_WITH_REPORT_ON_FAIL(cudaSetDevice(deviceId), reportType);
if (m_context)
{
cuCtxDestroy(m_context);
m_context = nullptr;
}
- if (_isError(cuCtxCreate(&m_context, flags, deviceId)))
- {
- return SLANG_FAIL;
- }
+
+ SLANG_CUDA_RETURN_WITH_REPORT_ON_FAIL(cuCtxCreate(&m_context, flags, deviceId), reportType);
return SLANG_OK;
}
@@ -346,7 +423,7 @@ public:
/* static */bool CUDAComputeUtil::canCreateDevice()
{
ScopeCUDAContext context;
- return SLANG_SUCCEEDED(context.init(0));
+ return SLANG_SUCCEEDED(context.init(0, CUDAReportStyle::Silent));
}
static bool _hasReadAccess(SlangResourceAccess access)
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 4f5d1e9bb..ab041b5bc 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -406,7 +406,7 @@ Result RenderTestApp::update(Window* window)
} // namespace renderer_test
-SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSession* session, int argcIn, const char*const* argvIn)
+static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* session, int argcIn, const char*const* argvIn)
{
using namespace renderer_test;
using namespace Slang;
@@ -694,6 +694,29 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
}
}
+SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSession* session, int argcIn, const char*const* argvIn)
+{
+ using namespace Slang;
+
+ SlangResult res = SLANG_FAIL;
+ try
+ {
+ res = _innerMain(stdWriters, session, argcIn, argvIn);
+ }
+ catch (const Slang::Exception& exception)
+ {
+ stdWriters->getOut().put(exception.Message.getUnownedSlice());
+ return SLANG_FAIL;
+ }
+ catch (...)
+ {
+ stdWriters->getOut().put(UnownedStringSlice::fromLiteral("Unhandled exception"));
+ return SLANG_FAIL;
+ }
+
+ return res;
+}
+
int main(int argc, char** argv)
{
using namespace Slang;
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index a85516941..a2e3296c9 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -54,6 +54,7 @@ struct TestOptions
// The categories that this test was assigned to
List<TestCategory*> categories;
+ bool isEnabled = true;
bool isSynthesized = false;
};
@@ -303,6 +304,8 @@ static TestResult _gatherTestOptions(
{
case 0: case '\r': case '\n':
skipToEndOfLine(&cursor);
+
+ *ioCursor = cursor;
return TestResult::Pass;
default:
@@ -348,7 +351,6 @@ TestResult gatherTestsForFile(
return TestResult::Fail;
}
-
// Walk through the lines of the file, looking for test commands
char const* cursor = fileContents.begin();
@@ -358,24 +360,33 @@ TestResult gatherTestsForFile(
skipHorizontalSpace(&cursor);
+ if(!match(&cursor, "//"))
+ {
+ skipToEndOfLine(&cursor);
+ continue;
+ }
+
// Look for a pattern that matches what we want
- if(match(&cursor, "//TEST_IGNORE_FILE"))
+ if (match(&cursor, "TEST_IGNORE_FILE"))
{
return TestResult::Ignored;
}
- else if(match(&cursor, "//TEST"))
+
+ TestDetails testDetails;
+ if (match(&cursor, "DISABLE_"))
{
- TestDetails testDetails;
+ testDetails.options.isEnabled = false;
+ }
+ if(match(&cursor, "TEST"))
+ {
if(_gatherTestOptions(categorySet, &cursor, testDetails.options) != TestResult::Pass)
return TestResult::Fail;
testList->tests.add(testDetails);
}
- else if (match(&cursor, "//DIAGNOSTIC_TEST"))
+ else if (match(&cursor, "DIAGNOSTIC_TEST"))
{
- TestDetails testDetails;
-
if (_gatherTestOptions(categorySet, &cursor, testDetails.options) != TestResult::Pass)
return TestResult::Fail;
@@ -2779,9 +2790,15 @@ static void _calcSynthesizedTests(TestContext* context, RenderApiType synthRende
}
}
-static bool _canIgnore(TestContext* context,
- const TestRequirements& requirements)
+static bool _canIgnore(TestContext* context, const TestDetails& details)
{
+ if (details.options.isEnabled == false)
+ {
+ return true;
+ }
+
+ const auto& requirements = details.requirements;
+
// Work out what render api flags are available
const RenderApiFlags availableRenderApiFlags = requirements.usedRenderApiFlags ? _getAvailableRenderApiFlags(context) : 0;
@@ -2933,7 +2950,7 @@ void runTestsOnFile(
TestResult testResult = TestResult::Fail;
// If this test can be ignored
- if (_canIgnore(context, testDetails.requirements))
+ if (_canIgnore(context, testDetails))
{
testResult = TestResult::Ignored;
}