Skip to content

Commit

Permalink
Open-source whole Vector Compute backend
Browse files Browse the repository at this point in the history
Change-Id: Id22b13722d4c79f70e4b0d1629510526d8dcf2e2
  • Loading branch information
kvladimi authored and sys_zuul committed Jul 7, 2020
1 parent b5e1a28 commit 3fdb587
Show file tree
Hide file tree
Showing 147 changed files with 74,118 additions and 0 deletions.
144 changes: 144 additions & 0 deletions IGC/AdaptorOCL/cmc.cpp
Expand Up @@ -611,3 +611,147 @@ int cmc::vISACompile_v2(cmc_compile_info_v2* output, iOpenCL::CGen8CMProgram& CM
CMProgram.CreateKernelBinaries();
return status;
}

static void getCmcArg(cmc_arg_info& CmcArg, const vc::ocl::ArgInfo& Arg)
{
switch (Arg.Kind)
{
case vc::ocl::ArgKind::General:
CmcArg.kind = cmc_arg_kind::General;
break;
case vc::ocl::ArgKind::LocalSize:
CmcArg.kind = cmc_arg_kind::LocalSize;
break;
case vc::ocl::ArgKind::GroupCount:
CmcArg.kind = cmc_arg_kind::GroupCount;
break;
case vc::ocl::ArgKind::Buffer:
CmcArg.kind = cmc_arg_kind::Buffer;
break;
case vc::ocl::ArgKind::SVM:
CmcArg.kind = cmc_arg_kind::SVM;
break;
case vc::ocl::ArgKind::Sampler:
CmcArg.kind = cmc_arg_kind::Sampler;
break;
case vc::ocl::ArgKind::Image1d:
CmcArg.kind = cmc_arg_kind::Image1d;
break;
case vc::ocl::ArgKind::Image2d:
CmcArg.kind = cmc_arg_kind::Image2d;
break;
case vc::ocl::ArgKind::Image3d:
CmcArg.kind = cmc_arg_kind::Image3d;
break;
case vc::ocl::ArgKind::PrintBuffer:
CmcArg.kind = cmc_arg_kind::PrintBuffer;
break;
case vc::ocl::ArgKind::PrivateBase:
CmcArg.kind = cmc_arg_kind::PrivateBase;
break;
}

switch (Arg.AccessKind)
{
case vc::ocl::ArgAccessKind::None:
CmcArg.access = cmc_access_kind::undef;
break;
case vc::ocl::ArgAccessKind::ReadOnly:
CmcArg.access = cmc_access_kind::read_only;
break;
case vc::ocl::ArgAccessKind::WriteOnly:
CmcArg.access = cmc_access_kind::write_only;
break;
case vc::ocl::ArgAccessKind::ReadWrite:
CmcArg.access = cmc_access_kind::read_write;
break;
}

CmcArg.index = Arg.Index;
CmcArg.offset = Arg.Offset;
CmcArg.sizeInBytes = Arg.SizeInBytes;
CmcArg.BTI = Arg.BTI;
}

// Returns vector of cmc_arg_info with all fields initialized.
static std::vector<cmc_arg_info> getCmcArgInfos(const std::vector<vc::ocl::ArgInfo>& Args)
{
std::vector<cmc_arg_info> CmcArgs{Args.size()};
for (unsigned i = 0, e = Args.size(); i != e; ++i)
getCmcArg(CmcArgs[i], Args[i]);
return CmcArgs;
}

static std::vector<cmc_ocl_print_string> getCmcPrintStrings(
const std::vector<std::string>& Original)
{
std::vector<cmc_ocl_print_string> Converted;
std::transform(Original.begin(), Original.end(), std::back_inserter(Converted),
[](const std::string &str) {
IGC_ASSERT_MESSAGE(str.size() < cmc_ocl_print_string::max_width, "illegal string length");
cmc_ocl_print_string Tmp;
strcpy_s(Tmp.s, cmc_ocl_print_string::max_width, str.c_str());
return Tmp;
});
return Converted;
}

struct CmcContext
{
std::vector<cmc_arg_info> Args;
std::vector<cmc_ocl_print_string> PrintStrings;
};

