Skip to content

Commit 9304c2d

Browse files
csyonghejsmall-zzz
andauthored
Diagnostic for no type conformance + bug fix. (shader-slang#1985)
* Diagnostic for no type conformance + bug fix. * Fixes. * Fix. * Include heterogeneous example only with --enable-experimental-projects premake flag Co-authored-by: Yong He <yhe@nvidia.com> Co-authored-by: jsmall-nvidia <jsmall@nvidia.com>
1 parent 66e319e commit 9304c2d

11 files changed

+128
-237
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,5 @@ prelude/*.h.cpp
5858
/docs/Gemfile.lock
5959
/docs/Gemfile
6060
/source/slang/slang-stdlib-generated.h
61+
62+
/examples/heterogeneous-hello-world/shader.cpp
+1-180
Original file line numberDiff line numberDiff line change
@@ -1,180 +1 @@
1-
#include "../../prelude/slang-cpp-prelude.h"
2-
3-
4-
#ifdef SLANG_PRELUDE_NAMESPACE
5-
using namespace SLANG_PRELUDE_NAMESPACE;
6-
#endif
7-
8-
Vector<uint32_t, 3> operator+(Vector<uint32_t, 3> a, Vector<uint32_t, 3> b)
9-
{
10-
Vector<uint32_t, 3> r;
11-
r.x = a.x + b.x;
12-
r.y = a.y + b.y;
13-
r.z = a.z + b.z;
14-
return r;
15-
}
16-
17-
Vector<uint32_t, 3> operator*(Vector<uint32_t, 3> a, Vector<uint32_t, 3> b)
18-
{
19-
Vector<uint32_t, 3> r;
20-
r.x = a.x * b.x;
21-
r.y = a.y * b.y;
22-
r.z = a.z * b.z;
23-
return r;
24-
}
25-
26-
Vector<uint32_t, 3> make_VecU3(uint32_t a, uint32_t b, uint32_t c)
27-
{
28-
return Vector<uint32_t, 3>{ a, b, c};
29-
}
30-
31-
void computeMain_wrapper(gfx_Device_0* device, Vector<uint32_t, 3> gridDims,
32-
RWStructuredBuffer<float> buffer)
33-
{
34-
gfx_ShaderProgram_0* shaderProgram = loadShaderProgram_0(device, "computeMain", "shader");
35-
gfx_TransientResourceHeap_0* transientHeap = buildTransientHeap_0(device);
36-
gfx_PipelineState_0* pipelineState = buildPipelineState_0(device, shaderProgram);
37-
gfx_ResourceView_0* bufferView = createBufferView_0(device, unconvertBuffer_0(buffer));
38-
dispatchComputation_0(device, transientHeap, pipelineState, bufferView, gridDims.x, gridDims.y, gridDims.z);
39-
}
40-
41-
#line 8 "../../../examples/heterogeneous-hello-world/shader.slang"
42-
struct EntryPointParams_0
43-
{
44-
RWStructuredBuffer<float> ioBuffer_0;
45-
};
46-
47-
48-
#line 21
49-
struct gfx_Device_0
50-
{
51-
};
52-
53-
54-
#line 22
55-
struct gfx_BufferResource_0
56-
{
57-
};
58-
59-
60-
#line 23
61-
struct gfx_ResourceView_0
62-
{
63-
};
64-
65-
66-
#line 8
67-
void _computeMain(void* _S1, void* entryPointParams_0, void* _S2)
68-
{
69-
70-
#line 8
71-
ComputeThreadVaryingInput* _S3 = (slang_bit_cast<ComputeThreadVaryingInput*>(_S1));
72-
73-
uint32_t tid_0 = (*(&_S3->groupID) * make_VecU3(4U, 1U, 1U) + *(&_S3->groupThreadID)).x;
74-
75-
float* _S4 = &(*(&(slang_bit_cast<EntryPointParams_0*>(entryPointParams_0))->ioBuffer_0))[tid_0];
76-
77-
#line 12
78-
float i_0 = *_S4;
79-
bool _S5 = i_0 < 0.50000000000000000000f;
80-
81-
#line 13
82-
float _S6 = i_0 + i_0;
83-
84-
#line 13
85-
float _S7 = (F32_sqrt((i_0)));
86-
87-
#line 13
88-
float o_0 = _S5 ? _S6 : _S7;
89-
90-
float* _S8 = &(*(&(slang_bit_cast<EntryPointParams_0*>(entryPointParams_0))->ioBuffer_0))[tid_0];
91-
92-
#line 15
93-
*_S8 = o_0;
94-
return;
95-
}
96-
97-
98-
#line 31
99-
gfx_Device_0* createDevice_0();
100-
101-
gfx_BufferResource_0* createStructuredBuffer_0(gfx_Device_0* _0, FixedArray<float, 4> _1);
102-
103-
104-
gfx_ResourceView_0* createBufferView_0(gfx_Device_0* _0, gfx_BufferResource_0* _1);
105-
106-
107-
#line 4
108-
RWStructuredBuffer<float> convertBuffer_0(gfx_BufferResource_0* _0);
109-
110-
111-
#line 44
112-
void printInitialValues_0(FixedArray<float, 4> _0, int32_t _1);
113-
114-
115-
#line 50
116-
bool printOutputValues_0(gfx_Device_0* _0, gfx_BufferResource_0* _1, int32_t _2);
117-
118-
119-
120-
121-
bool executeComputation_0()
122-
{
123-
124-
FixedArray<float, 4> initialArray_0 = { 3.00000000000000000000f, -20.00000000000000000000f, -6.00000000000000000000f, 8.00000000000000000000f };
125-
126-
127-
gfx_Device_0* _S9 = createDevice_0();
128-
gfx_BufferResource_0* _S10 = createStructuredBuffer_0(_S9, initialArray_0);
129-
gfx_ResourceView_0* _S11 = createBufferView_0(_S9, _S10);
130-
Vector<uint32_t, 3> _S12 = make_VecU3(uint32_t(int(4)), uint32_t(int(1)), uint32_t(int(1)));
131-
RWStructuredBuffer<float> _S13 = convertBuffer_0(_S10);
132-
133-
#line 64
134-
computeMain_wrapper(_S9, _S12, _S13);
135-
136-
printInitialValues_0(initialArray_0, int(4));
137-
bool _S14 = printOutputValues_0(_S9, _S10, int(4));
138-
139-
140-
return true;
141-
}
142-
143-
// [numthreads(4, 1, 1)]
144-
SLANG_PRELUDE_EXPORT
145-
void computeMain_Thread(ComputeThreadVaryingInput* varyingInput, void* entryPointParams, void* globalParams)
146-
{
147-
_computeMain(varyingInput, entryPointParams, globalParams);
148-
}
149-
// [numthreads(4, 1, 1)]
150-
SLANG_PRELUDE_EXPORT
151-
void computeMain_Group(ComputeVaryingInput* varyingInput, void* entryPointParams, void* globalParams)
152-
{
153-
ComputeThreadVaryingInput threadInput = {};
154-
threadInput.groupID = varyingInput->startGroupID;
155-
for (uint32_t x = 0; x < 4; ++x)
156-
{
157-
threadInput.groupThreadID.x = x;
158-
_computeMain(&threadInput, entryPointParams, globalParams);
159-
}
160-
}
161-
// [numthreads(4, 1, 1)]
162-
SLANG_PRELUDE_EXPORT
163-
void computeMain(ComputeVaryingInput* varyingInput, void* entryPointParams, void* globalParams)
164-
{
165-
ComputeVaryingInput vi = *varyingInput;
166-
ComputeVaryingInput groupVaryingInput = {};
167-
for (uint32_t z = vi.startGroupID.z; z < vi.endGroupID.z; ++z)
168-
{
169-
groupVaryingInput.startGroupID.z = z;
170-
for (uint32_t y = vi.startGroupID.y; y < vi.endGroupID.y; ++y)
171-
{
172-
groupVaryingInput.startGroupID.y = y;
173-
for (uint32_t x = vi.startGroupID.x; x < vi.endGroupID.x; ++x)
174-
{
175-
groupVaryingInput.startGroupID.x = x;
176-
computeMain_Group(&groupVaryingInput, entryPointParams, globalParams);
177-
}
178-
}
179-
}
180-
}
1+
// This is a placeholder. The contents will be generated during build.

premake5.lua

+23-11
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,14 @@ newoption {
152152
allowed = { { "true", "True"}, { "false", "False" } }
153153
}
154154

155+
newoption {
156+
trigger = "enable-experimental-projects",
157+
description = "(Optional) If true include experimental projects in build.",
158+
value = "bool",
159+
default = "false",
160+
allowed = { { "true", "True"}, { "false", "False" } }
161+
}
162+
155163
buildLocation = _OPTIONS["build-location"]
156164
executeBinary = (_OPTIONS["execute-binary"] == "true")
157165
buildGlslang = (_OPTIONS["build-glslang"] == "true")
@@ -162,7 +170,7 @@ newoption {
162170
enableProfile = (_OPTIONS["enable-profile"] == "true")
163171
enableEmbedStdLib = (_OPTIONS["enable-embed-stdlib"] == "true")
164172
enableXlib = (_OPTIONS["enable-xlib"] == "true")
165-
173+
enableExperimental = (_OPTIONS["enable-experimental-projects"] == "true")
166174
-- Determine the target info
167175

168176
targetInfo = slangUtil.getTargetInfo()
@@ -672,16 +680,20 @@ newoption {
672680
example "cpu-hello-world"
673681
kind "ConsoleApp"
674682

675-
example "heterogeneous-hello-world"
676-
kind "ConsoleApp"
677-
-- Additionally add slangc for compiling shader.cpp
678-
links { "example-base", "slang", "gfx", "gfx-util", "slangc", "platform", "core" }
679-
-- Generate shader.cpp from shader.slang
680-
prebuildmessage ("Generating shader.cpp from shader.slang")
681-
prebuildcommands {
682-
"\"%{wks.location:lower()}/bin/" .. targetName .. "/%{cfg.buildcfg:lower()}/slangc\" \"%{wks.location:lower()}/examples/heterogeneous-hello-world/shader.slang\" -o \"%{wks.location:lower()}/examples/heterogeneous-hello-world/shader.cpp\" -heterogeneous -target cpp -target hlsl"
683-
}
684-
683+
if enableExperimental then
684+
-- TODO: Currently this project doesn't build on linux CI.
685+
-- Need to fix so that we don't check in shader.cpp, which changes
686+
-- everytime when it is generated on a different machine (contains absolute path)
687+
example "heterogeneous-hello-world"
688+
kind "ConsoleApp"
689+
-- Additionally add slangc for compiling shader.cpp
690+
links { "example-base", "slang", "gfx", "gfx-util", "slangc", "platform", "core" }
691+
-- Generate shader.cpp from shader.slang
692+
prebuildmessage ("Generating shader.cpp from shader.slang")
693+
prebuildcommands {
694+
"\"%{wks.location:lower()}/bin/" .. targetName .. "/%{cfg.buildcfg:lower()}/slangc\" \"%{wks.location:lower()}/examples/heterogeneous-hello-world/shader.slang\" -o \"%{wks.location:lower()}/examples/heterogeneous-hello-world/shader.cpp\" -heterogeneous -target cpp -target hlsl"
695+
}
696+
end
685697
-- Most of the other projects have more interesting configuration going
686698
-- on, so let's walk through them in order of increasing complexity.
687699
--

slang.sln

-15
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpu-printing", "build\visua
3131
EndProject
3232
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello-world", "build\visual-studio\hello-world\hello-world.vcxproj", "{010BE414-ED5B-CF56-16C0-BD18027062C0}"
3333
EndProject
34-
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "heterogeneous-hello-world", "build\visual-studio\heterogeneous-hello-world\heterogeneous-hello-world.vcxproj", "{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}"
35-
EndProject
3634
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "model-viewer", "build\visual-studio\model-viewer\model-viewer.vcxproj", "{2F8724C6-1BC3-2730-84D5-3F277030D04A}"
3735
EndProject
3836
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ray-tracing", "build\visual-studio\ray-tracing\ray-tracing.vcxproj", "{71AC0F50-5DFD-FA91-8661-E95372118EFB}"
@@ -241,18 +239,6 @@ Global
241239
{010BE414-ED5B-CF56-16C0-BD18027062C0}.Release|Win32.Build.0 = Release|Win32
242240
{010BE414-ED5B-CF56-16C0-BD18027062C0}.Release|x64.ActiveCfg = Release|x64
243241
{010BE414-ED5B-CF56-16C0-BD18027062C0}.Release|x64.Build.0 = Release|x64
244-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|aarch64.ActiveCfg = Debug aarch64|ARM
245-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|aarch64.Build.0 = Debug aarch64|ARM
246-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|Win32.ActiveCfg = Debug|Win32
247-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|Win32.Build.0 = Debug|Win32
248-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|x64.ActiveCfg = Debug|x64
249-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|x64.Build.0 = Debug|x64
250-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|aarch64.ActiveCfg = Release aarch64|ARM
251-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|aarch64.Build.0 = Release aarch64|ARM
252-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|Win32.ActiveCfg = Release|Win32
253-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|Win32.Build.0 = Release|Win32
254-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|x64.ActiveCfg = Release|x64
255-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|x64.Build.0 = Release|x64
256242
{2F8724C6-1BC3-2730-84D5-3F277030D04A}.Debug|aarch64.ActiveCfg = Debug aarch64|ARM
257243
{2F8724C6-1BC3-2730-84D5-3F277030D04A}.Debug|aarch64.Build.0 = Debug aarch64|ARM
258244
{2F8724C6-1BC3-2730-84D5-3F277030D04A}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -449,7 +435,6 @@ Global
449435
{37BED5B5-23FA-D81F-8C0C-F1167867813A} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
450436
{57C81DD3-4304-213D-AC16-39349871C957} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
451437
{010BE414-ED5B-CF56-16C0-BD18027062C0} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
452-
{150CAA5A-0177-6A66-AA92-CFCB96DC2D49} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
453438
{2F8724C6-1BC3-2730-84D5-3F277030D04A} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
454439
{71AC0F50-5DFD-FA91-8661-E95372118EFB} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
455440
{17BA8E32-034E-84DA-6C12-DE8E58C5BECC} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}

source/slang/slang-diagnostic-defs.h

+2
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,8 @@ DIAGNOSTIC(51090, Error, cannotGenerateCodeForExternComponentType, "cannot gener
545545
DIAGNOSTIC(51091, Error, typeCannotBePlacedInATexture, "type '$0' cannot be placed in a texture.")
546546
DIAGNOSTIC(51092, Error, stageDoesntHaveInputWorld, "'$0' doesn't appear to have any input world")
547547

548+
DIAGNOSTIC(50100, Error, noTypeConformancesFoundForInterface, "No type conformances are found for interface '$0'. Code generation for current target requires at least one implementation type present in the linkage.")
549+
548550
DIAGNOSTIC(52000, Error, multiLevelBreakUnsupported, "control flow appears to require multi-level `break`, which Slang does not yet support")
549551

550552
DIAGNOSTIC(52001, Warning, dxilNotFound, "dxil shared library not found, so 'dxc' output cannot be signed! Shader code will not be runnable in non-development environments.")

source/slang/slang-ir-generics-lowering-context.h

+24
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,28 @@ namespace Slang
103103
// Ptr(RTTIType).
104104
bool isTypeValue(IRInst* typeInst);
105105

106+
template<typename TFunc>
107+
void workOnModule(SharedGenericsLoweringContext* sharedContext, const TFunc& func)
108+
{
109+
SharedIRBuilder* sharedBuilder = &sharedContext->sharedBuilderStorage;
110+
sharedBuilder->module = sharedContext->module;
111+
sharedBuilder->session = sharedContext->module->session;
112+
113+
sharedContext->addToWorkList(sharedContext->module->getModuleInst());
114+
115+
while (sharedContext->workList.getCount() != 0)
116+
{
117+
IRInst* inst = sharedContext->workList.getLast();
118+
119+
sharedContext->workList.removeLast();
120+
sharedContext->workListSet.Remove(inst);
121+
122+
func(inst);
123+
124+
for (auto child = inst->getLastChild(); child; child = child->getPrevInst())
125+
{
126+
sharedContext->addToWorkList(child);
127+
}
128+
}
129+
}
106130
}

source/slang/slang-ir-lower-generics.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,36 @@ namespace Slang
117117
cleanUpInterfaceTypes(sharedContext);
118118
}
119119

120+
void checkTypeConformanceExists(SharedGenericsLoweringContext* context)
121+
{
122+
HashSet<IRInst*> implementedInterfaces;
123+
124+
// Add all interface type that are implemented by at least one type to a set.
125+
for (auto inst : context->module->getGlobalInsts())
126+
{
127+
if (inst->getOp() == kIROp_WitnessTable)
128+
{
129+
auto interfaceType = cast<IRWitnessTableType>(inst->getDataType())->getConformanceType();
130+
implementedInterfaces.Add(interfaceType);
131+
}
132+
}
133+
// Check if an interface type has any implementations.
134+
workOnModule(context, [&](IRInst* inst)
135+
{
136+
if (auto lookupWitnessMethod = as<IRLookupWitnessMethod>(inst))
137+
{
138+
auto witnessTableType = lookupWitnessMethod->getWitnessTable()->getDataType();
139+
auto interfaceType = cast<IRWitnessTableType>(witnessTableType)->getConformanceType();
140+
if (!implementedInterfaces.Contains(interfaceType))
141+
{
142+
context->sink->diagnose(interfaceType->sourceLoc, Diagnostics::noTypeConformancesFoundForInterface, interfaceType);
143+
// Add to set to prevent duplicate diagnostic messages.
144+
implementedInterfaces.Add(interfaceType);
145+
}
146+
}
147+
});
148+
}
149+
120150
void lowerGenerics(
121151
TargetRequest* targetReq,
122152
IRModule* module,
@@ -127,6 +157,8 @@ namespace Slang
127157
sharedContext.module = module;
128158
sharedContext.sink = sink;
129159

160+
checkTypeConformanceExists(&sharedContext);
161+
130162
// Replace all `makeExistential` insts with `makeExistentialWithRTTI`
131163
// before making any other changes. This is necessary because a parameter of
132164
// generic type will be lowered into `AnyValueType`, and after that we can no longer

0 commit comments

Comments
 (0)