Skip to content

Commit 316afc5

Browse files
PawelJurekigcbot
authored andcommitted
Automatic detection of SPMD, ESIMD and SPMD+ESIMD SPIR-V modules
Before this change there were 3 paths of SPIR-V compilation: 1. If -vc-codegen option was passed, further translation was passed to VC codegen 2. If -spmd_esimd_compile was passed, vISA Linker Driver was invoked to split the module and dispatch the separate SPIR-V modules to SPMD and ESIMD (VC) backends. 3. If no option was provided, SPMD backend was invoked. This change introduces automatic ESIMD module detection - user can now pass ESIMD module without providing -vc-codegen option. Current flow is: 1. If no option is provided, detection algorithm is invoked and the SPIR-V module is directed to detected backend. 2. If -vc-codegen option is provided, VC backend is chosen without invoking the detection code. 3. There is no -spmd_esimd_compile option, so SPMD+ESIMD path is chosen after detection. Currently module is marked as ESIMD only, if there is an entry point marked with VectorComputeFunctionINTEL decoration. This is forbidden in SPMD module and SPMD+ESIMD module.
1 parent b66f7c1 commit 316afc5

File tree

6 files changed

+232
-80
lines changed

6 files changed

+232
-80
lines changed

IGC/AdaptorOCL/dllInterfaceCompute.cpp

Lines changed: 80 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -919,53 +919,12 @@ static void WriteSpecConstantsDump(const STB_TranslateInputArgs *pInputArgs,
919919
hash, "_specconst.txt");
920920
}
921921