// Fills non-owning cmc_kernel_info with all fields initialized.
static void getCmcKernelInfo(
cmc_kernel_info_v2& CmcInfo,
const vc::ocl::KernelInfo& Info,
const FINALIZER_INFO& JitInfo,
CmcContext& CmcCtx)
{
IGC_ASSERT_MESSAGE(CmcCtx.PrintStrings.size() == Info.PrintStrings.size(), "inconsistent arguments");
CmcInfo.name = Info.Name.c_str();
CmcInfo.num_args = CmcCtx.Args.size();
CmcInfo.arg_descs = CmcCtx.Args.data();
CmcInfo.HasLocalIDx = true;
CmcInfo.HasLocalIDy = true;
CmcInfo.HasLocalIDz = true;
CmcInfo.HasGroupID = Info.HasGroupID;
CmcInfo.CompiledSIMDSize = 1;
CmcInfo.SLMSize = Info.SLMSize;
CmcInfo.NumGRFRequired = JitInfo.numGRFTotal;
CmcInfo.GRFByteSize = Info.GRFSizeInBytes;
CmcInfo.HasBarriers = Info.HasBarriers;
CmcInfo.StatelessPrivateMemSize = Info.StatelessPrivateMemSize;
CmcInfo.HasReadWriteImages = Info.HasReadWriteImages;
CmcInfo.num_print_strings = CmcCtx.PrintStrings.size();
CmcInfo.print_string_descs = CmcCtx.PrintStrings.data();
// std::copy requires either reinteprets or implementation of operator= in
// TableInfos from independent headers so memcpy seems to be the best option
// for now
memcpy_s(&CmcInfo.RelocationTable, sizeof(Info.RelocationTable), &Info.RelocationTable,
sizeof(Info.RelocationTable));
memcpy_s(&CmcInfo.SymbolTable, sizeof(Info.SymbolTable), &Info.SymbolTable,
sizeof(Info.SymbolTable));
}

void vc::createBinary(
iOpenCL::CGen8CMProgram& CMProgram,
const std::vector<vc::ocl::CompileInfo>& CompileInfos)
{
cmc_kernel_info_v2 CmcInfo;
CmcContext CmcCtx;
for (const vc::ocl::CompileInfo& Info : CompileInfos)
{
CmcCtx.Args = getCmcArgInfos(Info.KernelInfo.Args);
CmcCtx.PrintStrings = getCmcPrintStrings(Info.KernelInfo.PrintStrings);
getCmcKernelInfo(CmcInfo, Info.KernelInfo, Info.JitInfo, CmcCtx);
CMKernel* K = new CMKernel(CMProgram.getPlatform());
CMProgram.m_kernels.push_back(K);
llvm::ArrayRef<uint8_t> GenBin{
reinterpret_cast<const uint8_t*>(Info.GenBinary.data()),
Info.GenBinary.size()};
populateKernelInfo_v2(&CmcInfo, Info.JitInfo, GenBin, *K);
}
CMProgram.CreateKernelBinaries();
}
8 changes: 8 additions & 0 deletions IGC/AdaptorOCL/cmc.h
Expand Up @@ -35,6 +35,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "igcmc.h"
#include "Compiler/CodeGenPublic.h"
#include "common/LLVMWarningsPush.hpp"
#include "VectorCompiler/include/vc/GenXCodeGen/GenXWrapper.h"
#include "common/LLVMWarningsPop.hpp"

