summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-03-30 19:23:09 -0400
committerGitHub <noreply@github.com>2020-03-30 23:23:09 +0000
commitea7690558bca71ce3a9453adff4e0135352a352f (patch)
tree3eb983d3f8e6b1c215f6d2818a0f3e793ecb4485 /source
parentad5b60c8b5868c69a979779f201748fb7837fdc9 (diff)
CUDA version handling (#1301)
* render feature for CUDA compute model. * Use SemanticVersion type. * Enable CUDA wave tests that require CUDA SM 7.0. Provide mechanism for DownstreamCompiler to specify version numbers. * Enabled wave-equality.slang * Make CUDA SM version major version not just a single digit. * Fix assert. * DownstreamCompiler::Version -> CapabilityVersion
Diffstat (limited to 'source')
-rw-r--r--source/core/slang-downstream-compiler.h13
-rw-r--r--source/core/slang-nvrtc-compiler.cpp31
-rw-r--r--source/core/slang-semantic-version.cpp9
-rw-r--r--source/core/slang-semantic-version.h23
-rw-r--r--source/slang/hlsl.meta.slang6
-rw-r--r--source/slang/slang-compiler.cpp14
-rw-r--r--source/slang/slang-diagnostic-defs.h2
-rw-r--r--source/slang/slang-emit-cuda.cpp26
-rw-r--r--source/slang/slang-emit-cuda.h15
-rw-r--r--source/slang/slang-ir-inst-defs.h2
-rw-r--r--source/slang/slang-ir-insts.h18
-rw-r--r--source/slang/slang-lower-to-ir.cpp5
-rw-r--r--source/slang/slang-modifier-defs.h8
-rw-r--r--source/slang/slang-parser.cpp49
14 files changed, 187 insertions, 34 deletions
diff --git a/source/core/slang-downstream-compiler.h b/source/core/slang-downstream-compiler.h
index f9e33ed6c..3ffa32097 100644
--- a/source/core/slang-downstream-compiler.h
+++ b/source/core/slang-downstream-compiler.h
@@ -7,6 +7,7 @@
#include "slang-process-util.h"
#include "slang-platform.h"
+#include "slang-semantic-version.h"
#include "slang-io.h"
@@ -207,6 +208,16 @@ public:
String value;
};
+ struct CapabilityVersion
+ {
+ enum class Kind
+ {
+ CUDASM, ///< What the version is for
+ };
+ Kind kind;
+ SemanticVersion version;
+ };
+
struct CompileOptions
{
typedef uint32_t Flags;
@@ -247,6 +258,8 @@ public:
List<String> includePaths;
List<String> libraryPaths;
+
+ List<CapabilityVersion> requiredCapabilityVersions;
};
typedef uint32_t ProductFlags;
diff --git a/source/core/slang-nvrtc-compiler.cpp b/source/core/slang-nvrtc-compiler.cpp
index 5d5a1ce0f..0e167bf80 100644
--- a/source/core/slang-nvrtc-compiler.cpp
+++ b/source/core/slang-nvrtc-compiler.cpp
@@ -10,6 +10,7 @@
#include "slang-io.h"
#include "slang-shared-library.h"
+#include "slang-semantic-version.h"
namespace nvrtc
{
@@ -307,14 +308,30 @@ SlangResult NVRTCDownstreamCompiler::compile(const CompileOptions& options, RefP
// This is arguably too much - but nvrtc does not appear to have a mechanism to switch off individual warnings.
// I tried the -Xcudafe mechanism but that does not appear to work for nvrtc
cmdLine.addArg("-w");
+ }
- //
-#if 0
- cmdLine.addArg("-arch=compute_70");
-#else
- // Needed for Warp intrinsics
- cmdLine.addArg("-arch=compute_30");
-#endif
+ {
+ // Lowest supported is 3.0
+ SemanticVersion version(3);
+ for (const auto& capabilityVersion : options.requiredCapabilityVersions)
+ {
+ if (capabilityVersion.kind == DownstreamCompiler::CapabilityVersion::Kind::CUDASM)
+ {
+ if (capabilityVersion.version > version)
+ {
+ version = capabilityVersion.version;
+ }
+ }
+ }
+
+ StringBuilder builder;
+ builder << "-arch=compute_";
+ builder << version.m_major;
+
+ SLANG_ASSERT(version.m_minor >= 0 && version.m_minor <= 9);
+ builder << char('0' + version.m_minor);
+
+ cmdLine.addArg(builder);
}
nvrtcProgram program = nullptr;
diff --git a/source/core/slang-semantic-version.cpp b/source/core/slang-semantic-version.cpp
index 93536e007..7f603fd9c 100644
--- a/source/core/slang-semantic-version.cpp
+++ b/source/core/slang-semantic-version.cpp
@@ -7,13 +7,13 @@
namespace Slang {
-SlangResult SemanticVersion::parse(const UnownedStringSlice& value, SemanticVersion& outVersion)
+SlangResult SemanticVersion::parse(const UnownedStringSlice& value, char separatorChar, SemanticVersion& outVersion)
{
outVersion.reset();
UnownedStringSlice slices[3];
Index splitCount;
- SLANG_RETURN_ON_FAIL(StringUtil::split(value, '.', 3, slices, splitCount));
+ SLANG_RETURN_ON_FAIL(StringUtil::split(value, separatorChar, 3, slices, splitCount));
if (splitCount <= 0)
{
return SLANG_FAIL;
@@ -38,6 +38,11 @@ SlangResult SemanticVersion::parse(const UnownedStringSlice& value, SemanticVers
return SLANG_OK;
}
+SlangResult SemanticVersion::parse(const UnownedStringSlice& value, SemanticVersion& outVersion)
+{
+ return parse(value, '.', outVersion);
+}
+
void SemanticVersion::append(StringBuilder& buf) const
{
buf << Int32(m_major) << "." << Int32(m_minor);
diff --git a/source/core/slang-semantic-version.h b/source/core/slang-semantic-version.h
index bbfcb663e..d33116de6 100644
--- a/source/core/slang-semantic-version.h
+++ b/source/core/slang-semantic-version.h
@@ -15,9 +15,9 @@ struct SemanticVersion
SemanticVersion():m_major(0), m_minor(0), m_patch(0) {}
SemanticVersion(int inMajor, int inMinor = 0, int inPatch = 0):
- m_major(uint8_t(inMajor)),
- m_minor(uint8_t(inMinor)),
- m_patch(uint8_t(inPatch))
+ m_major(uint32_t(inMajor)),
+ m_minor(uint16_t(inMinor)),
+ m_patch(uint16_t(inPatch))
{}
void reset()
@@ -27,15 +27,26 @@ struct SemanticVersion
m_patch = 0;
}
+ /// All zeros means nothing is set
+ bool isSet() const { return m_major || m_minor || m_patch; }
+
IntegerType toInteger() const { return (IntegerType(m_major) << 32) | (uint32_t(m_minor) << 16) | m_patch; }
void setFromInteger(IntegerType v)
{
- m_major = (v >> 32);
- m_minor = uint16_t(v >> 16);
- m_patch = uint16_t(v);
+ set(int(v >> 32), int((v >> 16) & 0xffff), int(v & 0xffff));
+ }
+ void set(int major, int minor, int patch = 0)
+ {
+ SLANG_ASSERT(major >= 0 && minor >=0 && patch >= 0);
+
+ m_major = uint32_t(major);
+ m_minor = uint16_t(minor);
+ m_patch = uint16_t(patch);
}
static SlangResult parse(const UnownedStringSlice& value, SemanticVersion& outVersion);
+ static SlangResult parse(const UnownedStringSlice& value, char separatorChar, SemanticVersion& outVersion);
+
void append(StringBuilder& buf) const;
bool operator>(const ThisType& rhs) const { return toInteger() > rhs.toInteger(); }
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index e2e745773..f82f7b5f4 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -2616,15 +2616,18 @@ __generic<T : __BuiltinType>
__glsl_extension(GL_KHR_shader_subgroup_vote)
__spirv_version(1.3)
__target_intrinsic(glsl, "subgroupAllEqual($0)")
+__cuda_sm_version(7.0)
__target_intrinsic(cuda, "_waveAllEqual($0)")
bool WaveActiveAllEqual(T value);
__generic<T : __BuiltinType, let N : int>
__glsl_extension(GL_KHR_shader_subgroup_vote)
__spirv_version(1.3)
__target_intrinsic(glsl, "subgroupAllEqual($0)")
+__cuda_sm_version(7.0)
__target_intrinsic(cuda, "_waveAllEqualMultiple($0)")
bool WaveActiveAllEqual(vector<T,N> value);
__generic<T : __BuiltinType, let N : int, let M : int>
+__cuda_sm_version(7.0)
__target_intrinsic(cuda, "_waveAllEqualMultiple($0)")
bool WaveActiveAllEqual(matrix<T,N,M> value);
@@ -2796,14 +2799,17 @@ uint WavePrefixCountBits(bool value);
__generic<T : __BuiltinType>
__target_intrinsic(hlsl)
+__cuda_sm_version(7.0)
__target_intrinsic(cuda, "_waveMatchScalar($0)")
uint4 WaveMatch(T value);
__generic<T : __BuiltinType, let N : int>
__target_intrinsic(hlsl)
+__cuda_sm_version(7.0)
__target_intrinsic(cuda, "_waveMatchMultiple($0)")
uint4 WaveMatch(vector<T,N> value);
__generic<T : __BuiltinType, let N : int, let M : int>
__target_intrinsic(hlsl)
+__cuda_sm_version(7.0)
__target_intrinsic(cuda, "_waveMatchMultiple($0)")
uint4 WaveMatch(matrix<T,N,M> value);
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 7eb5f145b..53a028483 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -22,6 +22,7 @@
#include "slang-emit.h"
#include "slang-glsl-extension-tracker.h"
+#include "slang-emit-cuda.h"
#include "slang-ir-serialize.h"
@@ -1292,6 +1293,19 @@ SlangResult dissassembleDXILUsingDXC(
SourceResult source;
SLANG_RETURN_ON_FAIL(emitEntryPointSource(slangRequest, entryPointIndex, targetReq, sourceTarget, endToEndReq, source));
+ // Look for the version
+ if (auto cudaTracker = as<CUDAExtensionTracker>(source.extensionTracker))
+ {
+ if (cudaTracker->m_smVersion.isSet())
+ {
+ DownstreamCompiler::CapabilityVersion version;
+ version.kind = DownstreamCompiler::CapabilityVersion::Kind::CUDASM;
+ version.version = cudaTracker->m_smVersion;
+
+ options.requiredCapabilityVersions.add(version);
+ }
+ }
+
options.sourceContents = source.source;
maybeDumpIntermediate(slangRequest, options.sourceContents.getBuffer(), sourceTarget);
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index a28bfe77e..6e77aa45d 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -208,7 +208,7 @@ DIAGNOSTIC(20004, Error, unexpectedTokenExpectedComponentDefinition, "unexpected
DIAGNOSTIC(20008, Error, invalidOperator, "invalid operator '$0'.");
DIAGNOSTIC(20011, Error, unexpectedColon, "unexpected ':'.")
DIAGNOSTIC(20012, Error, invalidSPIRVVersion, "Expecting SPIR-V version as either 'major.minor', or quoted if has patch (eg for SPIR-V 1.2, '1.2' or \"1.2\"')")
-
+DIAGNOSTIC(20013, Error, invalidCUDASMVersion, "Expecting CUDA SM version as either 'major.minor', or quoted if has patch (eg for '7.0' or \"7.0\"')")
//
// 3xxxx - Semantic analysis
//
diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp
index 64cb240fc..a728df755 100644
--- a/source/slang/slang-emit-cuda.cpp
+++ b/source/slang/slang-emit-cuda.cpp
@@ -375,6 +375,32 @@ bool CUDASourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
return Super::tryEmitInstExprImpl(inst, inOuterPrec);
}
+void CUDASourceEmitter::handleCallExprDecorationsImpl(IRInst* funcValue)
+{
+ // Does this function declare any requirements on GLSL version or
+ // extensions, which should affect our output?
+
+ auto decoratedValue = funcValue;
+ while (auto specInst = as<IRSpecialize>(decoratedValue))
+ {
+ decoratedValue = getSpecializedValue(specInst);
+ }
+
+ for (auto decoration : decoratedValue->getDecorations())
+ {
+ if( auto smDecoration = as<IRRequireCUDASMVersionDecoration>(decoration))
+ {
+ SemanticVersion version;
+ version.setFromInteger(SemanticVersion::IntegerType(smDecoration->getCUDASMVersion()));
+
+ if (version > m_extensionTracker->m_smVersion)
+ {
+ m_extensionTracker->m_smVersion = version;
+ }
+ }
+ }
+}
+
void CUDASourceEmitter::emitLayoutDirectivesImpl(TargetRequest* targetReq)
{
SLANG_UNUSED(targetReq);
diff --git a/source/slang/slang-emit-cuda.h b/source/slang/slang-emit-cuda.h
index 3d23fd80f..dce3b4eb8 100644
--- a/source/slang/slang-emit-cuda.h
+++ b/source/slang/slang-emit-cuda.h
@@ -7,6 +7,13 @@
namespace Slang
{
+class CUDAExtensionTracker : public RefObject
+{
+public:
+
+ SemanticVersion m_smVersion;
+};
+
class CUDASourceEmitter : public CPPSourceEmitter
{
public:
@@ -26,8 +33,11 @@ public:
static UnownedStringSlice getBuiltinTypeName(IROp op);
static UnownedStringSlice getVectorPrefix(IROp op);
+ virtual RefObject* getExtensionTracker() SLANG_OVERRIDE { return m_extensionTracker; }
+
CUDASourceEmitter(const Desc& desc) :
- Super(desc)
+ Super(desc),
+ m_extensionTracker(new CUDAExtensionTracker)
{}
protected:
@@ -51,6 +61,7 @@ protected:
virtual void emitLoopControlDecorationImpl(IRLoopControlDecoration* decl) SLANG_OVERRIDE;
+ virtual void handleCallExprDecorationsImpl(IRInst* funcValue) SLANG_OVERRIDE;
//virtual bool tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType) SLANG_OVERRIDE;
virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE;
@@ -64,6 +75,8 @@ protected:
virtual SlangResult calcScalarFuncName(HLSLIntrinsic::Op op, IRBasicType* type, StringBuilder& outBuilder) SLANG_OVERRIDE;
SlangResult _calcCUDATextureTypeName(IRTextureTypeBase* texType, StringBuilder& outName);
+
+ RefPtr<CUDAExtensionTracker> m_extensionTracker;
};
}
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index c6aaf57ca..6c01a700a 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -404,6 +404,8 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
INST(RequireSPIRVVersionDecoration, requireSPIRVVersion, 1, 0)
INST(RequireGLSLVersionDecoration, requireGLSLVersion, 1, 0)
INST(RequireGLSLExtensionDecoration, requireGLSLExtension, 1, 0)
+ INST(RequireCUDASMVersionDecoration, requireCUDASMVersion, 1, 0)
+
INST(ReadNoneDecoration, readNone, 0, 0)
INST(VulkanCallablePayloadDecoration, vulkanCallablePayload, 0, 0)
INST(EarlyDepthStencilDecoration, earlyDepthStencil, 0, 0)
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 448bf9f0e..e307dc41e 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -190,6 +190,18 @@ struct IRRequireSPIRVVersionDecoration : IRDecoration
}
};
+struct IRRequireCUDASMVersionDecoration : IRDecoration
+{
+ enum { kOp = kIROp_RequireCUDASMVersionDecoration };
+ IR_LEAF_ISA(RequireCUDASMVersionDecoration)
+
+ IRConstant* getCUDASMVersionOperand() { return cast<IRConstant>(getOperand(0)); }
+ IntegerLiteralValue getCUDASMVersion()
+ {
+ return getCUDASMVersionOperand()->value.intVal;
+ }
+};
+
struct IRRequireGLSLExtensionDecoration : IRDecoration
{
enum { kOp = kIROp_RequireGLSLExtensionDecoration };
@@ -2131,6 +2143,12 @@ struct IRBuilder
addDecoration(value, kIROp_RequireSPIRVVersionDecoration, getIntValue(getBasicType(BaseType::UInt64), intValue));
}
+ void addRequireCUDASMVersionDecoration(IRInst* value, const SemanticVersion& version)
+ {
+ SemanticVersion::IntegerType intValue = version.toInteger();
+ addDecoration(value, kIROp_RequireCUDASMVersionDecoration, getIntValue(getBasicType(BaseType::UInt64), intValue));
+ }
+
void addPatchConstantFuncDecoration(IRInst* value, IRInst* patchConstantFunc)
{
addDecoration(value, kIROp_PatchConstantFuncDecoration, patchConstantFunc);
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 16dc14819..ea1196a6c 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -6196,7 +6196,10 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
{
getBuilder()->addRequireSPIRVVersionDecoration(irFunc, versionMod->version);
}
-
+ for (auto versionMod : decl->GetModifiersOfType<RequiredCUDASMVersionModifier>())
+ {
+ getBuilder()->addRequireCUDASMVersionDecoration(irFunc, versionMod->version);
+ }
if (auto attr = decl->FindModifier<InstanceAttribute>())
{
diff --git a/source/slang/slang-modifier-defs.h b/source/slang/slang-modifier-defs.h
index 7ea1d0101..0c7156c72 100644
--- a/source/slang/slang-modifier-defs.h
+++ b/source/slang/slang-modifier-defs.h
@@ -80,6 +80,12 @@ SYNTAX_CLASS(RequiredSPIRVVersionModifier, Modifier)
FIELD(SemanticVersion, version)
END_SYNTAX_CLASS()
+// A modifier to tag something as an intrinsic that requires
+// a certain CUDA SM version to be enabled when used. Specified as "major.minor"
+SYNTAX_CLASS(RequiredCUDASMVersionModifier, Modifier)
+FIELD(SemanticVersion, version)
+END_SYNTAX_CLASS()
+
SIMPLE_SYNTAX_CLASS(InOutModifier, OutModifier)
// `__ref` modifier for by-reference parameter passing
@@ -486,4 +492,4 @@ SIMPLE_SYNTAX_CLASS(ExternAttribute, Attribute)
// An `[__unsafeForceInlineExternal]` attribute indicates that the callee should be inlined
// into call sites after initial IR generation (that is, as early as possible).
//
-SIMPLE_SYNTAX_CLASS(UnsafeForceInlineEarlyAttribute, Attribute) \ No newline at end of file
+SIMPLE_SYNTAX_CLASS(UnsafeForceInlineEarlyAttribute, Attribute)
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 46dd617a1..5a99f6ffb 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -4819,17 +4819,17 @@ namespace Slang
return modifier;
}
- static RefPtr<RefObject> parseSPIRVVersionModifier(Parser* parser, void* /*userData*/)
- {
- auto modifier = new RequiredSPIRVVersionModifier();
+
+ static SlangResult parseSemanticVersion(Parser* parser, Token& outToken, SemanticVersion& outVersion)
+ {
parser->ReadToken(TokenType::LParent);
- Token token = parser->ReadToken();
+ outToken = parser->ReadToken();
parser->ReadToken(TokenType::RParent);
- UnownedStringSlice content = token.Content;
+ UnownedStringSlice content = outToken.Content;
// We allow specified as major.minor or as a string (in quotes)
- switch (token.type)
+ switch (outToken.type)
{
case TokenType::FloatingPointLiteral:
{
@@ -4838,26 +4838,44 @@ namespace Slang
case TokenType::StringLiteral:
{
// We need to trim quotes if needed
- SLANG_ASSERT(content.getLength() >= 2 && content[0] == '"' && content[content.getLength() -1] == '"');
+ SLANG_ASSERT(content.getLength() >= 2 && content[0] == '"' && content[content.getLength() - 1] == '"');
content = UnownedStringSlice(content.begin() + 1, content.end() - 1);
break;
}
default:
{
- parser->sink->diagnose(token, Diagnostics::invalidSPIRVVersion);
- return RefPtr<RefObject>();
+ return SLANG_FAIL;
}
}
-
+ return SemanticVersion::parse(content, outVersion);
+ }
+
+ static RefPtr<RefObject> parseSPIRVVersionModifier(Parser* parser, void* /*userData*/)
+ {
+ Token token;
SemanticVersion version;
- if (SLANG_FAILED(SemanticVersion::parse(content, modifier->version)))
+ if (SLANG_SUCCEEDED(parseSemanticVersion(parser, token, version)))
{
- // Unable to parse the error so fail
- parser->sink->diagnose(token, Diagnostics::invalidSPIRVVersion);
- return RefPtr<RefObject>();
+ auto modifier = new RequiredSPIRVVersionModifier();
+ modifier->version = version;
+ return modifier;
}
+ parser->sink->diagnose(token, Diagnostics::invalidSPIRVVersion);
+ return RefPtr<RefObject>();
+ }
- return modifier;
+ static RefPtr<RefObject> parseCUDASMVersionModifier(Parser* parser, void* /*userData*/)
+ {
+ Token token;
+ SemanticVersion version;
+ if (SLANG_SUCCEEDED(parseSemanticVersion(parser, token, version)))
+ {
+ auto modifier = new RequiredCUDASMVersionModifier();
+ modifier->version = version;
+ return modifier;
+ }
+ parser->sink->diagnose(token, Diagnostics::invalidCUDASMVersion);
+ return RefPtr<RefObject>();
}
static RefPtr<RefObject> parseLayoutModifier(Parser* parser, void* /*userData*/)
@@ -5149,6 +5167,7 @@ namespace Slang
MODIFIER(__glsl_extension, parseGLSLExtensionModifier);
MODIFIER(__glsl_version, parseGLSLVersionModifier);
MODIFIER(__spirv_version, parseSPIRVVersionModifier);
+ MODIFIER(__cuda_sm_version, parseCUDASMVersionModifier);
MODIFIER(__builtin_type, parseBuiltinTypeModifier);
MODIFIER(__magic_type, parseMagicTypeModifier);