ocloc as shared library, ocloc API
Change-Id: Ie866b9ad5ee6de8c8b10f83551e2a3cab9d64a02
This commit is contained in:
parent
d4d5971d84
commit
697848f3d1
|
@ -821,7 +821,7 @@ if(MSVC)
|
|||
endif()
|
||||
|
||||
add_subdirectory_unique(offline_compiler ${NEO_BUILD_DIR}/offline_compiler)
|
||||
target_compile_definitions(ocloc PRIVATE MOCKABLE_VIRTUAL=)
|
||||
target_compile_definitions(ocloc_lib PRIVATE MOCKABLE_VIRTUAL=)
|
||||
|
||||
if(DONT_CARE_OF_VIRTUALS)
|
||||
set(NEO_CORE_RELEASE_LIB_NAME "neo_core")
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
project(ocloc)
|
||||
project(ocloc_lib)
|
||||
|
||||
set(CLOC_SRCS_LIB
|
||||
set(CLOC_LIB_SRCS_LIB
|
||||
${NEO_CORE_DIRECTORY}/device_binary_format/ar/ar.h
|
||||
${NEO_CORE_DIRECTORY}/device_binary_format/ar/ar_decoder.h
|
||||
${NEO_CORE_DIRECTORY}/device_binary_format/ar/ar_decoder.cpp
|
||||
|
@ -30,6 +30,10 @@ set(CLOC_SRCS_LIB
|
|||
${NEO_SOURCE_DIR}/offline_compiler/decoder/helper.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/decoder/iga_wrapper.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/decoder/translate_platform_base.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/ocloc_api.cpp
|
||||
${NEO_SOURCE_DIR}/offline_compiler/ocloc_api.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/ocloc_arg_helper.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/ocloc_arg_helper.cpp
|
||||
${NEO_SOURCE_DIR}/offline_compiler/ocloc_fatbinary.cpp
|
||||
${NEO_SOURCE_DIR}/offline_compiler/ocloc_fatbinary.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/offline_compiler_helper.cpp
|
||||
|
@ -47,24 +51,24 @@ set(CLOC_SRCS_LIB
|
|||
)
|
||||
|
||||
if(${IGA_HEADERS_AVAILABLE})
|
||||
set(CLOC_SRCS_LIB ${CLOC_SRCS_LIB}
|
||||
set(CLOC_LIB_SRCS_LIB ${CLOC_LIB_SRCS_LIB}
|
||||
${NEO_SOURCE_DIR}/offline_compiler/decoder/iga_wrapper.cpp
|
||||
${NEO_SOURCE_DIR}/offline_compiler/decoder${BRANCH_DIR_SUFFIX}/translate_platform.cpp
|
||||
)
|
||||
else()
|
||||
set(CLOC_SRCS_LIB ${CLOC_SRCS_LIB}
|
||||
set(CLOC_LIB_SRCS_LIB ${CLOC_LIB_SRCS_LIB}
|
||||
${NEO_SOURCE_DIR}/offline_compiler/decoder/iga_stubs.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND CLOC_SRCS_LIB
|
||||
list(APPEND CLOC_LIB_SRCS_LIB
|
||||
${NEO_CORE_DIRECTORY}/os_interface/windows/os_library_win.cpp
|
||||
${NEO_CORE_DIRECTORY}/os_interface/windows/os_library_win.h
|
||||
${NEO_SOURCE_DIR}/opencl/source/dll/windows/options_windows.cpp
|
||||
)
|
||||
else()
|
||||
list(APPEND CLOC_SRCS_LIB
|
||||
list(APPEND CLOC_LIB_SRCS_LIB
|
||||
${NEO_CORE_DIRECTORY}/os_interface/linux/os_library_linux.cpp
|
||||
${NEO_CORE_DIRECTORY}/os_interface/linux/os_library_linux.h
|
||||
${NEO_SOURCE_DIR}/opencl/source/dll/linux/options_linux.cpp
|
||||
|
@ -73,7 +77,7 @@ endif()
|
|||
|
||||
string(REPLACE ";" "," ALL_SUPPORTED_PRODUCT_FAMILIES "${ALL_SUPPORTED_PRODUCT_FAMILY}")
|
||||
|
||||
set(CLOC_LIB_FLAGS_DEFINITIONS
|
||||
set(CLOC_LIB_LIB_FLAGS_DEFINITIONS
|
||||
-DCIF_HEADERS_ONLY_BUILD
|
||||
-DALL_SUPPORTED_PRODUCT_FAMILIES=${ALL_SUPPORTED_PRODUCT_FAMILIES}
|
||||
)
|
||||
|
@ -83,43 +87,34 @@ set(RUNTIME_GENX_CPP_FILES
|
|||
)
|
||||
|
||||
macro(macro_for_each_platform)
|
||||
list(APPEND CLOC_SRCS_LIB ${NEO_SOURCE_DIR}/opencl/source/${GEN_TYPE_LOWER}/hw_info_${PLATFORM_IT_LOWER}.inl)
|
||||
list(APPEND CLOC_LIB_SRCS_LIB ${NEO_SOURCE_DIR}/opencl/source/${GEN_TYPE_LOWER}/hw_info_${PLATFORM_IT_LOWER}.inl)
|
||||
endmacro()
|
||||
|
||||
macro(macro_for_each_gen)
|
||||
foreach(SRC_IT ${RUNTIME_GENX_CPP_FILES})
|
||||
set(SRC_FILE ${NEO_SOURCE_DIR}/opencl/source/${GEN_TYPE_LOWER}/${SRC_IT})
|
||||
if(EXISTS ${SRC_FILE}_${GEN_TYPE_LOWER}.cpp)
|
||||
list(APPEND CLOC_SRCS_LIB ${SRC_FILE}_${GEN_TYPE_LOWER}.cpp)
|
||||
list(APPEND CLOC_LIB_SRCS_LIB ${SRC_FILE}_${GEN_TYPE_LOWER}.cpp)
|
||||
endif()
|
||||
endforeach()
|
||||
apply_macro_for_each_platform()
|
||||
|
||||
list(APPEND CLOC_SRCS_LIB ${NEO_CORE_DIRECTORY}/${GEN_TYPE_LOWER}/enable_${GEN_TYPE_LOWER}.cpp)
|
||||
list(APPEND CLOC_LIB_SRCS_LIB ${NEO_CORE_DIRECTORY}/${GEN_TYPE_LOWER}/enable_${GEN_TYPE_LOWER}.cpp)
|
||||
endmacro()
|
||||
|
||||
apply_macro_for_each_gen("SUPPORTED")
|
||||
|
||||
set(CLOC_SRCS
|
||||
${CLOC_SRCS_LIB}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
set(CLOC_LIB_SRCS
|
||||
${CLOC_LIB_SRCS_LIB}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
)
|
||||
add_executable(ocloc ${CLOC_SRCS})
|
||||
|
||||
if(UNIX)
|
||||
install(FILES $<TARGET_FILE:ocloc>
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||
COMPONENT ocloc)
|
||||
set_property(GLOBAL APPEND PROPERTY NEO_COMPONENTS_LIST "ocloc")
|
||||
endif()
|
||||
add_library(ocloc_lib SHARED ${CLOC_LIB_SRCS})
|
||||
|
||||
add_subdirectories()
|
||||
|
||||
create_project_source_tree(ocloc)
|
||||
create_project_source_tree(ocloc_lib)
|
||||
|
||||
set(CLOC_INCLUDES
|
||||
set(CLOC_LIB_INCLUDES
|
||||
${ENGINE_NODE_DIR}
|
||||
${IGC_OCL_ADAPTOR_DIR}
|
||||
${CIF_BASE_DIR}
|
||||
|
@ -128,22 +123,75 @@ set(CLOC_INCLUDES
|
|||
${NEO__IGC_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_include_directories(ocloc BEFORE PRIVATE ${CLOC_INCLUDES})
|
||||
target_include_directories(ocloc BEFORE PRIVATE ${IGA_INCLUDE_DIR})
|
||||
target_include_directories(ocloc_lib BEFORE PRIVATE ${CLOC_LIB_INCLUDES})
|
||||
target_include_directories(ocloc_lib BEFORE PRIVATE ${IGA_INCLUDE_DIR})
|
||||
|
||||
target_compile_definitions(ocloc PUBLIC ${CLOC_LIB_FLAGS_DEFINITIONS} ${SUPPORTED_GEN_FLAGS_DEFINITONS} DEFAULT_PLATFORM=${DEFAULT_SUPPORTED_PLATFORM}
|
||||
target_compile_definitions(ocloc_lib PUBLIC ${CLOC_LIB_LIB_FLAGS_DEFINITIONS} ${SUPPORTED_GEN_FLAGS_DEFINITONS} DEFAULT_PLATFORM=${DEFAULT_SUPPORTED_PLATFORM}
|
||||
IGA_LIBRARY_NAME=${CMAKE_SHARED_LIBRARY_PREFIX}${IGA_LIBRARY_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
target_compile_definitions(ocloc PRIVATE ${NEO__IGC_COMPILE_DEFINITIONS})
|
||||
target_compile_definitions(ocloc_lib PRIVATE ${NEO__IGC_COMPILE_DEFINITIONS})
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(ocloc dbghelp)
|
||||
target_link_libraries(ocloc_lib dbghelp)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
target_link_libraries(ocloc dl pthread)
|
||||
target_link_libraries(ocloc_lib dl pthread)
|
||||
endif()
|
||||
|
||||
set(CLOC_LIB_SRCS_LIB ${CLOC_LIB_SRCS_LIB} PARENT_SCOPE)
|
||||
|
||||
set(CLOC_SRCS
|
||||
${NEO_CORE_DIRECTORY}/os_interface/os_library.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/ocloc_wrapper.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/ocloc_wrapper.cpp
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/get_path.h
|
||||
)
|
||||
if(WIN32)
|
||||
list(APPEND CLOC_SRCS
|
||||
${NEO_CORE_DIRECTORY}/os_interface/windows/os_library_win.cpp
|
||||
${NEO_CORE_DIRECTORY}/os_interface/windows/os_library_win.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/windows/get_path.cpp
|
||||
|
||||
)
|
||||
else()
|
||||
list(APPEND CLOC_SRCS
|
||||
${NEO_CORE_DIRECTORY}/os_interface/linux/os_library_linux.cpp
|
||||
${NEO_CORE_DIRECTORY}/os_interface/linux/os_library_linux.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/linux/get_path.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(ocloc ${CLOC_SRCS} ${NEO_SOURCE_DIR}/offline_compiler/main.cpp)
|
||||
add_dependencies(ocloc ocloc_lib)
|
||||
target_link_libraries(ocloc ocloc_lib)
|
||||
|
||||
set(OCLOC_LIB_NAME "ocloc")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(OCLOC_BITNESS_SUFFIX 32)
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(OCLOC_BITNESS_SUFFIX 64)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
install(FILES $<TARGET_FILE:ocloc_lib>
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/intel-opencl
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
install(FILES $<TARGET_FILE:ocloc>
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
COMPONENT ocloc)
|
||||
set_property(GLOBAL APPEND PROPERTY NEO_COMPONENTS_LIST "ocloc")
|
||||
set_target_properties(ocloc_lib PROPERTIES OUTPUT_NAME ${OCLOC_LIB_NAME})
|
||||
add_definitions(-DOCLOC_LIB_NAME="lib${OCLOC_LIB_NAME}.so")
|
||||
else()
|
||||
set_target_properties(ocloc_lib PROPERTIES OUTPUT_NAME "${OCLOC_LIB_NAME}${OCLOC_BITNESS_SUFFIX}")
|
||||
add_definitions(-DOCLOC_LIB_NAME="${OCLOC_LIB_NAME}${OCLOC_BITNESS_SUFFIX}.dll")
|
||||
endif()
|
||||
|
||||
create_project_source_tree(ocloc)
|
||||
set_target_properties(ocloc PROPERTIES FOLDER "offline_compiler")
|
||||
set_target_properties(ocloc_lib PROPERTIES FOLDER "offline_compiler")
|
||||
|
||||
|
||||
add_custom_target(copy_compiler_files DEPENDS ${NEO__IGC_TARGETS})
|
||||
set_target_properties(copy_compiler_files PROPERTIES FOLDER "opencl runtime")
|
||||
|
@ -153,10 +201,11 @@ if(WIN32)
|
|||
add_custom_command(
|
||||
TARGET copy_compiler_files
|
||||
PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:ocloc_lib>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${TARGET_tmp}> $<TARGET_FILE_DIR:ocloc_lib>
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:ocloc>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${TARGET_tmp}> $<TARGET_FILE_DIR:ocloc>
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(CLOC_SRCS_LIB ${CLOC_SRCS_LIB} PARENT_SCOPE)
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ocloc_api.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void printHelp() {
|
||||
printf(R"===(ocloc is a tool for managing Intel OpenCL GPU device binary format.
|
||||
It can be used for generation (as part of 'compile' command) as well as
|
||||
manipulation (decoding/modifying - as part of 'disasm'/'asm' commands) of such
|
||||
binary files.
|
||||
Intel OpenCL GPU device binary is a format used by Intel OpenCL GPU runtime
|
||||
(aka NEO). Intel OpenCL GPU runtime will return this binary format when queried
|
||||
using clGetProgramInfo(..., CL_PROGRAM_BINARIES, ...). It will also honor
|
||||
this format as input to clCreateProgramWithBinary function call.
|
||||
ocloc does not require Intel GPU device to be present in the system nor does it
|
||||
depend on Intel OpenCL GPU runtime driver to be installed. It does however rely
|
||||
on the same set of compilers (IGC, common_clang) as the runtime driver.
|
||||
|
||||
Usage: ocloc [--help] <command> [<command_args>]
|
||||
Available commands are listed below.
|
||||
Use 'ocloc <command> --help' to get help about specific command.
|
||||
|
||||
Commands:
|
||||
compile Compiles input to Intel OpenCL GPU device binary.
|
||||
disasm Disassembles Intel OpenCL GPU device binary.
|
||||
asm Assembles Intel OpenCL GPU device binary.
|
||||
multi Compiles multiple files using a config file.
|
||||
|
||||
Default command (when none provided) is 'compile'.
|
||||
|
||||
Examples:
|
||||
Compile file to Intel OpenCL GPU device binary (out = source_file_Gen9core.bin)
|
||||
ocloc -file source_file.cl -device skl
|
||||
|
||||
Disassemble Intel OpenCL GPU device binary
|
||||
ocloc disasm -file source_file_Gen9core.bin
|
||||
|
||||
Assemble to Intel OpenCL GPU device binary (after above disasm)
|
||||
ocloc asm -out reassembled.bin
|
||||
)===");
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
int oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
const uint32_t numSources, const uint8_t **dataSources, const uint64_t *lenSources, const char **nameSources,
|
||||
const uint32_t numInputHeaders, const uint8_t **dataInputHeaders, const uint64_t *lenInputHeaders, const char **nameInputHeaders,
|
||||
uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs) {
|
||||
auto helper = std::make_unique<OclocArgHelper>(
|
||||
numSources, dataSources, lenSources, nameSources,
|
||||
numInputHeaders, dataInputHeaders, lenInputHeaders, nameInputHeaders,
|
||||
numOutputs, dataOutputs, lenOutputs, nameOutputs);
|
||||
std::vector<std::string> allArgs;
|
||||
if (numArgs > 1) {
|
||||
allArgs.assign(argv, argv + numArgs);
|
||||
}
|
||||
|
||||
try {
|
||||
if (numArgs == 1 || (numArgs > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))) {
|
||||
printHelp();
|
||||
} else if (numArgs > 1 && !strcmp(argv[1], "disasm")) {
|
||||
BinaryDecoder disasm(std::move(helper));
|
||||
int retVal = disasm.validateInput(allArgs);
|
||||
if (retVal == 0) {
|
||||
return disasm.decode();
|
||||
} else {
|
||||
return retVal;
|
||||
}
|
||||
} else if (numArgs > 1 && !strcmp(argv[1], "asm")) {
|
||||
BinaryEncoder assembler(std::move(helper));
|
||||
int retVal = assembler.validateInput(allArgs);
|
||||
if (retVal == 0) {
|
||||
return assembler.encode();
|
||||
} else {
|
||||
return retVal;
|
||||
}
|
||||
} else if (numArgs > 1 && (!strcmp(argv[1], "multi") || !strcmp(argv[1], "-multi"))) {
|
||||
int retValue = CL_SUCCESS;
|
||||
auto pMulti = std::unique_ptr<MultiCommand>(MultiCommand::create(allArgs, retValue));
|
||||
return retValue;
|
||||
} else {
|
||||
int retVal = CL_SUCCESS;
|
||||
std::vector<std::string> allArgs;
|
||||
if (numArgs > 1) {
|
||||
allArgs.assign(argv, argv + numArgs);
|
||||
}
|
||||
|
||||
OfflineCompiler *pCompiler = OfflineCompiler::create(numArgs, allArgs, true, retVal, std::move(helper));
|
||||
|
||||
if (retVal == CL_SUCCESS) {
|
||||
retVal = buildWithSafetyGuard(pCompiler);
|
||||
|
||||
std::string buildLog = pCompiler->getBuildLog();
|
||||
if (buildLog.empty() == false) {
|
||||
printf("%s\n", buildLog.c_str());
|
||||
}
|
||||
|
||||
if (retVal == CL_SUCCESS) {
|
||||
if (!pCompiler->isQuiet())
|
||||
printf("Build succeeded.\n");
|
||||
} else {
|
||||
printf("Build failed with error code: %d\n", retVal);
|
||||
}
|
||||
}
|
||||
delete pCompiler;
|
||||
return retVal;
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
printf("%s\n", e.what());
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
void oclocFreeOutput(uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs) {
|
||||
for (uint32_t i = 0; i < *numOutputs; i++) {
|
||||
delete[](*dataOutputs)[i];
|
||||
delete[](*nameOutputs)[i];
|
||||
}
|
||||
delete[](*dataOutputs);
|
||||
delete[](*lenOutputs);
|
||||
delete[](*nameOutputs);
|
||||
}
|
||||
}
|
|
@ -45,7 +45,7 @@ T readUnaligned(const void *ptr) {
|
|||
|
||||
int BinaryDecoder::decode() {
|
||||
parseTokens();
|
||||
std::ofstream ptmFile(pathToDump + "PTM.txt");
|
||||
std::stringstream ptmFile;
|
||||
auto devBinPtr = getDevBinary();
|
||||
if (devBinPtr == nullptr) {
|
||||
messagePrinter.printf("Error! Device Binary section was not found.\n");
|
||||
|
@ -85,7 +85,7 @@ void BinaryDecoder::dumpField(const void *&binaryPtr, const PTField &field, std:
|
|||
}
|
||||
|
||||
const void *BinaryDecoder::getDevBinary() {
|
||||
binary = readBinaryFile(binaryFile);
|
||||
binary = argHelper->readBinaryFile(binaryFile);
|
||||
const void *data = nullptr;
|
||||
std::string decoderErrors;
|
||||
std::string decoderWarnings;
|
||||
|
@ -95,18 +95,15 @@ const void *BinaryDecoder::getDevBinary() {
|
|||
auto sectionData = ArrayRef<const char>(reinterpret_cast<const char *>(sectionHeader.data.begin()), sectionHeader.data.size());
|
||||
switch (sectionHeader.header->type) {
|
||||
case NEO::Elf::SHT_OPENCL_LLVM_BINARY: {
|
||||
std::ofstream ofs(pathToDump + "llvm.bin", std::ios::binary);
|
||||
ofs.write(sectionData.begin(), sectionData.size());
|
||||
argHelper->saveOutput(pathToDump + "llvm.bin", sectionData.begin(), sectionData.size());
|
||||
break;
|
||||
}
|
||||
case NEO::Elf::SHT_OPENCL_SPIRV: {
|
||||
std::ofstream ofs(pathToDump + "spirv.bin", std::ios::binary);
|
||||
ofs.write(sectionData.begin(), sectionData.size());
|
||||
argHelper->saveOutput(pathToDump + "spirv.bin", sectionData.begin(), sectionData.size());
|
||||
break;
|
||||
}
|
||||
case NEO::Elf::SHT_OPENCL_OPTIONS: {
|
||||
std::ofstream ofs(pathToDump + "build.bin", std::ios::binary);
|
||||
ofs.write(sectionData.begin(), sectionData.size());
|
||||
argHelper->saveOutput(pathToDump + "build.bin", sectionData.begin(), sectionData.size());
|
||||
break;
|
||||
}
|
||||
case NEO::Elf::SHT_OPENCL_DEV_BINARY: {
|
||||
|
@ -135,70 +132,78 @@ uint8_t BinaryDecoder::getSize(const std::string &typeStr) {
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> BinaryDecoder::loadPatchList() {
|
||||
if (argHelper->hasHeaders()) {
|
||||
return argHelper->headersToVectorOfStrings();
|
||||
} else {
|
||||
std::vector<std::string> patchList;
|
||||
if (pathToPatch.empty()) {
|
||||
messagePrinter.printf("Path to patch list not provided - using defaults, skipping patchokens as undefined.\n");
|
||||
patchList = {
|
||||
"struct SProgramBinaryHeader",
|
||||
"{",
|
||||
" uint32_t Magic;",
|
||||
" uint32_t Version;",
|
||||
" uint32_t Device;",
|
||||
" uint32_t GPUPointerSizeInBytes;",
|
||||
" uint32_t NumberOfKernels;",
|
||||
" uint32_t SteppingId;",
|
||||
" uint32_t PatchListSize;",
|
||||
"};",
|
||||
"",
|
||||
"struct SKernelBinaryHeader",
|
||||
"{",
|
||||
" uint32_t CheckSum;",
|
||||
" uint64_t ShaderHashCode;",
|
||||
" uint32_t KernelNameSize;",
|
||||
" uint32_t PatchListSize;",
|
||||
"};",
|
||||
"",
|
||||
"struct SKernelBinaryHeaderCommon :",
|
||||
" SKernelBinaryHeader",
|
||||
"{",
|
||||
" uint32_t KernelHeapSize;",
|
||||
" uint32_t GeneralStateHeapSize;",
|
||||
" uint32_t DynamicStateHeapSize;",
|
||||
" uint32_t SurfaceStateHeapSize;",
|
||||
" uint32_t KernelUnpaddedSize;",
|
||||
"};",
|
||||
"",
|
||||
"enum PATCH_TOKEN",
|
||||
"{",
|
||||
" PATCH_TOKEN_ALLOCATE_GLOBAL_MEMORY_SURFACE_PROGRAM_BINARY_INFO, // 41 @SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo@",
|
||||
" PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO, // 42 @SPatchAllocateConstantMemorySurfaceProgramBinaryInfo@",
|
||||
"};",
|
||||
"struct SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo :",
|
||||
" SPatchItemHeader",
|
||||
"{",
|
||||
" uint32_t Type;",
|
||||
" uint32_t GlobalBufferIndex;",
|
||||
" uint32_t InlineDataSize;",
|
||||
"};",
|
||||
"struct SPatchAllocateConstantMemorySurfaceProgramBinaryInfo :",
|
||||
" SPatchItemHeader",
|
||||
"{",
|
||||
" uint32_t ConstantBufferIndex;",
|
||||
" uint32_t InlineDataSize;",
|
||||
"};",
|
||||
|
||||
};
|
||||
} else {
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_list.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_shared.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_g7.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_g8.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_g9.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_g10.h", true);
|
||||
}
|
||||
return patchList;
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryDecoder::parseTokens() {
|
||||
//Creating patchlist definitions
|
||||
std::vector<std::string> patchList;
|
||||
|
||||
if (pathToPatch.empty()) {
|
||||
messagePrinter.printf("Path to patch list not provided - using defaults, skipping patchokens as undefined.\n");
|
||||
patchList = {
|
||||
"struct SProgramBinaryHeader",
|
||||
"{",
|
||||
" uint32_t Magic;",
|
||||
" uint32_t Version;",
|
||||
" uint32_t Device;",
|
||||
" uint32_t GPUPointerSizeInBytes;",
|
||||
" uint32_t NumberOfKernels;",
|
||||
" uint32_t SteppingId;",
|
||||
" uint32_t PatchListSize;",
|
||||
"};",
|
||||
"",
|
||||
"struct SKernelBinaryHeader",
|
||||
"{",
|
||||
" uint32_t CheckSum;",
|
||||
" uint64_t ShaderHashCode;",
|
||||
" uint32_t KernelNameSize;",
|
||||
" uint32_t PatchListSize;",
|
||||
"};",
|
||||
"",
|
||||
"struct SKernelBinaryHeaderCommon :",
|
||||
" SKernelBinaryHeader",
|
||||
"{",
|
||||
" uint32_t KernelHeapSize;",
|
||||
" uint32_t GeneralStateHeapSize;",
|
||||
" uint32_t DynamicStateHeapSize;",
|
||||
" uint32_t SurfaceStateHeapSize;",
|
||||
" uint32_t KernelUnpaddedSize;",
|
||||
"};",
|
||||
"",
|
||||
"enum PATCH_TOKEN",
|
||||
"{",
|
||||
" PATCH_TOKEN_ALLOCATE_GLOBAL_MEMORY_SURFACE_PROGRAM_BINARY_INFO, // 41 @SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo@",
|
||||
" PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO, // 42 @SPatchAllocateConstantMemorySurfaceProgramBinaryInfo@",
|
||||
"};",
|
||||
"struct SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo :",
|
||||
" SPatchItemHeader",
|
||||
"{",
|
||||
" uint32_t Type;",
|
||||
" uint32_t GlobalBufferIndex;",
|
||||
" uint32_t InlineDataSize;",
|
||||
"};",
|
||||
"struct SPatchAllocateConstantMemorySurfaceProgramBinaryInfo :",
|
||||
" SPatchItemHeader",
|
||||
"{",
|
||||
" uint32_t ConstantBufferIndex;",
|
||||
" uint32_t InlineDataSize;",
|
||||
"};",
|
||||
|
||||
};
|
||||
} else {
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_list.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_shared.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_g7.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_g8.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_g9.h", true);
|
||||
readFileToVectorOfStrings(patchList, pathToPatch + "patch_g10.h", true);
|
||||
}
|
||||
auto patchList = loadPatchList();
|
||||
|
||||
size_t pos = findPos(patchList, "struct SProgramBinaryHeader");
|
||||
if (pos == patchList.size()) {
|
||||
|
@ -354,6 +359,8 @@ int BinaryDecoder::processBinary(const void *&ptr, std::ostream &ptmFile) {
|
|||
ptmFile << "Kernel #" << i << '\n';
|
||||
processKernel(ptr, ptmFile);
|
||||
}
|
||||
|
||||
argHelper->saveOutput(pathToDump + "PTM.txt", ptmFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -394,12 +401,12 @@ void BinaryDecoder::processKernel(const void *&ptr, std::ostream &ptmFile) {
|
|||
messagePrinter.printf("Trying to disassemble %s.krn\n", kernelName.c_str());
|
||||
std::string disassembledKernel;
|
||||
if (iga->tryDisassembleGenISA(ptr, KernelHeapUnpaddedSize, disassembledKernel)) {
|
||||
writeDataToFile((fileName + ".asm").c_str(), disassembledKernel.data(), disassembledKernel.size());
|
||||
argHelper->saveOutput(fileName + ".asm", disassembledKernel.data(), disassembledKernel.size());
|
||||
} else {
|
||||
if (ignoreIsaPadding) {
|
||||
writeDataToFile((fileName + ".dat").c_str(), ptr, KernelHeapUnpaddedSize);
|
||||
argHelper->saveOutput(fileName + ".dat", ptr, KernelHeapUnpaddedSize);
|
||||
} else {
|
||||
writeDataToFile((fileName + ".dat").c_str(), ptr, KernelHeapSize);
|
||||
argHelper->saveOutput(fileName + ".dat", ptr, KernelHeapSize);
|
||||
}
|
||||
}
|
||||
ptr = ptrOffset(ptr, KernelHeapSize);
|
||||
|
@ -407,16 +414,16 @@ void BinaryDecoder::processKernel(const void *&ptr, std::ostream &ptmFile) {
|
|||
if (GeneralStateHeapSize != 0) {
|
||||
messagePrinter.printf("Warning! GeneralStateHeapSize wasn't 0.\n");
|
||||
fileName = pathToDump + kernelName + "_GeneralStateHeap.bin";
|
||||
writeDataToFile(fileName.c_str(), ptr, DynamicStateHeapSize);
|
||||
argHelper->saveOutput(fileName, ptr, DynamicStateHeapSize);
|
||||
ptr = ptrOffset(ptr, GeneralStateHeapSize);
|
||||
}
|
||||
|
||||
fileName = pathToDump + kernelName + "_DynamicStateHeap.bin";
|
||||
writeDataToFile(fileName.c_str(), ptr, DynamicStateHeapSize);
|
||||
argHelper->saveOutput(fileName, ptr, DynamicStateHeapSize);
|
||||
ptr = ptrOffset(ptr, DynamicStateHeapSize);
|
||||
|
||||
fileName = pathToDump + kernelName + "_SurfaceStateHeap.bin";
|
||||
writeDataToFile(fileName.c_str(), ptr, SurfaceStateHeapSize);
|
||||
argHelper->saveOutput(fileName, ptr, SurfaceStateHeapSize);
|
||||
ptr = ptrOffset(ptr, SurfaceStateHeapSize);
|
||||
|
||||
if (KernelPatchListSize == 0) {
|
||||
|
@ -501,33 +508,34 @@ uint32_t BinaryDecoder::readStructFields(const std::vector<std::string> &patchLi
|
|||
return fullSize;
|
||||
}
|
||||
|
||||
int BinaryDecoder::validateInput(uint32_t argc, const char **argv) {
|
||||
if (!strcmp(argv[argc - 1], "--help")) {
|
||||
int BinaryDecoder::validateInput(const std::vector<std::string> &args) {
|
||||
if (args[args.size() - 1] == "-help") {
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (uint32_t i = 2; i < argc; ++i) {
|
||||
if (i < argc - 1) {
|
||||
if (!strcmp(argv[i], "-file")) {
|
||||
binaryFile = std::string(argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-device")) {
|
||||
iga->setProductFamily(getProductFamilyFromDeviceName(argv[++i]));
|
||||
} else if (!strcmp(argv[i], "-patch")) {
|
||||
pathToPatch = std::string(argv[++i]);
|
||||
addSlash(pathToPatch);
|
||||
} else if (!strcmp(argv[i], "-dump")) {
|
||||
pathToDump = std::string(argv[++i]);
|
||||
addSlash(pathToDump);
|
||||
}
|
||||
for (size_t argIndex = 2; argIndex < args.size(); ++argIndex) {
|
||||
const auto &currArg = args[argIndex];
|
||||
const bool hasMoreArgs = (argIndex + 1 < args.size());
|
||||
if ("-file" == currArg && hasMoreArgs) {
|
||||
binaryFile = args[++argIndex];
|
||||
} else if ("-device" == currArg && hasMoreArgs) {
|
||||
iga->setProductFamily(getProductFamilyFromDeviceName(args[++argIndex]));
|
||||
} else if ("-patch" == currArg && hasMoreArgs) {
|
||||
pathToPatch = args[++argIndex];
|
||||
addSlash(pathToPatch);
|
||||
} else if ("-dump" == currArg && hasMoreArgs) {
|
||||
pathToDump = args[++argIndex];
|
||||
addSlash(pathToDump);
|
||||
} else if ("-ignore_isa_padding" == currArg) {
|
||||
ignoreIsaPadding = true;
|
||||
} else if ("-q" == currArg) {
|
||||
this->messagePrinter = MessagePrinter{true};
|
||||
iga->setMessagePrinter(this->messagePrinter);
|
||||
} else {
|
||||
if (!strcmp(argv[i], "-ignore_isa_padding")) {
|
||||
ignoreIsaPadding = true;
|
||||
} else {
|
||||
messagePrinter.printf("Unknown argument %s\n", argv[i]);
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
messagePrinter.printf("Unknown argument %s\n", currArg.c_str());
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (binaryFile.find(".bin") == std::string::npos) {
|
||||
|
@ -535,15 +543,15 @@ int BinaryDecoder::validateInput(uint32_t argc, const char **argv) {
|
|||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
if (pathToDump.empty()) {
|
||||
messagePrinter.printf("Warning : Path to dump folder not specificed - using ./dump as default.\n");
|
||||
pathToDump = std::string("dump/");
|
||||
}
|
||||
|
||||
if (false == iga->isKnownPlatform()) {
|
||||
messagePrinter.printf("Warning : missing or invalid -device parameter - results may be inacurate\n");
|
||||
}
|
||||
|
||||
MakeDirectory(pathToDump.c_str());
|
||||
if (!argHelper->outputEnabled()) {
|
||||
if (pathToDump.empty()) {
|
||||
messagePrinter.printf("Warning : Path to dump folder not specificed - using ./dump as default.\n");
|
||||
pathToDump = std::string("dump/");
|
||||
}
|
||||
MakeDirectory(pathToDump.c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
#include "offline_compiler/decoder/helper.h"
|
||||
#include "offline_compiler/decoder/iga_wrapper.h"
|
||||
#include "offline_compiler/ocloc_arg_helper.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -33,15 +34,21 @@ class BinaryDecoder {
|
|||
public:
|
||||
BinaryDecoder() : iga(new IgaWrapper) {
|
||||
iga->setMessagePrinter(messagePrinter);
|
||||
if (nullptr == argHelper) {
|
||||
argHelper = std::make_unique<OclocArgHelper>();
|
||||
}
|
||||
}
|
||||
BinaryDecoder(const std::string &file, const std::string &patch, const std::string &dump)
|
||||
: binaryFile(file), pathToPatch(patch), pathToDump(dump){};
|
||||
BinaryDecoder(std::unique_ptr<OclocArgHelper> helper) : argHelper(std::move(helper)), iga(new IgaWrapper) {
|
||||
iga->setMessagePrinter(messagePrinter);
|
||||
};
|
||||
int decode();
|
||||
int validateInput(uint32_t argc, const char **argv);
|
||||
|
||||
int validateInput(const std::vector<std::string> &args);
|
||||
void setMessagePrinter(const MessagePrinter &messagePrinter);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<OclocArgHelper> argHelper = nullptr;
|
||||
bool ignoreIsaPadding = false;
|
||||
BinaryHeader programHeader, kernelHeader;
|
||||
std::vector<char> binary;
|
||||
|
@ -53,6 +60,7 @@ class BinaryDecoder {
|
|||
void dumpField(const void *&binaryPtr, const PTField &field, std::ostream &ptmFile);
|
||||
uint8_t getSize(const std::string &typeStr);
|
||||
const void *getDevBinary();
|
||||
std::vector<std::string> loadPatchList();
|
||||
void parseTokens();
|
||||
void printHelp();
|
||||
int processBinary(const void *&ptr, std::ostream &ptmFile);
|
||||
|
|
|
@ -56,16 +56,8 @@ void BinaryEncoder::calculatePatchListSizes(std::vector<std::string> &ptmFile) {
|
|||
}
|
||||
|
||||
bool BinaryEncoder::copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary, uint32_t *binaryLength) {
|
||||
std::ifstream ifs(srcFileName, std::ios::binary);
|
||||
if (!ifs.good()) {
|
||||
messagePrinter.printf("Cannot open %s.\n", srcFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
ifs.seekg(0, ifs.end);
|
||||
auto length = static_cast<size_t>(ifs.tellg());
|
||||
ifs.seekg(0, ifs.beg);
|
||||
std::vector<char> binary(length);
|
||||
ifs.read(binary.data(), length);
|
||||
auto binary = argHelper->readBinaryFile(srcFileName);
|
||||
auto length = binary.size();
|
||||
outBinary.write(binary.data(), length);
|
||||
|
||||
if (binaryLength) {
|
||||
|
@ -75,27 +67,24 @@ bool BinaryEncoder::copyBinaryToBinary(const std::string &srcFileName, std::ostr
|
|||
return true;
|
||||
}
|
||||
|
||||
int BinaryEncoder::createElf() {
|
||||
int BinaryEncoder::createElf(std::stringstream &deviceBinary) {
|
||||
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> ElfEncoder;
|
||||
ElfEncoder.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
|
||||
|
||||
//Build Options
|
||||
if (fileExists(pathToDump + "build.bin")) {
|
||||
auto binary = readBinaryFile(pathToDump + "build.bin");
|
||||
if (argHelper->fileExists(pathToDump + "build.bin")) {
|
||||
auto binary = argHelper->readBinaryFile(pathToDump + "build.bin");
|
||||
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_OPTIONS, "BuildOptions",
|
||||
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
||||
} else {
|
||||
messagePrinter.printf("Warning! Missing build section.\n");
|
||||
}
|
||||
|
||||
//LLVM or SPIRV
|
||||
if (fileExists(pathToDump + "llvm.bin")) {
|
||||
auto binary = readBinaryFile(pathToDump + "llvm.bin");
|
||||
if (argHelper->fileExists(pathToDump + "llvm.bin")) {
|
||||
auto binary = argHelper->readBinaryFile(pathToDump + "llvm.bin");
|
||||
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_LLVM_BINARY, "Intel(R) OpenCL LLVM Object",
|
||||
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
||||
} else if (fileExists(pathToDump + "spirv.bin")) {
|
||||
auto binary = readBinaryFile(pathToDump + "spirv.bin");
|
||||
std::string data(binary.begin(), binary.end());
|
||||
} else if (argHelper->fileExists(pathToDump + "spirv.bin")) {
|
||||
auto binary = argHelper->readBinaryFile(pathToDump + "spirv.bin");
|
||||
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_SPIRV, "SPIRV Object",
|
||||
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
||||
} else {
|
||||
|
@ -103,25 +92,15 @@ int BinaryEncoder::createElf() {
|
|||
}
|
||||
|
||||
//Device Binary
|
||||
if (fileExists(pathToDump + "device_binary.bin")) {
|
||||
auto binary = readBinaryFile(pathToDump + "device_binary.bin");
|
||||
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, "Intel(R) OpenCL Device Binary",
|
||||
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
||||
} else {
|
||||
messagePrinter.printf("Missing device_binary.bin\n");
|
||||
return -1;
|
||||
}
|
||||
auto deviceBinaryStr = deviceBinary.str();
|
||||
std::vector<char> binary(deviceBinaryStr.begin(), deviceBinaryStr.end());
|
||||
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, "Intel(R) OpenCL Device Binary",
|
||||
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
||||
|
||||
//Resolve Elf Binary
|
||||
auto elfBinary = ElfEncoder.encode();
|
||||
argHelper->saveOutput(elfName, elfBinary.data(), elfBinary.size());
|
||||
|
||||
std::ofstream elfFile(elfName, std::ios::binary);
|
||||
if (!elfFile.good()) {
|
||||
messagePrinter.printf("Couldn't create %s.\n", elfName.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
elfFile.write(reinterpret_cast<const char *>(elfBinary.data()), elfBinary.size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -160,21 +139,23 @@ Examples:
|
|||
|
||||
int BinaryEncoder::encode() {
|
||||
std::vector<std::string> ptmFile;
|
||||
readFileToVectorOfStrings(ptmFile, pathToDump + "PTM.txt");
|
||||
calculatePatchListSizes(ptmFile);
|
||||
|
||||
std::ofstream deviceBinary(pathToDump + "device_binary.bin", std::ios::binary);
|
||||
if (!deviceBinary.good()) {
|
||||
messagePrinter.printf("Error! Couldn't create device_binary.bin.\n");
|
||||
if (!argHelper->fileExists(pathToDump + "PTM.txt")) {
|
||||
messagePrinter.printf("Error! Couldn't find PTM.txt");
|
||||
return -1;
|
||||
}
|
||||
argHelper->readFileToVectorOfStrings(pathToDump + "PTM.txt", ptmFile);
|
||||
|
||||
calculatePatchListSizes(ptmFile);
|
||||
|
||||
std::stringstream deviceBinary; //(pathToDump + "device_binary.bin", std::ios::binary);
|
||||
int retVal = processBinary(ptmFile, deviceBinary);
|
||||
deviceBinary.close();
|
||||
argHelper->saveOutput(pathToDump + "device_binary.bin", deviceBinary.str().c_str(), deviceBinary.str().length());
|
||||
if (retVal != CL_SUCCESS) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
return createElf();
|
||||
retVal = createElf(deviceBinary);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int BinaryEncoder::processBinary(const std::vector<std::string> &ptmFileLines, std::ostream &deviceBinary) {
|
||||
|
@ -252,8 +233,8 @@ int BinaryEncoder::processKernel(size_t &line, const std::vector<std::string> &p
|
|||
bool heapsCopiedSuccesfully = true;
|
||||
|
||||
// Use .asm if available, fallback to .dat
|
||||
if (fileExists(pathToDump + kernelName + "_KernelHeap.asm")) {
|
||||
auto kernelAsAsm = readBinaryFile(pathToDump + kernelName + "_KernelHeap.asm");
|
||||
if (argHelper->fileExists(pathToDump + kernelName + "_KernelHeap.asm")) {
|
||||
auto kernelAsAsm = argHelper->readBinaryFile(pathToDump + kernelName + "_KernelHeap.asm");
|
||||
std::string kernelAsBinary;
|
||||
messagePrinter.printf("Trying to assemble %s.asm\n", kernelName.c_str());
|
||||
if (false == iga->tryAssembleGenISA(std::string(kernelAsAsm.begin(), kernelAsAsm.end()), kernelAsBinary)) {
|
||||
|
@ -278,7 +259,7 @@ int BinaryEncoder::processKernel(size_t &line, const std::vector<std::string> &p
|
|||
}
|
||||
|
||||
// Write GeneralStateHeap, DynamicStateHeap, SurfaceStateHeap
|
||||
if (fileExists(pathToDump + kernelName + "_GeneralStateHeap.bin")) {
|
||||
if (argHelper->fileExists(pathToDump + kernelName + "_GeneralStateHeap.bin")) {
|
||||
heapsCopiedSuccesfully = heapsCopiedSuccesfully && copyBinaryToBinary(pathToDump + kernelName + "_GeneralStateHeap.bin", kernelBlob);
|
||||
}
|
||||
heapsCopiedSuccesfully = heapsCopiedSuccesfully && copyBinaryToBinary(pathToDump + kernelName + "_DynamicStateHeap.bin", kernelBlob);
|
||||
|
@ -324,40 +305,39 @@ int BinaryEncoder::processKernel(size_t &line, const std::vector<std::string> &p
|
|||
return 0;
|
||||
}
|
||||
|
||||
int BinaryEncoder::validateInput(uint32_t argc, const char **argv) {
|
||||
if (!strcmp(argv[argc - 1], "--help")) {
|
||||
int BinaryEncoder::validateInput(const std::vector<std::string> &args) {
|
||||
if ("-help" == args[args.size() - 1]) {
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (uint32_t i = 2; i < argc; ++i) {
|
||||
if (i < argc - 1) {
|
||||
if (!strcmp(argv[i], "-dump")) {
|
||||
pathToDump = std::string(argv[++i]);
|
||||
addSlash(pathToDump);
|
||||
} else if (!strcmp(argv[i], "-device")) {
|
||||
iga->setProductFamily(getProductFamilyFromDeviceName(argv[++i]));
|
||||
} else if (!strcmp(argv[i], "-out")) {
|
||||
elfName = std::string(argv[++i]);
|
||||
} else {
|
||||
messagePrinter.printf("Unknown argument %s\n", argv[i]);
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
for (size_t argIndex = 2; argIndex < args.size(); ++argIndex) {
|
||||
const auto &currArg = args[argIndex];
|
||||
const bool hasMoreArgs = (argIndex + 1 < args.size());
|
||||
if ("-dump" == currArg && hasMoreArgs) {
|
||||
pathToDump = args[++argIndex];
|
||||
addSlash(pathToDump);
|
||||
} else if ("-device" == currArg && hasMoreArgs) {
|
||||
iga->setProductFamily(getProductFamilyFromDeviceName(args[++argIndex]));
|
||||
} else if ("-out" == currArg && hasMoreArgs) {
|
||||
elfName = args[++argIndex];
|
||||
} else if ("-ignore_isa_padding" == currArg) {
|
||||
ignoreIsaPadding = true;
|
||||
} else if ("-q" == currArg) {
|
||||
this->messagePrinter = MessagePrinter{true};
|
||||
iga->setMessagePrinter(this->messagePrinter);
|
||||
} else {
|
||||
if (!strcmp(argv[i], "-ignore_isa_padding")) {
|
||||
ignoreIsaPadding = true;
|
||||
} else {
|
||||
messagePrinter.printf("Unknown argument %s\n", argv[i]);
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
messagePrinter.printf("Unknown argument %s\n", currArg.c_str());
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (pathToDump.empty()) {
|
||||
messagePrinter.printf("Warning : Path to dump folder not specificed - using ./dump as default.\n");
|
||||
pathToDump = "dump";
|
||||
addSlash(pathToDump);
|
||||
if (!argHelper->outputEnabled()) {
|
||||
messagePrinter.printf("Warning : Path to dump folder not specificed - using ./dump as default.\n");
|
||||
pathToDump = "dump";
|
||||
addSlash(pathToDump);
|
||||
}
|
||||
}
|
||||
if (elfName.find(".bin") == std::string::npos) {
|
||||
messagePrinter.printf(".bin extension is expected for binary file.\n");
|
||||
|
@ -428,11 +408,3 @@ int BinaryEncoder::writeDeviceBinary(const std::string &line, std::ostream &devi
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool BinaryEncoder::fileExists(const std::string &path) const {
|
||||
return ::fileExists(path);
|
||||
}
|
||||
|
||||
std::vector<char> BinaryEncoder::readBinaryFile(const std::string &path) const {
|
||||
return ::readBinaryFile(path);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
#include "offline_compiler/ocloc_arg_helper.h"
|
||||
|
||||
#include "helper.h"
|
||||
#include "iga_wrapper.h"
|
||||
|
||||
|
@ -17,15 +19,20 @@ class BinaryEncoder {
|
|||
public:
|
||||
BinaryEncoder() : iga(new IgaWrapper) {
|
||||
iga->setMessagePrinter(messagePrinter);
|
||||
argHelper = std::make_unique<OclocArgHelper>();
|
||||
}
|
||||
BinaryEncoder(const std::string &dump, const std::string &elf)
|
||||
: pathToDump(dump), elfName(elf){};
|
||||
BinaryEncoder(std::unique_ptr<OclocArgHelper> helper) : argHelper(std::move(helper)), iga(new IgaWrapper) {
|
||||
iga->setMessagePrinter(messagePrinter);
|
||||
}
|
||||
int encode();
|
||||
int validateInput(uint32_t argc, const char **argv);
|
||||
int validateInput(const std::vector<std::string> &args);
|
||||
|
||||
void setMessagePrinter(const MessagePrinter &messagePrinter);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<OclocArgHelper> argHelper = nullptr;
|
||||
bool ignoreIsaPadding = false;
|
||||
std::string pathToDump, elfName;
|
||||
MessagePrinter messagePrinter;
|
||||
|
@ -35,7 +42,7 @@ class BinaryEncoder {
|
|||
bool copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary) {
|
||||
return copyBinaryToBinary(srcFileName, outBinary, nullptr);
|
||||
}
|
||||
int createElf();
|
||||
int createElf(std::stringstream &deviceBinary);
|
||||
void printHelp();
|
||||
int processBinary(const std::vector<std::string> &ptmFile, std::ostream &deviceBinary);
|
||||
int processKernel(size_t &i, const std::vector<std::string> &ptmFileLines, std::ostream &deviceBinary);
|
||||
|
@ -43,6 +50,4 @@ class BinaryEncoder {
|
|||
void write(std::stringstream &in, std::ostream &deviceBinary);
|
||||
int writeDeviceBinary(const std::string &line, std::ostream &deviceBinary);
|
||||
void addPadding(std::ostream &out, size_t numBytes);
|
||||
MOCKABLE_VIRTUAL bool fileExists(const std::string &path) const;
|
||||
MOCKABLE_VIRTUAL std::vector<char> readBinaryFile(const std::string &path) const;
|
||||
};
|
||||
|
|
|
@ -1,128 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/os_interface/os_library.h"
|
||||
#include "ocloc_wrapper.h"
|
||||
|
||||
#include "offline_compiler/multi_command.h"
|
||||
#include "offline_compiler/ocloc_fatbinary.h"
|
||||
#include "offline_compiler/offline_compiler.h"
|
||||
|
||||
#include "decoder/binary_decoder.h"
|
||||
#include "decoder/binary_encoder.h"
|
||||
#include <CL/cl.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
void printHelp() {
|
||||
printf(R"===(ocloc is a tool for managing Intel OpenCL GPU device binary format.
|
||||
It can be used for generation (as part of 'compile' command) as well as
|
||||
manipulation (decoding/modifying - as part of 'disasm'/'asm' commands) of such
|
||||
binary files.
|
||||
Intel OpenCL GPU device binary is a format used by Intel OpenCL GPU runtime
|
||||
(aka NEO). Intel OpenCL GPU runtime will return this binary format when queried
|
||||
using clGetProgramInfo(..., CL_PROGRAM_BINARIES, ...). It will also honor
|
||||
this format as input to clCreateProgramWithBinary function call.
|
||||
ocloc does not require Intel GPU device to be present in the system nor does it
|
||||
depend on Intel OpenCL GPU runtime driver to be installed. It does however rely
|
||||
on the same set of compilers (IGC, common_clang) as the runtime driver.
|
||||
|
||||
Usage: ocloc [--help] <command> [<command_args>]
|
||||
Available commands are listed below.
|
||||
Use 'ocloc <command> --help' to get help about specific command.
|
||||
|
||||
Commands:
|
||||
compile Compiles input to Intel OpenCL GPU device binary.
|
||||
disasm Disassembles Intel OpenCL GPU device binary.
|
||||
asm Assembles Intel OpenCL GPU device binary.
|
||||
multi Compiles multiple files using a config file.
|
||||
|
||||
Default command (when none provided) is 'compile'.
|
||||
|
||||
Examples:
|
||||
Compile file to Intel OpenCL GPU device binary (out = source_file_Gen9core.bin)
|
||||
ocloc -file source_file.cl -device skl
|
||||
|
||||
Disassemble Intel OpenCL GPU device binary
|
||||
ocloc disasm -file source_file_Gen9core.bin
|
||||
|
||||
Assemble to Intel OpenCL GPU device binary (after above disasm)
|
||||
ocloc asm -out reassembled.bin
|
||||
)===");
|
||||
}
|
||||
|
||||
int main(int numArgs, const char *argv[]) {
|
||||
try {
|
||||
if (numArgs == 1 || (numArgs > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))) {
|
||||
printHelp();
|
||||
} else if (numArgs > 1 && !strcmp(argv[1], "disasm")) {
|
||||
BinaryDecoder disasm;
|
||||
int retVal = disasm.validateInput(numArgs, argv);
|
||||
if (retVal == 0) {
|
||||
return disasm.decode();
|
||||
} else {
|
||||
return retVal;
|
||||
}
|
||||
} else if (numArgs > 1 && !strcmp(argv[1], "asm")) {
|
||||
BinaryEncoder assembler;
|
||||
int retVal = assembler.validateInput(numArgs, argv);
|
||||
if (retVal == 0) {
|
||||
return assembler.encode();
|
||||
} else {
|
||||
return retVal;
|
||||
}
|
||||
} else if (numArgs > 1 && (!strcmp(argv[1], "multi") || !strcmp(argv[1], "-multi"))) {
|
||||
int retValue = CL_SUCCESS;
|
||||
std::vector<std::string> allArgs;
|
||||
if (numArgs > 1) {
|
||||
allArgs.assign(argv, argv + numArgs);
|
||||
}
|
||||
auto pMulti = std::unique_ptr<MultiCommand>(MultiCommand::create(allArgs, retValue));
|
||||
return retValue;
|
||||
} else {
|
||||
if (requestedFatBinary(numArgs, argv)) {
|
||||
return buildFatbinary(numArgs, argv);
|
||||
}
|
||||
|
||||
int retVal = CL_SUCCESS;
|
||||
std::vector<std::string> allArgs;
|
||||
if (numArgs > 1) {
|
||||
allArgs.assign(argv, argv + numArgs);
|
||||
}
|
||||
|
||||
OfflineCompiler *pCompiler = OfflineCompiler::create(numArgs, allArgs, true, retVal);
|
||||
|
||||
if (retVal == CL_SUCCESS) {
|
||||
retVal = buildWithSafetyGuard(pCompiler);
|
||||
|
||||
std::string buildLog = pCompiler->getBuildLog();
|
||||
if (buildLog.empty() == false) {
|
||||
printf("%s\n", buildLog.c_str());
|
||||
}
|
||||
|
||||
if (retVal == CL_SUCCESS) {
|
||||
if (!pCompiler->isQuiet())
|
||||
printf("Build succeeded.\n");
|
||||
} else {
|
||||
printf("Build failed with error code: %d\n", retVal);
|
||||
printf("Command was:");
|
||||
for (auto i = 0; i < numArgs; ++i)
|
||||
printf(" %s", argv[i]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
delete pCompiler;
|
||||
return retVal;
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
printf("%s\n", e.what());
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
int main(int argc, const char *argv[]) {
|
||||
OclocWrapper oclocWrapper;
|
||||
return oclocWrapper.invokeOcloc(argc, argv);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ocloc_api.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void printHelp() {
|
||||
printf(R"===(ocloc is a tool for managing Intel OpenCL GPU device binary format.
|
||||
It can be used for generation (as part of 'compile' command) as well as
|
||||
manipulation (decoding/modifying - as part of 'disasm'/'asm' commands) of such
|
||||
binary files.
|
||||
Intel OpenCL GPU device binary is a format used by Intel OpenCL GPU runtime
|
||||
(aka NEO). Intel OpenCL GPU runtime will return this binary format when queried
|
||||
using clGetProgramInfo(..., CL_PROGRAM_BINARIES, ...). It will also honor
|
||||
this format as input to clCreateProgramWithBinary function call.
|
||||
ocloc does not require Intel GPU device to be present in the system nor does it
|
||||
depend on Intel OpenCL GPU runtime driver to be installed. It does however rely
|
||||
on the same set of compilers (IGC, common_clang) as the runtime driver.
|
||||
|
||||
Usage: ocloc [--help] <command> [<command_args>]
|
||||
Available commands are listed below.
|
||||
Use 'ocloc <command> --help' to get help about specific command.
|
||||
|
||||
Commands:
|
||||
compile Compiles input to Intel OpenCL GPU device binary.
|
||||
disasm Disassembles Intel OpenCL GPU device binary.
|
||||
asm Assembles Intel OpenCL GPU device binary.
|
||||
multi Compiles multiple files using a config file.
|
||||
|
||||
Default command (when none provided) is 'compile'.
|
||||
|
||||
Examples:
|
||||
Compile file to Intel OpenCL GPU device binary (out = source_file_Gen9core.bin)
|
||||
ocloc -file source_file.cl -device skl
|
||||
|
||||
Disassemble Intel OpenCL GPU device binary
|
||||
ocloc disasm -file source_file_Gen9core.bin
|
||||
|
||||
Assemble to Intel OpenCL GPU device binary (after above disasm)
|
||||
ocloc asm -out reassembled.bin
|
||||
)===");
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
int oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
const uint32_t numSources, const uint8_t **dataSources, const uint64_t *lenSources, const char **nameSources,
|
||||
const uint32_t numInputHeaders, const uint8_t **dataInputHeaders, const uint64_t *lenInputHeaders, const char **nameInputHeaders,
|
||||
uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs) {
|
||||
auto helper = std::make_unique<OclocArgHelper>(
|
||||
numSources, dataSources, lenSources, nameSources,
|
||||
numInputHeaders, dataInputHeaders, lenInputHeaders, nameInputHeaders,
|
||||
numOutputs, dataOutputs, lenOutputs, nameOutputs);
|
||||
std::vector<std::string> allArgs;
|
||||
if (numArgs > 1) {
|
||||
allArgs.assign(argv, argv + numArgs);
|
||||
}
|
||||
|
||||
try {
|
||||
if (numArgs == 1 || (numArgs > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))) {
|
||||
printHelp();
|
||||
} else if (numArgs > 1 && !strcmp(argv[1], "disasm")) {
|
||||
BinaryDecoder disasm(std::move(helper));
|
||||
int retVal = disasm.validateInput(allArgs);
|
||||
if (retVal == 0) {
|
||||
return disasm.decode();
|
||||
} else {
|
||||
return retVal;
|
||||
}
|
||||
} else if (numArgs > 1 && !strcmp(argv[1], "asm")) {
|
||||
BinaryEncoder assembler(std::move(helper));
|
||||
int retVal = assembler.validateInput(allArgs);
|
||||
if (retVal == 0) {
|
||||
return assembler.encode();
|
||||
} else {
|
||||
return retVal;
|
||||
}
|
||||
} else if (numArgs > 1 && (!strcmp(argv[1], "multi") || !strcmp(argv[1], "-multi"))) {
|
||||
int retValue = CL_SUCCESS;
|
||||
auto pMulti = std::unique_ptr<MultiCommand>(MultiCommand::create(allArgs, retValue));
|
||||
return retValue;
|
||||
} else {
|
||||
int retVal = CL_SUCCESS;
|
||||
std::vector<std::string> allArgs;
|
||||
if (numArgs > 1) {
|
||||
allArgs.assign(argv, argv + numArgs);
|
||||
}
|
||||
|
||||
OfflineCompiler *pCompiler = OfflineCompiler::create(numArgs, allArgs, true, retVal, std::move(helper));
|
||||
|
||||
if (retVal == CL_SUCCESS) {
|
||||
retVal = buildWithSafetyGuard(pCompiler);
|
||||
|
||||
std::string buildLog = pCompiler->getBuildLog();
|
||||
if (buildLog.empty() == false) {
|
||||
printf("%s\n", buildLog.c_str());
|
||||
}
|
||||
|
||||
if (retVal == CL_SUCCESS) {
|
||||
if (!pCompiler->isQuiet())
|
||||
printf("Build succeeded.\n");
|
||||
} else {
|
||||
printf("Build failed with error code: %d\n", retVal);
|
||||
}
|
||||
}
|
||||
delete pCompiler;
|
||||
return retVal;
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
printf("%s\n", e.what());
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int oclocFreeOutput(uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs) {
|
||||
for (uint32_t i = 0; i < *numOutputs; i++) {
|
||||
delete[](*dataOutputs)[i];
|
||||
delete[](*nameOutputs)[i];
|
||||
}
|
||||
delete[](*dataOutputs);
|
||||
delete[](*lenOutputs);
|
||||
delete[](*nameOutputs);
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "offline_compiler/multi_command.h"
|
||||
#include "offline_compiler/offline_compiler.h"
|
||||
|
||||
#include "decoder/binary_decoder.h"
|
||||
#include "decoder/binary_encoder.h"
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SIGNATURE __declspec(dllexport) int __cdecl
|
||||
#else
|
||||
#define SIGNATURE int
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
SIGNATURE oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
const uint32_t numSources, const uint8_t **dataSources, const uint64_t *lenSources, const char **nameSources,
|
||||
const uint32_t numInputHeaders, const uint8_t **dataInputHeaders, const uint64_t *lenInputHeaders, const char **nameInputHeaders,
|
||||
uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs);
|
||||
SIGNATURE oclocFreeOutput(uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs);
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ocloc_arg_helper.h"
|
||||
|
||||
#include "shared/source/helpers/file_io.h"
|
||||
#include "shared/source/helpers/string.h"
|
||||
|
||||
#include "decoder/helper.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
void Source::toVectorOfStrings(std::vector<std::string> &lines, bool replaceTabs) {
|
||||
std::string line;
|
||||
const char *file = reinterpret_cast<const char *>(data);
|
||||
|
||||
while (*file != '\0') {
|
||||
if (replaceTabs && *file == '\t') {
|
||||
line += ' ';
|
||||
} else if (*file == '\n') {
|
||||
lines.push_back(line);
|
||||
line = "";
|
||||
} else {
|
||||
line += *file;
|
||||
}
|
||||
file++;
|
||||
}
|
||||
}
|
||||
|
||||
Output::Output(const std::string &name, const void *data, const size_t &size)
|
||||
: name(name), size(size) {
|
||||
this->data = new uint8_t[size];
|
||||
memcpy_s(reinterpret_cast<void *>(this->data), this->size, data, size);
|
||||
};
|
||||
|
||||
OclocArgHelper::OclocArgHelper(const uint32_t numSources, const uint8_t **dataSources,
|
||||
const uint64_t *lenSources, const char **nameSources,
|
||||
const uint32_t numInputHeaders,
|
||||
const uint8_t **dataInputHeaders,
|
||||
const uint64_t *lenInputHeaders, const char **nameInputHeaders,
|
||||
uint32_t *numOutputs, uint8_t ***dataOutputs,
|
||||
uint64_t **lenOutputs, char ***nameOutputs)
|
||||
: numOutputs(numOutputs), nameOutputs(nameOutputs),
|
||||
dataOutputs(dataOutputs), lenOutputs(lenOutputs), hasOutput(numOutputs != nullptr) {
|
||||
for (uint32_t i = 0; i < numSources; ++i) {
|
||||
inputs.push_back(Source(dataSources[i], lenSources[i], nameSources[i]));
|
||||
}
|
||||
for (uint32_t i = 0; i < numInputHeaders; ++i) {
|
||||
headers.push_back(Source(dataInputHeaders[i], lenInputHeaders[i], nameInputHeaders[i]));
|
||||
}
|
||||
}
|
||||
|
||||
OclocArgHelper::~OclocArgHelper() {
|
||||
if (outputEnabled()) {
|
||||
moveOutputs();
|
||||
}
|
||||
}
|
||||
|
||||
bool OclocArgHelper::fileExists(const std::string &filename) const {
|
||||
return sourceFileExists(filename) || ::fileExists(filename);
|
||||
}
|
||||
|
||||
void OclocArgHelper::moveOutputs() {
|
||||
*numOutputs = static_cast<uint32_t>(outputs.size());
|
||||
*nameOutputs = new char *[outputs.size()];
|
||||
*dataOutputs = new uint8_t *[outputs.size()];
|
||||
*lenOutputs = new uint64_t[outputs.size()];
|
||||
for (size_t i = 0; i < outputs.size(); ++i) {
|
||||
(*nameOutputs)[i] = new char[outputs[i]->name.length() + 1];
|
||||
strncpy((*nameOutputs)[i], outputs[i]->name.c_str(), outputs[i]->name.length() + 1);
|
||||
(*dataOutputs)[i] = outputs[i]->data;
|
||||
(*lenOutputs)[i] = outputs[i]->size;
|
||||
}
|
||||
}
|
||||
|
||||
Source *OclocArgHelper::findSourceFile(const std::string &filename) {
|
||||
for (auto &source : inputs) {
|
||||
if (filename == source.name) {
|
||||
return &source;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool OclocArgHelper::sourceFileExists(const std::string &filename) const {
|
||||
for (auto &input : inputs) {
|
||||
if (filename == input.name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> OclocArgHelper::headersToVectorOfStrings() {
|
||||
std::vector<std::string> lines;
|
||||
for (auto &header : headers) {
|
||||
header.toVectorOfStrings(lines, true);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
void OclocArgHelper::readFileToVectorOfStrings(const std::string &filename, std::vector<std::string> &lines) {
|
||||
if (Source *s = findSourceFile(filename)) {
|
||||
s->toVectorOfStrings(lines);
|
||||
} else {
|
||||
::readFileToVectorOfStrings(lines, filename);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<char> OclocArgHelper::readBinaryFile(const std::string &filename) {
|
||||
if (Source *s = findSourceFile(filename)) {
|
||||
return s->toBinaryVector();
|
||||
} else {
|
||||
return ::readBinaryFile(filename);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<char[]> OclocArgHelper::loadDataFromFile(const std::string &filename, size_t &retSize) {
|
||||
if (Source *s = findSourceFile(filename)) {
|
||||
std::unique_ptr<char[]> ret(new char[static_cast<unsigned int>(s->length)]());
|
||||
memcpy(ret.get(), s->data, static_cast<size_t>(s->length));
|
||||
retSize = static_cast<size_t>(s->length);
|
||||
return ret;
|
||||
} else {
|
||||
return ::loadDataFromFile(filename.c_str(), retSize);
|
||||
}
|
||||
}
|
||||
|
||||
void OclocArgHelper::saveOutput(const std::string &filename, const void *pData, const size_t &dataSize) {
|
||||
if (outputEnabled()) {
|
||||
addOutput(filename, pData, dataSize);
|
||||
} else {
|
||||
writeDataToFile(filename.c_str(), pData, dataSize);
|
||||
}
|
||||
}
|
||||
|
||||
void OclocArgHelper::saveOutput(const std::string &filename, std::ostream &stream) {
|
||||
std::stringstream ss;
|
||||
ss << stream.rdbuf();
|
||||
if (outputEnabled()) {
|
||||
addOutput(filename, ss.str().c_str(), ss.str().length());
|
||||
} else {
|
||||
std::ofstream file(filename);
|
||||
file << ss.str();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#pragma once
|
||||
|
||||
struct Source {
|
||||
const uint8_t *data;
|
||||
const uint64_t length;
|
||||
const char *name;
|
||||
Source(const uint8_t *data, const uint64_t length, const char *name)
|
||||
: data(data), length(length), name(name){};
|
||||
void toVectorOfStrings(std::vector<std::string> &lines, bool replaceTabs = false);
|
||||
inline std::vector<char> toBinaryVector() {
|
||||
return std::vector<char>(data, data + length);
|
||||
};
|
||||
};
|
||||
|
||||
struct Output {
|
||||
std::string name;
|
||||
uint8_t *data;
|
||||
const size_t size;
|
||||
Output(const std::string &name, const void *data, const size_t &size);
|
||||
};
|
||||
|
||||
class OclocArgHelper {
|
||||
protected:
|
||||
std::vector<Source> inputs, headers;
|
||||
std::vector<Output *> outputs;
|
||||
uint32_t *numOutputs = nullptr;
|
||||
char ***nameOutputs = nullptr;
|
||||
uint8_t ***dataOutputs = nullptr;
|
||||
uint64_t **lenOutputs = nullptr;
|
||||
bool hasOutput = false;
|
||||
void moveOutputs();
|
||||
|
||||
Source *findSourceFile(const std::string &filename);
|
||||
bool sourceFileExists(const std::string &filename) const;
|
||||
|
||||
inline void addOutput(const std::string &filename, const void *data, const size_t &size) {
|
||||
outputs.push_back(new Output(filename, data, size));
|
||||
}
|
||||
|
||||
public:
|
||||
OclocArgHelper() = default;
|
||||
OclocArgHelper(const uint32_t numSources, const uint8_t **dataSources,
|
||||
const uint64_t *lenSources, const char **nameSources,
|
||||
const uint32_t numInputHeaders,
|
||||
const uint8_t **dataInputHeaders,
|
||||
const uint64_t *lenInputHeaders, const char **nameInputHeaders,
|
||||
uint32_t *numOutputs, uint8_t ***dataOutputs,
|
||||
uint64_t **lenOutputs, char ***nameOutputs);
|
||||
virtual ~OclocArgHelper();
|
||||
|
||||
MOCKABLE_VIRTUAL bool fileExists(const std::string &filename) const;
|
||||
|
||||
std::vector<std::string> headersToVectorOfStrings();
|
||||
void readFileToVectorOfStrings(const std::string &filename, std::vector<std::string> &lines);
|
||||
MOCKABLE_VIRTUAL std::vector<char> readBinaryFile(const std::string &filename);
|
||||
std::unique_ptr<char[]> loadDataFromFile(const std::string &filename, size_t &retSize);
|
||||
|
||||
inline bool outputEnabled() { return hasOutput; }
|
||||
inline bool hasHeaders() { return headers.size() > 0; }
|
||||
void saveOutput(const std::string &filename, const void *pData, const size_t &dataSize);
|
||||
void saveOutput(const std::string &filename, std::ostream &stream);
|
||||
|
||||
void addInput(const std::string &filename, std::stringstream &stream);
|
||||
};
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ocloc_wrapper.h"
|
||||
|
||||
#include "shared/source/os_interface/os_library.h"
|
||||
|
||||
#include "utilities/get_path.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
typedef int (*pOclocInvoke)(
|
||||
unsigned int numArgs, const char *argv[],
|
||||
const uint32_t numSources, const uint8_t **dataSources, const uint64_t *lenSources, const char **nameSources,
|
||||
const uint32_t numInputHeaders, const uint8_t **dataInputHeaders, const uint64_t *lenInputHeaders, const char **nameInputHeaders,
|
||||
uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs);
|
||||
|
||||
typedef int (*pOclocFreeOutput)(
|
||||
uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs);
|
||||
|
||||
struct OclocLibrary {
|
||||
pOclocInvoke invoke = nullptr;
|
||||
pOclocFreeOutput freeOutput = nullptr;
|
||||
|
||||
std::unique_ptr<NEO::OsLibrary> library;
|
||||
bool isLoaded() {
|
||||
return library != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
OclocWrapper::OclocWrapper() : pImpl(std::make_unique<Impl>()){};
|
||||
OclocWrapper::~OclocWrapper() = default;
|
||||
|
||||
struct OclocWrapper::Impl {
|
||||
OclocLibrary oclocLib;
|
||||
|
||||
void loadOcloc() {
|
||||
OclocLibrary ocloc;
|
||||
std::string oclocLibName = getPath() + OCLOC_LIB_NAME;
|
||||
ocloc.library.reset(NEO::OsLibrary::load(oclocLibName));
|
||||
if (nullptr == ocloc.library) {
|
||||
std::cout << "Error! Couldn't find " << OCLOC_LIB_NAME << ".\n";
|
||||
return;
|
||||
}
|
||||
if (nullptr == (ocloc.invoke = reinterpret_cast<pOclocInvoke>(ocloc.library->getProcAddress("oclocInvoke")))) {
|
||||
std::cout << "Error! Couldn't find OclocInvoke function.\n";
|
||||
return;
|
||||
}
|
||||
if (nullptr == (ocloc.freeOutput = reinterpret_cast<pOclocFreeOutput>(ocloc.library->getProcAddress("oclocFreeOutput")))) {
|
||||
std::cout << "Error! Couldn't find OclocFreeOutput function.\n";
|
||||
return;
|
||||
}
|
||||
this->oclocLib = std::move(ocloc);
|
||||
}
|
||||
};
|
||||
|
||||
int OclocWrapper::invokeOcloc(unsigned int numArgs, const char *argv[]) {
|
||||
return invokeOcloc(numArgs, argv, 0, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
int OclocWrapper::invokeOcloc(unsigned int numArgs, const char *argv[],
|
||||
const uint32_t numSources, const uint8_t **dataSources, const uint64_t *lenSources, const char **nameSources,
|
||||
const uint32_t numInputHeaders, const uint8_t **dataInputHeaders, const uint64_t *lenInputHeaders, const char **nameInputHeaders,
|
||||
uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs) {
|
||||
if (false == tryLoadOcloc()) {
|
||||
std::cout << "Error! Ocloc Library couldn't be loaded.\n";
|
||||
return -1;
|
||||
}
|
||||
return pImpl->oclocLib.invoke(numArgs, argv,
|
||||
numSources, dataSources, lenSources, nameSources,
|
||||
numInputHeaders, dataInputHeaders, lenInputHeaders, nameInputHeaders,
|
||||
numOutputs, dataOutputs, lenOutputs, nameOutputs);
|
||||
}
|
||||
|
||||
int OclocWrapper::freeOutput(uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs) {
|
||||
if (false == tryLoadOcloc()) {
|
||||
std::cout << "Error! Ocloc Library couldn't be loaded.\n";
|
||||
return -1;
|
||||
}
|
||||
return pImpl->oclocLib.freeOutput(numOutputs, dataOutputs, lenOutputs, nameOutputs);
|
||||
}
|
||||
|
||||
bool OclocWrapper::tryLoadOcloc() {
|
||||
if (false == pImpl->oclocLib.isLoaded()) {
|
||||
pImpl->loadOcloc();
|
||||
}
|
||||
return pImpl->oclocLib.isLoaded();
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cctype>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
struct OclocWrapper {
|
||||
public:
|
||||
OclocWrapper();
|
||||
~OclocWrapper();
|
||||
|
||||
OclocWrapper(OclocWrapper &) = delete;
|
||||
OclocWrapper(const OclocWrapper &&) = delete;
|
||||
OclocWrapper &operator=(const OclocWrapper &) = delete;
|
||||
OclocWrapper &operator=(OclocWrapper &&) = delete;
|
||||
|
||||
int invokeOcloc(unsigned int numArgs, const char *argv[]);
|
||||
int invokeOcloc(unsigned int numArgs, const char *argv[],
|
||||
const uint32_t numSources, const uint8_t **dataSources, const uint64_t *lenSources, const char **nameSources,
|
||||
const uint32_t numInputHeaders, const uint8_t **dataInputHeaders, const uint64_t *lenInputHeaders, const char **nameInputHeaders,
|
||||
uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs);
|
||||
int freeOutput(uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs);
|
||||
|
||||
protected:
|
||||
bool tryLoadOcloc();
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> pImpl;
|
||||
};
|
|
@ -78,6 +78,24 @@ OfflineCompiler *OfflineCompiler::create(size_t numArgs, const std::vector<std::
|
|||
auto pOffCompiler = new OfflineCompiler();
|
||||
|
||||
if (pOffCompiler) {
|
||||
pOffCompiler->argHelper = std::make_unique<OclocArgHelper>();
|
||||
retVal = pOffCompiler->initialize(numArgs, allArgs, dumpFiles);
|
||||
}
|
||||
|
||||
if (retVal != CL_SUCCESS) {
|
||||
delete pOffCompiler;
|
||||
pOffCompiler = nullptr;
|
||||
}
|
||||
|
||||
return pOffCompiler;
|
||||
}
|
||||
|
||||
OfflineCompiler *OfflineCompiler::create(size_t numArgs, const std::vector<std::string> &allArgs, bool dumpFiles, int &retVal, std::unique_ptr<OclocArgHelper> helper) {
|
||||
retVal = CL_SUCCESS;
|
||||
auto pOffCompiler = new OfflineCompiler();
|
||||
|
||||
if (pOffCompiler) {
|
||||
pOffCompiler->argHelper = std::move(helper);
|
||||
retVal = pOffCompiler->initialize(numArgs, allArgs, dumpFiles);
|
||||
}
|
||||
|
||||
|
@ -256,7 +274,7 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector<std::string> &
|
|||
oclocOptionsFileName.append("_ocloc_options.txt");
|
||||
|
||||
std::string oclocOptionsFromFile;
|
||||
bool oclocOptionsRead = readOptionsFromFile(oclocOptionsFromFile, oclocOptionsFileName);
|
||||
bool oclocOptionsRead = readOptionsFromFile(oclocOptionsFromFile, oclocOptionsFileName, argHelper);
|
||||
if (oclocOptionsRead && !isQuiet()) {
|
||||
printf("Building with ocloc options:\n%s\n", oclocOptionsFromFile.c_str());
|
||||
}
|
||||
|
@ -275,7 +293,7 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector<std::string> &
|
|||
std::string optionsFileName = inputFile.substr(0, ext_start);
|
||||
optionsFileName.append("_options.txt");
|
||||
|
||||
bool optionsRead = readOptionsFromFile(options, optionsFileName);
|
||||
bool optionsRead = readOptionsFromFile(options, optionsFileName, argHelper);
|
||||
if (optionsRead && !isQuiet()) {
|
||||
printf("Building with options:\n%s\n", options.c_str());
|
||||
}
|
||||
|
@ -284,7 +302,7 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector<std::string> &
|
|||
internalOptionsFileName.append("_internal_options.txt");
|
||||
|
||||
std::string internalOptionsFromFile;
|
||||
bool internalOptionsRead = readOptionsFromFile(internalOptionsFromFile, internalOptionsFileName);
|
||||
bool internalOptionsRead = readOptionsFromFile(internalOptionsFromFile, internalOptionsFileName, argHelper);
|
||||
if (internalOptionsRead && !isQuiet()) {
|
||||
printf("Building with internal options:\n%s\n", internalOptionsFromFile.c_str());
|
||||
}
|
||||
|
@ -295,7 +313,7 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector<std::string> &
|
|||
parseDebugSettings();
|
||||
|
||||
// set up the device inside the program
|
||||
sourceFromFile = loadDataFromFile(inputFile.c_str(), sourceFromFileSize);
|
||||
sourceFromFile = argHelper->loadDataFromFile(inputFile, sourceFromFileSize);
|
||||
if (sourceFromFileSize == 0) {
|
||||
retVal = INVALID_FILE;
|
||||
return retVal;
|
||||
|
@ -507,7 +525,7 @@ int OfflineCompiler::parseCommandLine(size_t numArgs, const std::vector<std::str
|
|||
} else if (deviceName.empty()) {
|
||||
printf("Error: Device name missing.\n");
|
||||
retVal = INVALID_COMMAND_LINE;
|
||||
} else if (!fileExists(inputFile)) {
|
||||
} else if (!argHelper->fileExists(inputFile)) {
|
||||
printf("Error: Input file %s missing.\n", inputFile.c_str());
|
||||
retVal = INVALID_FILE;
|
||||
} else {
|
||||
|
@ -828,24 +846,18 @@ void OfflineCompiler::writeOutAllFiles() {
|
|||
if (irBinary) {
|
||||
std::string irOutputFileName = generateFilePathForIr(fileBase) + generateOptsSuffix();
|
||||
|
||||
writeDataToFile(
|
||||
irOutputFileName.c_str(),
|
||||
irBinary,
|
||||
irBinarySize);
|
||||
argHelper->saveOutput(irOutputFileName, irBinary, irBinarySize);
|
||||
}
|
||||
|
||||
if (genBinary) {
|
||||
std::string genOutputFile = generateFilePath(outputDirectory, fileBase, ".gen") + generateOptsSuffix();
|
||||
|
||||
writeDataToFile(
|
||||
genOutputFile.c_str(),
|
||||
genBinary,
|
||||
genBinarySize);
|
||||
argHelper->saveOutput(genOutputFile, genBinary, genBinarySize);
|
||||
|
||||
if (useCppFile) {
|
||||
std::string cppOutputFile = generateFilePath(outputDirectory, fileBase, ".cpp");
|
||||
std::string cpp = parseBinAsCharArray((uint8_t *)genBinary, genBinarySize, fileTrunk);
|
||||
writeDataToFile(cppOutputFile.c_str(), cpp.c_str(), cpp.size());
|
||||
argHelper->saveOutput(cppOutputFile, cpp.c_str(), cpp.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -856,8 +868,8 @@ void OfflineCompiler::writeOutAllFiles() {
|
|||
} else {
|
||||
elfOutputFile = generateFilePath(outputDirectory, fileBase, ".bin") + generateOptsSuffix();
|
||||
}
|
||||
writeDataToFile(
|
||||
elfOutputFile.c_str(),
|
||||
argHelper->saveOutput(
|
||||
elfOutputFile,
|
||||
elfBinary.data(),
|
||||
elfBinary.size());
|
||||
}
|
||||
|
@ -865,19 +877,19 @@ void OfflineCompiler::writeOutAllFiles() {
|
|||
if (debugDataBinary) {
|
||||
std::string debugOutputFile = generateFilePath(outputDirectory, fileBase, ".dbg") + generateOptsSuffix();
|
||||
|
||||
writeDataToFile(
|
||||
debugOutputFile.c_str(),
|
||||
argHelper->saveOutput(
|
||||
debugOutputFile,
|
||||
debugDataBinary,
|
||||
debugDataBinarySize);
|
||||
}
|
||||
}
|
||||
|
||||
bool OfflineCompiler::readOptionsFromFile(std::string &options, const std::string &file) {
|
||||
if (!fileExists(file)) {
|
||||
bool OfflineCompiler::readOptionsFromFile(std::string &options, const std::string &file, std::unique_ptr<OclocArgHelper> &helper) {
|
||||
if (!helper->fileExists(file)) {
|
||||
return false;
|
||||
}
|
||||
size_t optionsSize = 0U;
|
||||
auto optionsFromFile = loadDataFromFile(file.c_str(), optionsSize);
|
||||
auto optionsFromFile = helper->loadDataFromFile(file, optionsSize);
|
||||
if (optionsSize > 0) {
|
||||
// Remove comment containing copyright header
|
||||
options = optionsFromFile.get();
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "shared/source/utilities/arrayref.h"
|
||||
#include "shared/source/utilities/const_stringref.h"
|
||||
|
||||
#include "offline_compiler/ocloc_arg_helper.h"
|
||||
|
||||
#include "cif/common/cif_main.h"
|
||||
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
||||
#include "ocl_igc_interface/igc_ocl_device_ctx.h"
|
||||
|
@ -38,6 +40,7 @@ std::string getDevicesTypes();
|
|||
class OfflineCompiler {
|
||||
public:
|
||||
static OfflineCompiler *create(size_t numArgs, const std::vector<std::string> &allArgs, bool dumpFiles, int &retVal);
|
||||
static OfflineCompiler *create(size_t numArgs, const std::vector<std::string> &allArgs, bool dumpFiles, int &retVal, std::unique_ptr<OclocArgHelper> helper);
|
||||
int build();
|
||||
std::string &getBuildLog();
|
||||
void printUsage();
|
||||
|
@ -51,7 +54,9 @@ class OfflineCompiler {
|
|||
}
|
||||
|
||||
std::string parseBinAsCharArray(uint8_t *binary, size_t size, std::string &fileName);
|
||||
static bool readOptionsFromFile(std::string &optionsOut, const std::string &file);
|
||||
|
||||
static bool readOptionsFromFile(std::string &optionsOut, const std::string &file, std::unique_ptr<OclocArgHelper> &helper);
|
||||
|
||||
ArrayRef<const uint8_t> getPackedDeviceBinaryOutput() {
|
||||
return this->elfBinary;
|
||||
}
|
||||
|
@ -126,5 +131,7 @@ class OfflineCompiler {
|
|||
CIF::RAII::UPtr_t<CIF::CIFMain> fclMain = nullptr;
|
||||
CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> fclDeviceCtx = nullptr;
|
||||
IGC::CodeType::CodeType_t preferredIntermediateRepresentation;
|
||||
|
||||
std::unique_ptr<OclocArgHelper> argHelper = nullptr;
|
||||
};
|
||||
} // namespace NEO
|
||||
|
|
|
@ -4,24 +4,27 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
set(CLOC_SRCS_UTILITIES
|
||||
set(CLOC_LIB_SRCS_UTILITIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/safety_caller.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/get_current_dir.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/get_path.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND CLOC_SRCS_UTILITIES
|
||||
list(APPEND CLOC_LIB_SRCS_UTILITIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/safety_caller_windows.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/safety_guard_windows.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/seh_exception.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/seh_exception.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/get_current_dir_windows.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/get_path.cpp
|
||||
)
|
||||
else()
|
||||
list(APPEND CLOC_SRCS_UTILITIES
|
||||
list(APPEND CLOC_LIB_SRCS_UTILITIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/safety_caller_linux.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/get_current_dir_linux.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/get_path.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(ocloc PRIVATE ${CLOC_SRCS_UTILITIES})
|
||||
target_sources(ocloc_lib PRIVATE ${CLOC_LIB_SRCS_UTILITIES})
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern std::string getPath();
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
std::string getPath() {
|
||||
char exepath[128] = {0};
|
||||
std::stringstream ss;
|
||||
ss << "/proc/" << getpid() << "/exe";
|
||||
if (readlink(ss.str().c_str(), exepath, 128) != -1) {
|
||||
std::string path = std::string(exepath);
|
||||
path = path.substr(0, path.find_last_of('/') + 1);
|
||||
return path;
|
||||
} else {
|
||||
return std::string("");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string getPath() {
|
||||
return std::string("");
|
||||
}
|
|
@ -64,11 +64,12 @@ function(compile_builtin gen_type platform_type builtin bits builtin_options)
|
|||
set(cloc_cmd_prefix ocloc)
|
||||
else()
|
||||
if(DEFINED NEO__IGC_LIBRARY_PATH)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=${NEO__IGC_LIBRARY_PATH} $<TARGET_FILE:ocloc>)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=${NEO__IGC_LIBRARY_PATH}:$<TARGET_FILE_DIR:ocloc_lib> $<TARGET_FILE:ocloc>)
|
||||
else()
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=$<TARGET_FILE_DIR:ocloc> $<TARGET_FILE:ocloc>)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=$<TARGET_FILE_DIR:ocloc_lib> $<TARGET_FILE:ocloc>)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND __cloc__options__ "-cl-kernel-arg-info")
|
||||
add_custom_command(
|
||||
OUTPUT ${OUTPUT_FILES}
|
||||
|
|
|
@ -35,9 +35,9 @@ function(compile_kernel target gen_type platform_type kernel)
|
|||
set(cloc_cmd_prefix ocloc)
|
||||
else()
|
||||
if(DEFINED NEO__IGC_LIBRARY_PATH)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=${NEO__IGC_LIBRARY_PATH} $<TARGET_FILE:ocloc>)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=${NEO__IGC_LIBRARY_PATH}:$<TARGET_FILE_DIR:ocloc_lib> $<TARGET_FILE:ocloc>)
|
||||
else()
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=$<TARGET_FILE_DIR:ocloc> $<TARGET_FILE:ocloc>)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=$<TARGET_FILE_DIR:ocloc_lib> $<TARGET_FILE:ocloc>)
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND __cloc__options__ "-cl-kernel-arg-info")
|
||||
|
|
|
@ -205,9 +205,9 @@ if(WIN32)
|
|||
set(cloc_cmd_prefix ocloc)
|
||||
else()
|
||||
if(DEFINED NEO__IGC_LIBRARY_PATH)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=${NEO__IGC_LIBRARY_PATH} $<TARGET_FILE:ocloc>)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=${NEO__IGC_LIBRARY_PATH}:$<TARGET_FILE_DIR:ocloc_lib> $<TARGET_FILE:ocloc>)
|
||||
else()
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=$<TARGET_FILE_DIR:ocloc> $<TARGET_FILE:ocloc>)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=$<TARGET_FILE_DIR:ocloc_lib> $<TARGET_FILE:ocloc>)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -20,15 +20,16 @@ ${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_encoder.h
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_iga_wrapper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_compiler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_sip_ocloc_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_argument_helper.h
|
||||
)
|
||||
|
||||
set(CLOC_SRCS_UTILITIES
|
||||
set(CLOC_LIB_SRCS_UTILITIES
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/safety_caller.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities//get_current_dir.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND CLOC_SRCS_UTILITIES
|
||||
list(APPEND CLOC_LIB_SRCS_UTILITIES
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/windows/safety_caller_windows.cpp
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/windows/safety_guard_windows.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/windows/seh_exception.cpp
|
||||
|
@ -36,7 +37,7 @@ if(WIN32)
|
|||
${NEO_SOURCE_DIR}/offline_compiler/utilities/windows/get_current_dir_windows.cpp
|
||||
)
|
||||
else()
|
||||
list(APPEND CLOC_SRCS_UTILITIES
|
||||
list(APPEND CLOC_LIB_SRCS_UTILITIES
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/linux/safety_caller_linux.cpp
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/linux/safety_guard_linux.h
|
||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/linux/get_current_dir_linux.cpp
|
||||
|
@ -62,8 +63,8 @@ set(IGDRCL_SRCS_offline_compiler_tests
|
|||
${IGDRCL_SRCS_cloc}
|
||||
${IGDRCL_SRCS_offline_compiler_mock}
|
||||
${IGDRCL_SRCS_tests_compiler_mocks}
|
||||
${CLOC_SRCS_LIB}
|
||||
${CLOC_SRCS_UTILITIES}
|
||||
${CLOC_LIB_SRCS_LIB}
|
||||
${CLOC_LIB_SRCS_UTILITIES}
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
@ -81,9 +82,9 @@ link_directories(${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
|||
add_executable(ocloc_tests ${IGDRCL_SRCS_offline_compiler_tests})
|
||||
|
||||
target_include_directories(ocloc_tests PRIVATE
|
||||
$<TARGET_PROPERTY:ocloc,INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:ocloc_lib,INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_compile_definitions(ocloc_tests PUBLIC MOCKABLE_VIRTUAL=virtual $<TARGET_PROPERTY:ocloc,INTERFACE_COMPILE_DEFINITIONS>)
|
||||
target_compile_definitions(ocloc_tests PUBLIC MOCKABLE_VIRTUAL=virtual $<TARGET_PROPERTY:ocloc_lib,INTERFACE_COMPILE_DEFINITIONS>)
|
||||
|
||||
target_link_libraries(ocloc_tests gmock-gtest)
|
||||
|
||||
|
@ -95,25 +96,25 @@ if(UNIX)
|
|||
target_link_libraries(ocloc_tests dl pthread)
|
||||
endif()
|
||||
|
||||
get_property(CLOC_FOLDER TARGET ocloc PROPERTY FOLDER)
|
||||
get_property(CLOC_COMPILE_FLAGS TARGET ocloc PROPERTY COMPILE_FLAGS)
|
||||
set_property(TARGET ocloc_tests PROPERTY FOLDER ${CLOC_FOLDER})
|
||||
set_property(TARGET ocloc_tests APPEND_STRING PROPERTY COMPILE_FLAGS ${CLOC_COMPILE_FLAGS})
|
||||
get_property(CLOC_LIB_FOLDER TARGET ocloc_lib PROPERTY FOLDER)
|
||||
get_property(CLOC_LIB_COMPILE_FLAGS TARGET ocloc_lib PROPERTY COMPILE_FLAGS)
|
||||
set_property(TARGET ocloc_tests PROPERTY FOLDER ${CLOC_LIB_FOLDER})
|
||||
set_property(TARGET ocloc_tests APPEND_STRING PROPERTY COMPILE_FLAGS ${CLOC_LIB_COMPILE_FLAGS})
|
||||
|
||||
string(TOLOWER ${DEFAULT_TESTED_PLATFORM} CLOC_DEFAULT_DEVICE)
|
||||
string(TOLOWER ${DEFAULT_TESTED_PLATFORM} CLOC_LIB_DEFAULT_DEVICE)
|
||||
|
||||
add_custom_target(run_ocloc_tests ALL
|
||||
DEPENDS ocloc_tests
|
||||
)
|
||||
macro(macro_for_each_platform)
|
||||
if("${PLATFORM_IT_LOWER}" STREQUAL "${CLOC_DEFAULT_DEVICE}")
|
||||
if("${PLATFORM_IT_LOWER}" STREQUAL "${CLOC_LIB_DEFAULT_DEVICE}")
|
||||
foreach(PLATFORM_TYPE ${PLATFORM_TYPES})
|
||||
if(${PLATFORM_IT}_IS_${PLATFORM_TYPE})
|
||||
get_family_name_with_type(${GEN_TYPE} ${PLATFORM_TYPE})
|
||||
add_dependencies(run_ocloc_tests prepare_test_kernels_${family_name_with_type})
|
||||
neo_copy_test_files(copy_test_files_${family_name_with_type} ${family_name_with_type})
|
||||
add_dependencies(run_ocloc_tests copy_test_files_${family_name_with_type})
|
||||
set(run_tests_cmd ocloc_tests --device ${CLOC_DEFAULT_DEVICE} --family_type ${family_name_with_type})
|
||||
set(run_tests_cmd ocloc_tests --device ${CLOC_LIB_DEFAULT_DEVICE} --family_type ${family_name_with_type})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
@ -123,17 +124,17 @@ macro(macro_for_each_gen)
|
|||
endmacro()
|
||||
apply_macro_for_each_gen("TESTED")
|
||||
|
||||
set_property(TARGET run_ocloc_tests PROPERTY FOLDER ${CLOC_FOLDER})
|
||||
set_property(TARGET run_ocloc_tests PROPERTY FOLDER ${CLOC_LIB_FOLDER})
|
||||
|
||||
if(WIN32)
|
||||
add_custom_command(
|
||||
TARGET run_ocloc_tests
|
||||
POST_BUILD
|
||||
COMMAND echo deleting offline compiler files and directories...
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/copybuffer_${CLOC_DEFAULT_DEVICE}.bc
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/copybuffer_${CLOC_DEFAULT_DEVICE}.gen
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/copybuffer_${CLOC_DEFAULT_DEVICE}.bin
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TargetDir}/${CLOC_DEFAULT_DEVICE}/offline_compiler_test
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/copybuffer_${CLOC_LIB_DEFAULT_DEVICE}.bc
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/copybuffer_${CLOC_LIB_DEFAULT_DEVICE}.gen
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/copybuffer_${CLOC_LIB_DEFAULT_DEVICE}.bin
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/offline_compiler_test
|
||||
COMMAND ${run_tests_cmd}
|
||||
WORKING_DIRECTORY ${TargetDir}
|
||||
)
|
||||
|
@ -142,10 +143,10 @@ else()
|
|||
TARGET run_ocloc_tests
|
||||
POST_BUILD
|
||||
COMMAND echo deleting offline compiler files and directories...
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/*.bc
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/*.gen
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/*.ll
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/*.bin
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/*.bc
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/*.gen
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/*.ll
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/*.bin
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory "${TargetDir}/offline_compiler_test"
|
||||
COMMAND ${run_tests_cmd}
|
||||
WORKING_DIRECTORY ${TargetDir}
|
||||
|
|
|
@ -29,7 +29,7 @@ SKernelBinaryHeaderCommon createKernelBinaryHeaderCommon(const uint32_t kernelNa
|
|||
|
||||
namespace NEO {
|
||||
TEST(DecoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
||||
const char *argv[] = {
|
||||
std::vector<std::string> args = {
|
||||
"ocloc",
|
||||
"decoder",
|
||||
"-file",
|
||||
|
@ -40,22 +40,22 @@ TEST(DecoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
|||
"test_files/created"};
|
||||
|
||||
MockDecoder decoder;
|
||||
EXPECT_EQ(0, decoder.validateInput(static_cast<uint32_t>(arrayCount<const char *>(argv)), argv));
|
||||
EXPECT_EQ(0, decoder.validateInput(args));
|
||||
}
|
||||
|
||||
TEST(DecoderTests, WhenMissingParametersThenValidateInputReturnsErrorCode) {
|
||||
const char *argv[] = {
|
||||
std::vector<std::string> args = {
|
||||
"ocloc",
|
||||
"decoder",
|
||||
"-patch",
|
||||
"test_files"};
|
||||
|
||||
MockDecoder decoder;
|
||||
EXPECT_NE(0, decoder.validateInput(static_cast<uint32_t>(arrayCount<const char *>(argv)), argv));
|
||||
EXPECT_NE(0, decoder.validateInput(args));
|
||||
}
|
||||
|
||||
TEST(DecoderTests, GivenWrongParametersWhenParsingParametersThenValidateInputReturnsErrorCode) {
|
||||
const char *argv[] = {
|
||||
std::vector<std::string> args = {
|
||||
"cloc",
|
||||
"decoder",
|
||||
"-file",
|
||||
|
@ -66,7 +66,7 @@ TEST(DecoderTests, GivenWrongParametersWhenParsingParametersThenValidateInputRet
|
|||
"test_files/created"};
|
||||
|
||||
MockDecoder decoder;
|
||||
EXPECT_NE(0, decoder.validateInput(static_cast<uint32_t>(arrayCount<const char *>(argv)), argv));
|
||||
EXPECT_NE(0, decoder.validateInput(args));
|
||||
}
|
||||
|
||||
TEST(DecoderTests, GivenValidSizeStringWhenGettingSizeThenProperOutcomeIsExpectedAndExceptionIsNotThrown) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
namespace NEO {
|
||||
TEST(EncoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
||||
const char *argv[] = {
|
||||
std::vector<std::string> args = {
|
||||
"ocloc",
|
||||
"asm",
|
||||
"-dump",
|
||||
|
@ -26,11 +26,11 @@ TEST(EncoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
|||
"test_files/binary_gen.bin"};
|
||||
|
||||
MockEncoder encoder;
|
||||
EXPECT_EQ(0, encoder.validateInput(static_cast<uint32_t>(arrayCount<const char *>(argv)), argv));
|
||||
EXPECT_EQ(0, encoder.validateInput(args));
|
||||
}
|
||||
|
||||
TEST(EncoderTests, WhenMissingParametersThenErrorCodeIsReturned) {
|
||||
const char *argv[] = {
|
||||
std::vector<std::string> args = {
|
||||
"ocloc",
|
||||
"asm",
|
||||
"-dump",
|
||||
|
@ -38,11 +38,11 @@ TEST(EncoderTests, WhenMissingParametersThenErrorCodeIsReturned) {
|
|||
"-out"};
|
||||
|
||||
MockEncoder encoder;
|
||||
EXPECT_NE(0, encoder.validateInput(static_cast<uint32_t>(arrayCount<const char *>(argv)), argv));
|
||||
EXPECT_NE(0, encoder.validateInput(args));
|
||||
}
|
||||
|
||||
TEST(EncoderTests, GivenWrongParametersWhenParsingParametersThenErrorCodeIsReturne) {
|
||||
const char *argv[] = {
|
||||
TEST(EncoderTests, GivenWrongParametersWhenParsingParametersThenErrorCodeIsReturned) {
|
||||
std::vector<std::string> args = {
|
||||
"ocloc",
|
||||
"asm",
|
||||
"-dump",
|
||||
|
@ -51,7 +51,7 @@ TEST(EncoderTests, GivenWrongParametersWhenParsingParametersThenErrorCodeIsRetur
|
|||
"rasputin"};
|
||||
|
||||
MockEncoder encoder;
|
||||
EXPECT_NE(0, encoder.validateInput(static_cast<uint32_t>(arrayCount<const char *>(argv)), argv));
|
||||
EXPECT_NE(0, encoder.validateInput(args));
|
||||
}
|
||||
|
||||
TEST(EncoderTests, WhenTryingToCopyNonExistingFileThenErrorCodeIsReturned) {
|
||||
|
|
|
@ -17,6 +17,7 @@ struct MockDecoder : public BinaryDecoder {
|
|||
: BinaryDecoder(file, patch, dump) {
|
||||
this->iga.reset(new MockIgaWrapper);
|
||||
setMessagePrinter(MessagePrinter{true});
|
||||
argHelper = std::make_unique<OclocArgHelper>();
|
||||
};
|
||||
using BinaryDecoder::binaryFile;
|
||||
using BinaryDecoder::decode;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "shared/source/helpers/hash.h"
|
||||
|
||||
#include "offline_compiler/decoder/binary_encoder.h"
|
||||
#include "opencl/test/unit_test/offline_compiler/mock/mock_argument_helper.h"
|
||||
|
||||
#include "mock_iga_wrapper.h"
|
||||
|
||||
|
@ -21,8 +22,11 @@ struct MockEncoder : public BinaryEncoder {
|
|||
: BinaryEncoder(dump, elf) {
|
||||
this->iga.reset(new MockIgaWrapper);
|
||||
setMessagePrinter(MessagePrinter{true});
|
||||
this->argHelper.reset(new MockOclocArgHelper(filesMap));
|
||||
};
|
||||
|
||||
std::map<std::string, std::string> filesMap;
|
||||
|
||||
bool copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary, uint32_t *binaryLength) override {
|
||||
auto it = filesMap.find(srcFileName);
|
||||
if (it == filesMap.end()) {
|
||||
|
@ -34,16 +38,6 @@ struct MockEncoder : public BinaryEncoder {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fileExists(const std::string &path) const override {
|
||||
return filesMap.count(path) || BinaryEncoder::fileExists(path);
|
||||
}
|
||||
|
||||
std::vector<char> readBinaryFile(const std::string &path) const override {
|
||||
return filesMap.count(path) ? std::vector<char>(filesMap.at(path).c_str(), filesMap.at(path).c_str() + filesMap.at(path).size())
|
||||
: BinaryEncoder::readBinaryFile(path);
|
||||
}
|
||||
|
||||
using BinaryEncoder::addPadding;
|
||||
using BinaryEncoder::calculatePatchListSizes;
|
||||
using BinaryEncoder::copyBinaryToBinary;
|
||||
|
@ -60,6 +54,4 @@ struct MockEncoder : public BinaryEncoder {
|
|||
MockIgaWrapper *getMockIga() const {
|
||||
return static_cast<MockIgaWrapper *>(iga.get());
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> filesMap;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "offline_compiler/ocloc_arg_helper.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class MockOclocArgHelper : public OclocArgHelper {
|
||||
public:
|
||||
std::map<std::string, std::string> &filesMap;
|
||||
MockOclocArgHelper(std::map<std::string, std::string> &filesMap) : OclocArgHelper(
|
||||
0, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr),
|
||||
filesMap(filesMap){};
|
||||
|
||||
protected:
|
||||
bool fileExists(const std::string &filename) const override {
|
||||
return filesMap.find(filename) != filesMap.end();
|
||||
}
|
||||
|
||||
std::vector<char> readBinaryFile(const std::string &filename) override {
|
||||
auto file = filesMap[filename];
|
||||
return std::vector<char>(file.begin(), file.end());
|
||||
}
|
||||
};
|
|
@ -31,6 +31,8 @@ class MockOfflineCompiler : public OfflineCompiler {
|
|||
using OfflineCompiler::useOptionsSuffix;
|
||||
|
||||
MockOfflineCompiler() : OfflineCompiler() {
|
||||
argHelper.reset(new OclocArgHelper(
|
||||
0, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||
}
|
||||
|
||||
int initialize(size_t numArgs, const std::vector<std::string> &argv) {
|
||||
|
|
|
@ -1051,7 +1051,8 @@ TEST(OfflineCompilerTest, givenNonExistingFilenameWhenUsedToReadOptionsThenReadO
|
|||
std::string file("non_existing_file");
|
||||
ASSERT_FALSE(fileExists(file.c_str()));
|
||||
|
||||
bool result = OfflineCompiler::readOptionsFromFile(options, file);
|
||||
auto helper = std::make_unique<OclocArgHelper>();
|
||||
bool result = OfflineCompiler::readOptionsFromFile(options, file, helper);
|
||||
|
||||
EXPECT_FALSE(result);
|
||||
}
|
||||
|
|
|
@ -64,9 +64,9 @@ function(compile_builtin gen_type platform_type builtin bits builtin_options)
|
|||
set(cloc_cmd_prefix ocloc)
|
||||
else()
|
||||
if(DEFINED NEO__IGC_LIBRARY_PATH)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=${NEO__IGC_LIBRARY_PATH} $<TARGET_FILE:ocloc>)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=${NEO__IGC_LIBRARY_PATH}:$<TARGET_FILE_DIR:ocloc_lib> $<TARGET_FILE:ocloc>)
|
||||
else()
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=$<TARGET_FILE_DIR:ocloc> $<TARGET_FILE:ocloc>)
|
||||
set(cloc_cmd_prefix LD_LIBRARY_PATH=$<TARGET_FILE_DIR:ocloc_lib> $<TARGET_FILE:ocloc>)
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND __cloc__options__ "-cl-kernel-arg-info")
|
||||
|
|
Loading…
Reference in New Issue