namespace iOpenCL {
class CGen8CMProgram;
Expand Down Expand Up @@ -111,3 +114,8 @@ extern int vISACompile_v2(cmc_compile_info_v2 *output,
extern const char* getPlatformStr(PLATFORM platform);

} // namespace cmc

namespace vc {
void createBinary(iOpenCL::CGen8CMProgram &CMProgram,
const std::vector<vc::ocl::CompileInfo> &CompileInfos);
} // namespace vc
150 changes: 150 additions & 0 deletions IGC/AdaptorOCL/dllInterfaceCompute.cpp
Expand Up @@ -55,6 +55,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "AdaptorOCL/OCL/sp/gtpin_igc_ocl.h"
#include "AdaptorOCL/igcmc.h"
#include "AdaptorOCL/cmc.h"
#include "common/LLVMWarningsPush.hpp"
#include <llvm/ADT/ScopeExit.h>
#include "VectorCompiler/include/vc/Support/StatusCode.h"
#include "VectorCompiler/include/vc/GenXCodeGen/GenXWrapper.h"
#include "common/LLVMWarningsPop.hpp"

#include <iStdLib/MemCopy.h>

Expand Down Expand Up @@ -820,6 +825,14 @@ static bool TranslateBuildCM(const STB_TranslateInputArgs* pInputArgs,
const IGC::CPlatform& IGCPlatform,
float profilingTimerResolution);

#if !defined(WDDM_LINUX)
static std::error_code TranslateBuildVC(
const STB_TranslateInputArgs* pInputArgs,
STB_TranslateOutputArgs* pOutputArgs, TB_DATA_FORMAT inputDataFormatTemp,
const IGC::CPlatform& IGCPlatform, float profilingTimerResolution);
#endif // !defined(WDDM_LINUX)


bool TranslateBuild(
const STB_TranslateInputArgs* pInputArgs,
STB_TranslateOutputArgs* pOutputArgs,
Expand All @@ -828,6 +841,16 @@ bool TranslateBuild(
float profilingTimerResolution)
{
if (pInputArgs->pOptions) {
#if !defined(WDDM_LINUX)
std::error_code Status =
TranslateBuildVC(pInputArgs, pOutputArgs, inputDataFormatTemp,
IGCPlatform, profilingTimerResolution);
if (!Status)
return true;
// If vc codegen option was not specified, then vc was not called.
if (static_cast<vc::errc>(Status.value()) != vc::errc::not_vc_codegen)
return false;
#endif // !defined(WDDM_LINUX)
static const char* CMC = "-cmc";
if (strstr(pInputArgs->pOptions, CMC) != nullptr)
return TranslateBuildCM(pInputArgs,
Expand Down Expand Up @@ -1438,4 +1461,131 @@ static bool TranslateBuildCM(const STB_TranslateInputArgs* pInputArgs,
return false;
}

#if !defined(WDDM_LINUX)

static void adjustPlatformVC(const IGC::CPlatform& IGCPlatform,
vc::CompileOptions& Opts)
{
Opts.CPUStr = cmc::getPlatformStr(IGCPlatform.getPlatformInfo());
Opts.WATable = std::make_unique<WA_TABLE>(IGCPlatform.getWATable());
}

static void adjustFileTypeVC(TB_DATA_FORMAT DataFormat,
vc::CompileOptions& Opts)
{
switch (DataFormat)
{
case TB_DATA_FORMAT::TB_DATA_FORMAT_SPIR_V:
Opts.FType = vc::FileType::SPIRV;
return;
default:
llvm_unreachable("Data format is not supported yet");
}
}

static void adjustOptLevelVC(vc::CompileOptions& Opts)
{
if (IGC_IS_FLAG_ENABLED(VCOptimizeNone))
Opts.OptLevel = vc::OptimizerLevel::None;
}

static void adjustOptionsVC(const IGC::CPlatform& IGCPlatform,
TB_DATA_FORMAT DataFormat, vc::CompileOptions& Opts)
{
adjustPlatformVC(IGCPlatform, Opts);
adjustFileTypeVC(DataFormat, Opts);
adjustOptLevelVC(Opts);
}

static std::error_code getErrorVC(llvm::Error Err,
STB_TranslateOutputArgs* pOutputArgs)
{
std::error_code Status;
llvm::handleAllErrors(
std::move(Err), [&Status, pOutputArgs](const llvm::ErrorInfoBase& EI) {
Status = EI.convertToErrorCode();
// Some tests check for build log when everything is ok.
// So let's not even try to touch things if we were not called.
if (static_cast<vc::errc>(Status.value()) == vc::errc::not_vc_codegen)
return;
SetErrorMessage(EI.message(), *pOutputArgs);
});
return Status;
}

static void outputBinaryVC(llvm::StringRef Binary,
STB_TranslateOutputArgs* pOutputArgs)
{
size_t BinarySize = static_cast<size_t>(Binary.size());
char* pBinaryOutput = new char[BinarySize];
memcpy_s(pBinaryOutput, BinarySize, Binary.data(), BinarySize);
pOutputArgs->OutputSize = static_cast<uint32_t>(BinarySize);
pOutputArgs->pOutput = pBinaryOutput;
}

static std::error_code TranslateBuildVC(
const STB_TranslateInputArgs* pInputArgs,
STB_TranslateOutputArgs* pOutputArgs, TB_DATA_FORMAT inputDataFormatTemp,
const IGC::CPlatform& IGCPlatform, float profilingTimerResolution)
{
#if IGC_VC_DISABLED
SetErrorMessage("IGC VC explicitly disabled in build", *pOutputArgs);
return false;
#else

llvm::StringRef ApiOptions{pInputArgs->pOptions, pInputArgs->OptionsSize};
llvm::StringRef InternalOptions{pInputArgs->pInternalOptions,
pInputArgs->InternalOptionsSize};
auto pInput = pInputArgs->pInput;
size_t InputSize = pInputArgs->InputSize;


auto ExpOptions = vc::ParseOptions(ApiOptions, InternalOptions);
if (!ExpOptions)
return getErrorVC(ExpOptions.takeError(), pOutputArgs);

// Reset options when everything is done here.
// This is needed to not interfere with subsequent translations.
const auto ClOptGuard =
llvm::make_scope_exit([]() { llvm::cl::ResetAllOptionOccurrences(); });

vc::CompileOptions& Opts = ExpOptions.get();
adjustOptionsVC(IGCPlatform, inputDataFormatTemp, Opts);

llvm::ArrayRef<char> Input{pInput, InputSize};
auto ExpOutput = vc::Compile(Input, Opts);
if (!ExpOutput)
return getErrorVC(ExpOutput.takeError(), pOutputArgs);
vc::CompileOutput& Res = ExpOutput.get();

auto Visitor = [&IGCPlatform, pOutputArgs](auto&& CompileResult) {
using Ty = std::decay_t<decltype(CompileResult)>;
if constexpr (std::is_same_v<Ty, vc::cm::CompileOutput>)
{
outputBinaryVC(CompileResult.IsaBinary, pOutputArgs);
}
else if constexpr (std::is_same_v<Ty, vc::ocl::CompileOutput>)
{
iOpenCL::CGen8CMProgram CMProgram{IGCPlatform.getPlatformInfo()};
vc::createBinary(CMProgram, CompileResult.Kernels);
Util::BinaryStream ProgramBinary;
CMProgram.GetProgramBinary(ProgramBinary,
CompileResult.PointerSizeInBytes);
llvm::StringRef BinaryRef(ProgramBinary.GetLinearPointer(),
ProgramBinary.Size());
outputBinaryVC(BinaryRef, pOutputArgs);
}
else
{
static_assert(!sizeof(Ty), "One of compile output is not visited");
}
};

std::visit(Visitor, Res);

return {};
#endif
}
#endif // !defined(WDDM_LINUX)

} // namespace TC
24 changes: 24 additions & 0 deletions IGC/CMakeLists.txt
Expand Up @@ -2196,6 +2196,14 @@ set(IGC_BUILD__PROJ_NAME_PREFIX "")
set(IGC_BUILD__SPIRV_ENABLED ON)


# Enable vector compiler for Linux and Windows
# If user already defined this, honor decision
if(NOT DEFINED IGC_BUILD__VC_ENABLED)
if(LLVM_ON_UNIX OR LLVM_ON_WIN32)
set(IGC_BUILD__VC_ENABLED ON)
endif()
endif()


# ======================================== Path helper variables =======================================

Expand Down Expand Up @@ -3078,6 +3086,12 @@ if(IGC_BUILD__SPIRV_ENABLED)
)
endif()

#VC OPT switch on/off
if(NOT IGC_BUILD__VC_ENABLED)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
IGC_VC_DISABLED
)
endif()
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
_SCL_SECURE_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
Expand Down Expand Up @@ -3446,6 +3460,10 @@ if(LLVM_ON_WIN32
endif()


if(IGC_BUILD__VC_ENABLED AND NOT CMAKE_WDDM_LINUX)
add_subdirectory(VectorCompiler)
endif()

add_subdirectory(Compiler)
add_subdirectory(DriverInterface)
igc_sg_define(IGC__DriverInterface)
Expand Down Expand Up @@ -3737,6 +3755,12 @@ list(APPEND _targetLinkLineCommon zebinlib)
)
endif()

if(IGC_BUILD__VC_ENABLED)
list(APPEND _targetLinkLineCommon
${IGC_BUILD__PROJ_VC_LIBS_TO_LINK}
)
endif()

list(APPEND _targetLinkLineCommon
"${IGC_BUILD__START_GROUP}"
${IGC_BUILD__LLVM_LIBS_TO_LINK}
Expand Down

0 comments on commit 3fdb587

Please sign in to comment.