From e1ea7ed2f9b8cfcf19258a05d270de4db03fec22 Mon Sep 17 00:00:00 2001 From: Dietrich Geisler Date: Wed, 12 Aug 2020 13:39:08 -0400 Subject: GPU Foreach Parsing and Checking (#1482) This PR introduces parsing and semantic checking for a GPU foreach loop for heterogeneouis programming. A GPU foreach loop takes the form: ``` __GPU_FOREACH(renderer, gridDims, LAMBDA(uint3 dispatchThreadID) { kernelCall(args, ...); }); ``` And will allow the host code to call into a kernel with the correct renderer and grid dimensions. This commit also introduces a hack to unify types in the heterogeneous hello world file, which will hopefully be amended in the future. Co-authored-by: Tim Foley --- source/slang/slang-parser.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'source/slang/slang-parser.cpp') diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 460f781fe..179587550 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -3380,6 +3380,56 @@ namespace Slang return stmt; } + GpuForeachStmt* ParseGpuForeachStmt(Parser* parser) + { + // Hard-coding parsing of the following: + // __GPU_FOREACH(renderer, gridDims, LAMBDA(uint3 dispatchThreadID) { + // kernelCall(args, ...); }); + + // Setup the scope so that dispatchThreadID is in scope for kernelCall + ScopeDecl* scopeDecl = parser->astBuilder->create(); + GpuForeachStmt* stmt = parser->astBuilder->create(); + stmt->scopeDecl = scopeDecl; + + parser->FillPosition(stmt); + parser->ReadToken("__GPU_FOREACH"); + parser->ReadToken(TokenType::LParent); + stmt->renderer = parser->ParseArgExpr(); + parser->ReadToken(TokenType::Comma); + stmt->gridDims = parser->ParseArgExpr(); + + parser->ReadToken(TokenType::Comma); + parser->ReadToken("LAMBDA"); + parser->ReadToken(TokenType::LParent); + + auto idType = parser->ParseTypeExp(); + NameLoc varNameAndLoc = expectIdentifier(parser); + VarDecl* varDecl = parser->astBuilder->create(); + varDecl->nameAndLoc = varNameAndLoc; + varDecl->loc = varNameAndLoc.loc; + varDecl->type = idType; + stmt->dispatchThreadID = varDecl; + + parser->ReadToken(TokenType::RParent); + parser->ReadToken(TokenType::LBrace); + + parser->pushScopeAndSetParent(scopeDecl); + AddMember(parser->currentScope, varDecl); + + stmt->kernelCall = parser->ParseExpression(); + + parser->PopScope(); + + parser->ReadToken(TokenType::Semicolon); + parser->ReadToken(TokenType::RBrace); + + parser->ReadToken(TokenType::RParent); + + parser->ReadToken(TokenType::Semicolon); + + return stmt; + } + static bool _isType(Decl* decl) { return decl && (as(decl) || as(decl)); @@ -3552,6 +3602,8 @@ namespace Slang statement = ParseCaseStmt(this); else if (LookAheadToken("default")) statement = ParseDefaultStmt(this); + else if (LookAheadToken("__GPU_FOREACH")) + statement = ParseGpuForeachStmt(this); else if (LookAheadToken(TokenType::Dollar)) { statement = parseCompileTimeStmt(this); -- cgit v1.2.3