922-
bool TranslateBuild(
923-
const STB_TranslateInputArgs* pInputArgs,
924-
STB_TranslateOutputArgs* pOutputArgs,
925-
TB_DATA_FORMAT inputDataFormatTemp,
926-
const IGC::CPlatform& IGCPlatform,
927-
float profilingTimerResolution)
928-
{
929-
ShaderHash inputShHash = ShaderHashOCL(reinterpret_cast<const UINT *>(pInputArgs->pInput),
930-
pInputArgs->InputSize / 4);
931-
932-
// on wrong spec constants, vc::translateBuild may fail
933-
// so lets dump those early
934-
if (pInputArgs->SpecConstantsSize > 0 &&
935-
IGC_IS_FLAG_ENABLED(ShaderDumpEnable))
936-
WriteSpecConstantsDump(pInputArgs, inputShHash.getAsmHash());
937-
938-
#if defined(IGC_VC_ENABLED)
939-
if (pInputArgs->pOptions) {
940-
// Currently, VC compiler effectively uses global variables to store
941-
// some configuration information. This may lead to problems
942-
// during multi-threaded compilations. The mutex below serializes
943-
// the whole compilation process.
944-
// This is a temporary measure till a proper re-design is done.
945-
const std::lock_guard<std::mutex> lock(llvm_mutex);
946-
947-
std::error_code Status =
948-
vc::translateBuild(pInputArgs, pOutputArgs, inputDataFormatTemp,
949-
IGCPlatform, profilingTimerResolution);
950-
if (!Status)
951-
return true;
952-
// If vc codegen option was not specified, then vc was not called.
953-
if (static_cast<vc::errc>(Status.value()) != vc::errc::not_vc_codegen)
954-
return false;
955-
}
956-
#endif // defined(IGC_VC_ENABLED)
957-
if (pInputArgs->pOptions &&
958-
strstr(pInputArgs->pOptions,
959-
VLD::VLD_compilation_enable_option)) {
960-
std::string errorMessage;
961-
bool ret = VLD::TranslateBuildSPMDAndESIMD(
962-
pInputArgs, pOutputArgs, inputDataFormatTemp, IGCPlatform,
963-
profilingTimerResolution, inputShHash, errorMessage);
964-
if (!ret) {
965-
SetErrorMessage(errorMessage, *pOutputArgs);
966-
}
967-
return ret;
968-
}
922+
bool TranslateBuildSPMD(const STB_TranslateInputArgs *pInputArgs,
923+
STB_TranslateOutputArgs *pOutputArgs,
924+
TB_DATA_FORMAT inputDataFormatTemp,
925+
const IGC::CPlatform &IGCPlatform,
926+
float profilingTimerResolution,
927+
const ShaderHash& inputShHash) {
969928

970929
// This part of code is a critical-section for threads,
971930
// due static LLVM object which handles options.
@@ -1372,6 +1331,80 @@ bool TranslateBuild(
13721331
return true;
13731332
}
13741333

1334+
1335+
#if defined(IGC_VC_ENABLED)
1336+
bool TranslateBuildESIMD(
1337+
const STB_TranslateInputArgs* pInputArgs,
1338+
STB_TranslateOutputArgs* pOutputArgs,
1339+
TB_DATA_FORMAT inputDataFormatTemp,
1340+
const IGC::CPlatform& IGCPlatform,
1341+
float profilingTimerResolution,
1342+
const ShaderHash& inputShHash) {
1343+
1344+
IGC_ASSERT(pInputArgs->pOptions &&
1345+
(strstr(pInputArgs->pOptions, "-vc-codegen") ||
1346+
strstr(pInputArgs->pOptions, "-cmc")));
1347+
1348+
// Currently, VC compiler effectively uses global variables to store
1349+
// some configuration information. This may lead to problems
1350+
// during multi-threaded compilations. The mutex below serializes
1351+
// the whole compilation process.
1352+
// This is a temporary measure till a proper re-design is done.
1353+
const std::lock_guard<std::mutex> lock(llvm_mutex);
1354+
1355+
std::error_code Status =
1356+
vc::translateBuild(pInputArgs, pOutputArgs, inputDataFormatTemp,
1357+
IGCPlatform, profilingTimerResolution);
1358+
if (!Status)
1359+
return true;
1360+
return false;
1361+
}
1362+
#endif // defined(IGC_VC_ENABLED)
1363+
1364+
bool TranslateBuild(
1365+
const STB_TranslateInputArgs* pInputArgs,
1366+
STB_TranslateOutputArgs* pOutputArgs,
1367+
TB_DATA_FORMAT inputDataFormatTemp,
1368+
const IGC::CPlatform& IGCPlatform,
1369+
float profilingTimerResolution)
1370+
{
1371+
ShaderHash inputShHash = ShaderHashOCL(reinterpret_cast<const UINT *>(pInputArgs->pInput),
1372+
pInputArgs->InputSize / 4);
1373+
1374+
// on wrong spec constants, vc::translateBuild may fail
1375+
// so lets dump those early
1376+
if (pInputArgs->SpecConstantsSize > 0 &&
1377+
IGC_IS_FLAG_ENABLED(ShaderDumpEnable))
1378+
WriteSpecConstantsDump(pInputArgs, inputShHash.getAsmHash());
1379+
1380+
#if defined(IGC_VC_ENABLED)
1381+
// if VC option was specified, go to ESIMD compilation directly.
1382+
if (pInputArgs->pOptions && (strstr(pInputArgs->pOptions, "-vc-codegen") ||
1383+
strstr(pInputArgs->pOptions, "-cmc"))) {
1384+
return TranslateBuildESIMD(pInputArgs, pOutputArgs, inputDataFormatTemp,
1385+
IGCPlatform, profilingTimerResolution,
1386+
inputShHash);
1387+
}
1388+
#endif // defined(IGC_VC_ENABLED)
1389+
1390+
if (inputDataFormatTemp != TB_DATA_FORMAT_SPIR_V) {
1391+
return TranslateBuildSPMD(pInputArgs, pOutputArgs, inputDataFormatTemp,
1392+
IGCPlatform, profilingTimerResolution,
1393+
inputShHash);
1394+
}
1395+
1396+
// Recognize if SPIR-V module contains SPMD,ESIMD or SPMD+ESIMD code and compile it.
1397+
std::string errorMessage;
1398+
bool ret = VLD::TranslateBuildSPMDAndESIMD(
1399+
pInputArgs, pOutputArgs, inputDataFormatTemp, IGCPlatform,
1400+
profilingTimerResolution, inputShHash, errorMessage);
1401+
if (!ret) {
1402+
SetErrorMessage(errorMessage, *pOutputArgs);
1403+
}
1404+
return ret;
1405+
1406+
}
1407+
13751408
bool CIGCTranslationBlock::FreeAllocations(
13761409
STB_TranslateOutputArgs* pOutputArgs)
13771410
{

IGC/AdaptorOCL/ocl_igc_interface/impl/igc_ocl_translation_ctx_impl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,22 @@ bool TranslateBuild(
4747
const IGC::CPlatform &platform,
4848
float profilingTimerResolution);
4949

50+
bool TranslateBuildSPMD(
51+
const STB_TranslateInputArgs* pInputArgs,
52+
STB_TranslateOutputArgs* pOutputArgs,
53+
TB_DATA_FORMAT inputDataFormatTemp,
54+
const IGC::CPlatform &platform,
55+
float profilingTimerResolution,
56+
const ShaderHash& inputShHash);
57+
58+
bool TranslateBuildESIMD(
59+
const STB_TranslateInputArgs* pInputArgs,
60+
STB_TranslateOutputArgs* pOutputArgs,
61+
TB_DATA_FORMAT inputDataFormatTemp,
62+
const IGC::CPlatform &platform,
63+
float profilingTimerResolution,
64+
const ShaderHash& inputShHash);
65+
5066
bool ReadSpecConstantsFromSPIRV(
5167
std::istream &IS,
5268
std::vector<std::pair<uint32_t, uint32_t>> &OutSCInfo);

IGC/VISALinkerDriver/VLD.cpp

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,24 @@ namespace VLD {
7474
using namespace TC;
7575

7676

77-
// Translates SPIR-V module that consists of SPMD code that invokes ESIMD code.
77+
// Translates ESIMD and SPMD code in the module.
78+
// 3 cases are handled:
79+
// 1. only SPMD code is present
80+
// 2. only ESIMD code is present
81+
// 3. ESIMD code is invoked from SPMD code
82+
//
7883
// The general flow is:
7984
// 1. Split input SPIR-V module into SPMD and ESIMD parts
8085
// 2. Invoke SPMD and ESIMD backends with appropriate SPIR-V modules
81-
// 3. Extract .visaasm from the output zeBinary
86+
// 3. If SPMD code invokes ESIMD code, extract .visaasm from the each output zeBinary
8287
// TODO: 4. Link .visaasm files via vISA interfaces
8388
//
8489
// The function signature corresponds to TC::TranslateBuild interface, so that
8590
// it is easy to pass same arguments to SPMD and VC backends.
8691
//
8792
// Assumptions:
88-
// 1. ZEBinary output format is used.
93+
// 1. ZEBinary output format is used in SPMD+ESIMD case.
8994
// TODO: error out if patch token output format is used.
90-
// 2. Input is in SPIR-V format
91-
// TODO: error out if other input format is used.
9295
bool TranslateBuildSPMDAndESIMD(const TC::STB_TranslateInputArgs *pInputArgs,
9396
TC::STB_TranslateOutputArgs *pOutputArgs,
9497
TC::TB_DATA_FORMAT inputDataFormatTemp,
@@ -97,19 +100,54 @@ bool TranslateBuildSPMDAndESIMD(const TC::STB_TranslateInputArgs *pInputArgs,
97100
const ShaderHash &inputShHash,
98101
std::string& errorMessage) {
99102

103+
IGC_ASSERT(inputDataFormatTemp == TB_DATA_FORMAT_SPIR_V);
104+
100105
// Split ESIMD and SPMD code.
101106
auto spmd_esimd_programs_or_err = VLD::SplitSPMDAndESIMD(
102107
pInputArgs->pInput, pInputArgs->InputSize);
103108

104109
if (!spmd_esimd_programs_or_err) {
105-
// Caller releases the error string, so we need to make a copy of the error message here.
106-
// TODO: pOutputArgs contains field for error string so we can copy it there.
107-
// Not done now, as it would require copy-paste code that is avaiable in dllinterfacecompute. Needs to be refactored.
108-
errorMessage = "Error while splitting ESIMD and SPMD code: " +
109-
llvm::toString(spmd_esimd_programs_or_err.takeError());
110-
return false;
110+
// Workaround: try to compile on SPMD path if splitting failed.
111+
// This is because not all VC opcodes are merged to SPIR-V Tools.
112+
return TranslateBuildSPMD(pInputArgs, pOutputArgs, inputDataFormatTemp,
113+
IGCPlatform, profilingTimerResolution,
114+
inputShHash);
115+
116+
// TODO: uncomment once above workaround is removed.
117+
// Caller releases the error string, so we need to make a copy of the error message here.
118+
// TODO: pOutputArgs contains field for error string so we can copy it there.
119+
// Not done now, as it would require copy-paste code that is avaiable in dllinterfacecompute. Needs to be refactored.
120+
// errorMessage = llvm::toString(spmd_esimd_programs_or_err.takeError());
121+
// return false;
111122
}
112123

124+
std::string newOptions{pInputArgs->pOptions ? pInputArgs->pOptions : ""};
125+
std::string esimdOptions{ newOptions };
126+
esimdOptions += " -vc-codegen";
127+
128+
IGC_ASSERT(!spmd_esimd_programs_or_err->first.empty() || !spmd_esimd_programs_or_err->second.empty());
129+
if (spmd_esimd_programs_or_err->first.empty()) {
130+
#if defined(IGC_VC_ENABLED)
131+
// Only ESIMD code detected.
132+
STB_TranslateInputArgs newArgs = *pInputArgs;
133+
newArgs.pOptions = esimdOptions.data();
134+
newArgs.OptionsSize = esimdOptions.size();
135+
return TranslateBuildESIMD(&newArgs, pOutputArgs, inputDataFormatTemp,
136+
IGCPlatform, profilingTimerResolution,
137+
inputShHash);
138+
#else // defined(IGC_VC_ENABLED)
139+
errorMessage = "ESIMD code detected, but VC not enabled in this build.";
140+
return false;
141+
#endif // defined(IGC_VC_ENABLED)
142+
} else if (spmd_esimd_programs_or_err->second.empty()) {
143+
// Only SPMD code detected.
144+
return TranslateBuildSPMD(pInputArgs, pOutputArgs, inputDataFormatTemp,
145+
IGCPlatform, profilingTimerResolution,
146+
inputShHash);
147+
}
148+
149+
// SPMD+ESIMD code detected.
150+
113151
if (IGC_IS_FLAG_ENABLED(ShaderDumpEnable)) {
114152
const char* pOutputFolder = IGC::Debug::GetShaderOutputFolder();
115153

@@ -134,27 +172,24 @@ bool TranslateBuildSPMDAndESIMD(const TC::STB_TranslateInputArgs *pInputArgs,
134172
dump((*spmd_esimd_programs_or_err).second, ".esimd_split.spv");
135173
}
136174

137-
std::string newOptions{pInputArgs->pOptions};
138-
IGC_ASSERT(newOptions.find(VLD_compilation_enable_option) !=
139-
std::string::npos);
140-
newOptions.erase(newOptions.find(VLD_compilation_enable_option),
141-
strnlen(VLD_compilation_enable_option, sizeof(VLD_compilation_enable_option)));
142-
143175
auto translateToVISA =
144176
[&](VLD::ProgramStreamType& program,
145-
const char *newOptions) -> decltype(GetVISAAsmFromZEBinary(0,0)) {
177+
const std::string& newOptions,
178+
decltype(TranslateBuildSPMD) TranslateFunction
179+
) -> decltype(GetVISAAsmFromZEBinary(0,0)) {
146180
STB_TranslateInputArgs newArgs = *pInputArgs;
147181

148182
TC::STB_TranslateOutputArgs outputArgs;
149183
CIF::SafeZeroOut(outputArgs);
150184

151185
newArgs.pInput = reinterpret_cast<char*>(program.data());
152186
newArgs.InputSize = program.size() * sizeof(*program.begin());;
153-
newArgs.pOptions = newOptions;
187+
newArgs.pOptions = newOptions.data();
188+
newArgs.OptionsSize = newOptions.size();
154189

155190
const bool success =
156-
TranslateBuild(&newArgs, &outputArgs, inputDataFormatTemp,
157-
IGCPlatform, profilingTimerResolution);
191+
TranslateFunction(&newArgs, &outputArgs, inputDataFormatTemp,
192+
IGCPlatform, profilingTimerResolution, inputShHash);
158193

159194
auto outputData = std::unique_ptr<char[]>(outputArgs.pOutput);
160195
auto errorString = std::unique_ptr<char[]>(outputArgs.pErrorString);
@@ -170,20 +205,22 @@ bool TranslateBuildSPMDAndESIMD(const TC::STB_TranslateInputArgs *pInputArgs,
170205
return spmdVISAAsmVector;
171206
};
172207

173-
std::string esimdOptions{ newOptions };
174-
esimdOptions += " -vc-codegen";
175-
208+
#if defined(IGC_VC_ENABLED)
176209
auto esimdVISA =
177-
translateToVISA(spmd_esimd_programs_or_err->second, esimdOptions.data());
210+
translateToVISA(spmd_esimd_programs_or_err->second, esimdOptions, TranslateBuildESIMD);
178211

179212
if (!esimdVISA) {
180213
errorMessage = "VLD: Failed to compile ESIMD part with following error: \n" +
181214
llvm::toString(esimdVISA.takeError());
182215
return false;
183216
}
217+
#else // defined(IGC_VC_ENABLED)
218+
errorMessage = "Could not compile ESIMD part of SPIR-V module, as VC is not included in this build.";
219+
return false;
220+
#endif // defined(IGC_VC_ENABLED)
184221

185222
auto spmdVISA =
186-
translateToVISA(spmd_esimd_programs_or_err->first, newOptions.data());
223+
translateToVISA(spmd_esimd_programs_or_err->first, newOptions.data(), TranslateBuildSPMD);
187224

188225
if (!spmdVISA) {
189226
errorMessage = "VLD: Failed to compile SPMD part with following error: \n" +

IGC/VISALinkerDriver/VLD.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ namespace IGC {
2121
namespace IGC {
2222
namespace VLD {
2323

24-
// Option that must be passed to enable VLD path
25-
static const char VLD_compilation_enable_option[] = "-spmd_esimd_compile";
26-
2724
bool TranslateBuildSPMDAndESIMD(const TC::STB_TranslateInputArgs* pInputArgs,
2825
TC::STB_TranslateOutputArgs* pOutputArgs,
2926
TC::TB_DATA_FORMAT inputDataFormatTemp,

0 commit comments

Comments
 (0)