mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-19 16:24:18 +08:00
ocloc as shared library, ocloc API
Change-Id: Ie866b9ad5ee6de8c8b10f83551e2a3cab9d64a02
This commit is contained in:
@@ -821,7 +821,7 @@ if(MSVC)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory_unique(offline_compiler ${NEO_BUILD_DIR}/offline_compiler)
|
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)
|
if(DONT_CARE_OF_VIRTUALS)
|
||||||
set(NEO_CORE_RELEASE_LIB_NAME "neo_core")
|
set(NEO_CORE_RELEASE_LIB_NAME "neo_core")
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
# 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.h
|
||||||
${NEO_CORE_DIRECTORY}/device_binary_format/ar/ar_decoder.h
|
${NEO_CORE_DIRECTORY}/device_binary_format/ar/ar_decoder.h
|
||||||
${NEO_CORE_DIRECTORY}/device_binary_format/ar/ar_decoder.cpp
|
${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/helper.h
|
||||||
${NEO_SOURCE_DIR}/offline_compiler/decoder/iga_wrapper.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/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.cpp
|
||||||
${NEO_SOURCE_DIR}/offline_compiler/ocloc_fatbinary.h
|
${NEO_SOURCE_DIR}/offline_compiler/ocloc_fatbinary.h
|
||||||
${NEO_SOURCE_DIR}/offline_compiler/offline_compiler_helper.cpp
|
${NEO_SOURCE_DIR}/offline_compiler/offline_compiler_helper.cpp
|
||||||
@@ -47,24 +51,24 @@ set(CLOC_SRCS_LIB
|
|||||||
)
|
)
|
||||||
|
|
||||||
if(${IGA_HEADERS_AVAILABLE})
|
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/iga_wrapper.cpp
|
||||||
${NEO_SOURCE_DIR}/offline_compiler/decoder${BRANCH_DIR_SUFFIX}/translate_platform.cpp
|
${NEO_SOURCE_DIR}/offline_compiler/decoder${BRANCH_DIR_SUFFIX}/translate_platform.cpp
|
||||||
)
|
)
|
||||||
else()
|
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
|
${NEO_SOURCE_DIR}/offline_compiler/decoder/iga_stubs.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
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.cpp
|
||||||
${NEO_CORE_DIRECTORY}/os_interface/windows/os_library_win.h
|
${NEO_CORE_DIRECTORY}/os_interface/windows/os_library_win.h
|
||||||
${NEO_SOURCE_DIR}/opencl/source/dll/windows/options_windows.cpp
|
${NEO_SOURCE_DIR}/opencl/source/dll/windows/options_windows.cpp
|
||||||
)
|
)
|
||||||
else()
|
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.cpp
|
||||||
${NEO_CORE_DIRECTORY}/os_interface/linux/os_library_linux.h
|
${NEO_CORE_DIRECTORY}/os_interface/linux/os_library_linux.h
|
||||||
${NEO_SOURCE_DIR}/opencl/source/dll/linux/options_linux.cpp
|
${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}")
|
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
|
-DCIF_HEADERS_ONLY_BUILD
|
||||||
-DALL_SUPPORTED_PRODUCT_FAMILIES=${ALL_SUPPORTED_PRODUCT_FAMILIES}
|
-DALL_SUPPORTED_PRODUCT_FAMILIES=${ALL_SUPPORTED_PRODUCT_FAMILIES}
|
||||||
)
|
)
|
||||||
@@ -83,43 +87,34 @@ set(RUNTIME_GENX_CPP_FILES
|
|||||||
)
|
)
|
||||||
|
|
||||||
macro(macro_for_each_platform)
|
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()
|
endmacro()
|
||||||
|
|
||||||
macro(macro_for_each_gen)
|
macro(macro_for_each_gen)
|
||||||
foreach(SRC_IT ${RUNTIME_GENX_CPP_FILES})
|
foreach(SRC_IT ${RUNTIME_GENX_CPP_FILES})
|
||||||
set(SRC_FILE ${NEO_SOURCE_DIR}/opencl/source/${GEN_TYPE_LOWER}/${SRC_IT})
|
set(SRC_FILE ${NEO_SOURCE_DIR}/opencl/source/${GEN_TYPE_LOWER}/${SRC_IT})
|
||||||
if(EXISTS ${SRC_FILE}_${GEN_TYPE_LOWER}.cpp)
|
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()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
apply_macro_for_each_platform()
|
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()
|
endmacro()
|
||||||
|
|
||||||
apply_macro_for_each_gen("SUPPORTED")
|
apply_macro_for_each_gen("SUPPORTED")
|
||||||
|
|
||||||
set(CLOC_SRCS
|
set(CLOC_LIB_SRCS
|
||||||
${CLOC_SRCS_LIB}
|
${CLOC_LIB_SRCS_LIB}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||||
)
|
)
|
||||||
add_executable(ocloc ${CLOC_SRCS})
|
add_library(ocloc_lib SHARED ${CLOC_LIB_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_subdirectories()
|
add_subdirectories()
|
||||||
|
|
||||||
create_project_source_tree(ocloc)
|
create_project_source_tree(ocloc_lib)
|
||||||
|
|
||||||
set(CLOC_INCLUDES
|
set(CLOC_LIB_INCLUDES
|
||||||
${ENGINE_NODE_DIR}
|
${ENGINE_NODE_DIR}
|
||||||
${IGC_OCL_ADAPTOR_DIR}
|
${IGC_OCL_ADAPTOR_DIR}
|
||||||
${CIF_BASE_DIR}
|
${CIF_BASE_DIR}
|
||||||
@@ -128,22 +123,75 @@ set(CLOC_INCLUDES
|
|||||||
${NEO__IGC_INCLUDE_DIR}
|
${NEO__IGC_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(ocloc BEFORE PRIVATE ${CLOC_INCLUDES})
|
target_include_directories(ocloc_lib BEFORE PRIVATE ${CLOC_LIB_INCLUDES})
|
||||||
target_include_directories(ocloc BEFORE PRIVATE ${IGA_INCLUDE_DIR})
|
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})
|
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)
|
if(MSVC)
|
||||||
target_link_libraries(ocloc dbghelp)
|
target_link_libraries(ocloc_lib dbghelp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
target_link_libraries(ocloc dl pthread)
|
target_link_libraries(ocloc_lib dl pthread)
|
||||||
endif()
|
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 PROPERTIES FOLDER "offline_compiler")
|
||||||
|
set_target_properties(ocloc_lib PROPERTIES FOLDER "offline_compiler")
|
||||||
|
|
||||||
|
|
||||||
add_custom_target(copy_compiler_files DEPENDS ${NEO__IGC_TARGETS})
|
add_custom_target(copy_compiler_files DEPENDS ${NEO__IGC_TARGETS})
|
||||||
set_target_properties(copy_compiler_files PROPERTIES FOLDER "opencl runtime")
|
set_target_properties(copy_compiler_files PROPERTIES FOLDER "opencl runtime")
|
||||||
@@ -153,10 +201,11 @@ if(WIN32)
|
|||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET copy_compiler_files
|
TARGET copy_compiler_files
|
||||||
PRE_BUILD
|
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 make_directory $<TARGET_FILE_DIR:ocloc>
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${TARGET_tmp}> $<TARGET_FILE_DIR:ocloc>
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${TARGET_tmp}> $<TARGET_FILE_DIR:ocloc>
|
||||||
)
|
)
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CLOC_SRCS_LIB ${CLOC_SRCS_LIB} PARENT_SCOPE)
|
|
||||||
|
|||||||
128
offline_compiler/api.cpp
Normal file
128
offline_compiler/api.cpp
Normal file
@@ -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() {
|
int BinaryDecoder::decode() {
|
||||||
parseTokens();
|
parseTokens();
|
||||||
std::ofstream ptmFile(pathToDump + "PTM.txt");
|
std::stringstream ptmFile;
|
||||||
auto devBinPtr = getDevBinary();
|
auto devBinPtr = getDevBinary();
|
||||||
if (devBinPtr == nullptr) {
|
if (devBinPtr == nullptr) {
|
||||||
messagePrinter.printf("Error! Device Binary section was not found.\n");
|
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() {
|
const void *BinaryDecoder::getDevBinary() {
|
||||||
binary = readBinaryFile(binaryFile);
|
binary = argHelper->readBinaryFile(binaryFile);
|
||||||
const void *data = nullptr;
|
const void *data = nullptr;
|
||||||
std::string decoderErrors;
|
std::string decoderErrors;
|
||||||
std::string decoderWarnings;
|
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());
|
auto sectionData = ArrayRef<const char>(reinterpret_cast<const char *>(sectionHeader.data.begin()), sectionHeader.data.size());
|
||||||
switch (sectionHeader.header->type) {
|
switch (sectionHeader.header->type) {
|
||||||
case NEO::Elf::SHT_OPENCL_LLVM_BINARY: {
|
case NEO::Elf::SHT_OPENCL_LLVM_BINARY: {
|
||||||
std::ofstream ofs(pathToDump + "llvm.bin", std::ios::binary);
|
argHelper->saveOutput(pathToDump + "llvm.bin", sectionData.begin(), sectionData.size());
|
||||||
ofs.write(sectionData.begin(), sectionData.size());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NEO::Elf::SHT_OPENCL_SPIRV: {
|
case NEO::Elf::SHT_OPENCL_SPIRV: {
|
||||||
std::ofstream ofs(pathToDump + "spirv.bin", std::ios::binary);
|
argHelper->saveOutput(pathToDump + "spirv.bin", sectionData.begin(), sectionData.size());
|
||||||
ofs.write(sectionData.begin(), sectionData.size());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NEO::Elf::SHT_OPENCL_OPTIONS: {
|
case NEO::Elf::SHT_OPENCL_OPTIONS: {
|
||||||
std::ofstream ofs(pathToDump + "build.bin", std::ios::binary);
|
argHelper->saveOutput(pathToDump + "build.bin", sectionData.begin(), sectionData.size());
|
||||||
ofs.write(sectionData.begin(), sectionData.size());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NEO::Elf::SHT_OPENCL_DEV_BINARY: {
|
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() {
|
void BinaryDecoder::parseTokens() {
|
||||||
//Creating patchlist definitions
|
//Creating patchlist definitions
|
||||||
std::vector<std::string> patchList;
|
auto patchList = loadPatchList();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t pos = findPos(patchList, "struct SProgramBinaryHeader");
|
size_t pos = findPos(patchList, "struct SProgramBinaryHeader");
|
||||||
if (pos == patchList.size()) {
|
if (pos == patchList.size()) {
|
||||||
@@ -354,6 +359,8 @@ int BinaryDecoder::processBinary(const void *&ptr, std::ostream &ptmFile) {
|
|||||||
ptmFile << "Kernel #" << i << '\n';
|
ptmFile << "Kernel #" << i << '\n';
|
||||||
processKernel(ptr, ptmFile);
|
processKernel(ptr, ptmFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argHelper->saveOutput(pathToDump + "PTM.txt", ptmFile);
|
||||||
return 0;
|
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());
|
messagePrinter.printf("Trying to disassemble %s.krn\n", kernelName.c_str());
|
||||||
std::string disassembledKernel;
|
std::string disassembledKernel;
|
||||||
if (iga->tryDisassembleGenISA(ptr, KernelHeapUnpaddedSize, 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 {
|
} else {
|
||||||
if (ignoreIsaPadding) {
|
if (ignoreIsaPadding) {
|
||||||
writeDataToFile((fileName + ".dat").c_str(), ptr, KernelHeapUnpaddedSize);
|
argHelper->saveOutput(fileName + ".dat", ptr, KernelHeapUnpaddedSize);
|
||||||
} else {
|
} else {
|
||||||
writeDataToFile((fileName + ".dat").c_str(), ptr, KernelHeapSize);
|
argHelper->saveOutput(fileName + ".dat", ptr, KernelHeapSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptr = ptrOffset(ptr, KernelHeapSize);
|
ptr = ptrOffset(ptr, KernelHeapSize);
|
||||||
@@ -407,16 +414,16 @@ void BinaryDecoder::processKernel(const void *&ptr, std::ostream &ptmFile) {
|
|||||||
if (GeneralStateHeapSize != 0) {
|
if (GeneralStateHeapSize != 0) {
|
||||||
messagePrinter.printf("Warning! GeneralStateHeapSize wasn't 0.\n");
|
messagePrinter.printf("Warning! GeneralStateHeapSize wasn't 0.\n");
|
||||||
fileName = pathToDump + kernelName + "_GeneralStateHeap.bin";
|
fileName = pathToDump + kernelName + "_GeneralStateHeap.bin";
|
||||||
writeDataToFile(fileName.c_str(), ptr, DynamicStateHeapSize);
|
argHelper->saveOutput(fileName, ptr, DynamicStateHeapSize);
|
||||||
ptr = ptrOffset(ptr, GeneralStateHeapSize);
|
ptr = ptrOffset(ptr, GeneralStateHeapSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
fileName = pathToDump + kernelName + "_DynamicStateHeap.bin";
|
fileName = pathToDump + kernelName + "_DynamicStateHeap.bin";
|
||||||
writeDataToFile(fileName.c_str(), ptr, DynamicStateHeapSize);
|
argHelper->saveOutput(fileName, ptr, DynamicStateHeapSize);
|
||||||
ptr = ptrOffset(ptr, DynamicStateHeapSize);
|
ptr = ptrOffset(ptr, DynamicStateHeapSize);
|
||||||
|
|
||||||
fileName = pathToDump + kernelName + "_SurfaceStateHeap.bin";
|
fileName = pathToDump + kernelName + "_SurfaceStateHeap.bin";
|
||||||
writeDataToFile(fileName.c_str(), ptr, SurfaceStateHeapSize);
|
argHelper->saveOutput(fileName, ptr, SurfaceStateHeapSize);
|
||||||
ptr = ptrOffset(ptr, SurfaceStateHeapSize);
|
ptr = ptrOffset(ptr, SurfaceStateHeapSize);
|
||||||
|
|
||||||
if (KernelPatchListSize == 0) {
|
if (KernelPatchListSize == 0) {
|
||||||
@@ -501,33 +508,34 @@ uint32_t BinaryDecoder::readStructFields(const std::vector<std::string> &patchLi
|
|||||||
return fullSize;
|
return fullSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BinaryDecoder::validateInput(uint32_t argc, const char **argv) {
|
int BinaryDecoder::validateInput(const std::vector<std::string> &args) {
|
||||||
if (!strcmp(argv[argc - 1], "--help")) {
|
if (args[args.size() - 1] == "-help") {
|
||||||
printHelp();
|
printHelp();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 2; i < argc; ++i) {
|
for (size_t argIndex = 2; argIndex < args.size(); ++argIndex) {
|
||||||
if (i < argc - 1) {
|
const auto &currArg = args[argIndex];
|
||||||
if (!strcmp(argv[i], "-file")) {
|
const bool hasMoreArgs = (argIndex + 1 < args.size());
|
||||||
binaryFile = std::string(argv[++i]);
|
if ("-file" == currArg && hasMoreArgs) {
|
||||||
} else if (!strcmp(argv[i], "-device")) {
|
binaryFile = args[++argIndex];
|
||||||
iga->setProductFamily(getProductFamilyFromDeviceName(argv[++i]));
|
} else if ("-device" == currArg && hasMoreArgs) {
|
||||||
} else if (!strcmp(argv[i], "-patch")) {
|
iga->setProductFamily(getProductFamilyFromDeviceName(args[++argIndex]));
|
||||||
pathToPatch = std::string(argv[++i]);
|
} else if ("-patch" == currArg && hasMoreArgs) {
|
||||||
addSlash(pathToPatch);
|
pathToPatch = args[++argIndex];
|
||||||
} else if (!strcmp(argv[i], "-dump")) {
|
addSlash(pathToPatch);
|
||||||
pathToDump = std::string(argv[++i]);
|
} else if ("-dump" == currArg && hasMoreArgs) {
|
||||||
addSlash(pathToDump);
|
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 {
|
} else {
|
||||||
if (!strcmp(argv[i], "-ignore_isa_padding")) {
|
messagePrinter.printf("Unknown argument %s\n", currArg.c_str());
|
||||||
ignoreIsaPadding = true;
|
printHelp();
|
||||||
} else {
|
return -1;
|
||||||
messagePrinter.printf("Unknown argument %s\n", argv[i]);
|
|
||||||
printHelp();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (binaryFile.find(".bin") == std::string::npos) {
|
if (binaryFile.find(".bin") == std::string::npos) {
|
||||||
@@ -535,15 +543,15 @@ int BinaryDecoder::validateInput(uint32_t argc, const char **argv) {
|
|||||||
printHelp();
|
printHelp();
|
||||||
return -1;
|
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()) {
|
if (false == iga->isKnownPlatform()) {
|
||||||
messagePrinter.printf("Warning : missing or invalid -device parameter - results may be inacurate\n");
|
messagePrinter.printf("Warning : missing or invalid -device parameter - results may be inacurate\n");
|
||||||
}
|
}
|
||||||
|
if (!argHelper->outputEnabled()) {
|
||||||
MakeDirectory(pathToDump.c_str());
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "offline_compiler/decoder/helper.h"
|
#include "offline_compiler/decoder/helper.h"
|
||||||
#include "offline_compiler/decoder/iga_wrapper.h"
|
#include "offline_compiler/decoder/iga_wrapper.h"
|
||||||
|
#include "offline_compiler/ocloc_arg_helper.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -33,15 +34,21 @@ class BinaryDecoder {
|
|||||||
public:
|
public:
|
||||||
BinaryDecoder() : iga(new IgaWrapper) {
|
BinaryDecoder() : iga(new IgaWrapper) {
|
||||||
iga->setMessagePrinter(messagePrinter);
|
iga->setMessagePrinter(messagePrinter);
|
||||||
|
if (nullptr == argHelper) {
|
||||||
|
argHelper = std::make_unique<OclocArgHelper>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BinaryDecoder(const std::string &file, const std::string &patch, const std::string &dump)
|
BinaryDecoder(const std::string &file, const std::string &patch, const std::string &dump)
|
||||||
: binaryFile(file), pathToPatch(patch), pathToDump(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 decode();
|
||||||
int validateInput(uint32_t argc, const char **argv);
|
int validateInput(const std::vector<std::string> &args);
|
||||||
|
|
||||||
void setMessagePrinter(const MessagePrinter &messagePrinter);
|
void setMessagePrinter(const MessagePrinter &messagePrinter);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::unique_ptr<OclocArgHelper> argHelper = nullptr;
|
||||||
bool ignoreIsaPadding = false;
|
bool ignoreIsaPadding = false;
|
||||||
BinaryHeader programHeader, kernelHeader;
|
BinaryHeader programHeader, kernelHeader;
|
||||||
std::vector<char> binary;
|
std::vector<char> binary;
|
||||||
@@ -53,6 +60,7 @@ class BinaryDecoder {
|
|||||||
void dumpField(const void *&binaryPtr, const PTField &field, std::ostream &ptmFile);
|
void dumpField(const void *&binaryPtr, const PTField &field, std::ostream &ptmFile);
|
||||||
uint8_t getSize(const std::string &typeStr);
|
uint8_t getSize(const std::string &typeStr);
|
||||||
const void *getDevBinary();
|
const void *getDevBinary();
|
||||||
|
std::vector<std::string> loadPatchList();
|
||||||
void parseTokens();
|
void parseTokens();
|
||||||
void printHelp();
|
void printHelp();
|
||||||
int processBinary(const void *&ptr, std::ostream &ptmFile);
|
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) {
|
bool BinaryEncoder::copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary, uint32_t *binaryLength) {
|
||||||
std::ifstream ifs(srcFileName, std::ios::binary);
|
auto binary = argHelper->readBinaryFile(srcFileName);
|
||||||
if (!ifs.good()) {
|
auto length = binary.size();
|
||||||
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);
|
|
||||||
outBinary.write(binary.data(), length);
|
outBinary.write(binary.data(), length);
|
||||||
|
|
||||||
if (binaryLength) {
|
if (binaryLength) {
|
||||||
@@ -75,27 +67,24 @@ bool BinaryEncoder::copyBinaryToBinary(const std::string &srcFileName, std::ostr
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BinaryEncoder::createElf() {
|
int BinaryEncoder::createElf(std::stringstream &deviceBinary) {
|
||||||
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> ElfEncoder;
|
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> ElfEncoder;
|
||||||
ElfEncoder.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
|
ElfEncoder.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
|
||||||
|
|
||||||
//Build Options
|
//Build Options
|
||||||
if (fileExists(pathToDump + "build.bin")) {
|
if (argHelper->fileExists(pathToDump + "build.bin")) {
|
||||||
auto binary = readBinaryFile(pathToDump + "build.bin");
|
auto binary = argHelper->readBinaryFile(pathToDump + "build.bin");
|
||||||
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_OPTIONS, "BuildOptions",
|
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_OPTIONS, "BuildOptions",
|
||||||
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
||||||
} else {
|
} else {
|
||||||
messagePrinter.printf("Warning! Missing build section.\n");
|
messagePrinter.printf("Warning! Missing build section.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//LLVM or SPIRV
|
//LLVM or SPIRV
|
||||||
if (fileExists(pathToDump + "llvm.bin")) {
|
if (argHelper->fileExists(pathToDump + "llvm.bin")) {
|
||||||
auto binary = readBinaryFile(pathToDump + "llvm.bin");
|
auto binary = argHelper->readBinaryFile(pathToDump + "llvm.bin");
|
||||||
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_LLVM_BINARY, "Intel(R) OpenCL LLVM Object",
|
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()));
|
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
||||||
} else if (fileExists(pathToDump + "spirv.bin")) {
|
} else if (argHelper->fileExists(pathToDump + "spirv.bin")) {
|
||||||
auto binary = readBinaryFile(pathToDump + "spirv.bin");
|
auto binary = argHelper->readBinaryFile(pathToDump + "spirv.bin");
|
||||||
std::string data(binary.begin(), binary.end());
|
|
||||||
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_SPIRV, "SPIRV Object",
|
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_SPIRV, "SPIRV Object",
|
||||||
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
||||||
} else {
|
} else {
|
||||||
@@ -103,25 +92,15 @@ int BinaryEncoder::createElf() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Device Binary
|
//Device Binary
|
||||||
if (fileExists(pathToDump + "device_binary.bin")) {
|
auto deviceBinaryStr = deviceBinary.str();
|
||||||
auto binary = readBinaryFile(pathToDump + "device_binary.bin");
|
std::vector<char> binary(deviceBinaryStr.begin(), deviceBinaryStr.end());
|
||||||
ElfEncoder.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, "Intel(R) OpenCL Device Binary",
|
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()));
|
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
|
||||||
} else {
|
|
||||||
messagePrinter.printf("Missing device_binary.bin\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Resolve Elf Binary
|
//Resolve Elf Binary
|
||||||
auto elfBinary = ElfEncoder.encode();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,21 +139,23 @@ Examples:
|
|||||||
|
|
||||||
int BinaryEncoder::encode() {
|
int BinaryEncoder::encode() {
|
||||||
std::vector<std::string> ptmFile;
|
std::vector<std::string> ptmFile;
|
||||||
readFileToVectorOfStrings(ptmFile, pathToDump + "PTM.txt");
|
if (!argHelper->fileExists(pathToDump + "PTM.txt")) {
|
||||||
calculatePatchListSizes(ptmFile);
|
messagePrinter.printf("Error! Couldn't find PTM.txt");
|
||||||
|
|
||||||
std::ofstream deviceBinary(pathToDump + "device_binary.bin", std::ios::binary);
|
|
||||||
if (!deviceBinary.good()) {
|
|
||||||
messagePrinter.printf("Error! Couldn't create device_binary.bin.\n");
|
|
||||||
return -1;
|
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);
|
int retVal = processBinary(ptmFile, deviceBinary);
|
||||||
deviceBinary.close();
|
argHelper->saveOutput(pathToDump + "device_binary.bin", deviceBinary.str().c_str(), deviceBinary.str().length());
|
||||||
if (retVal != CL_SUCCESS) {
|
if (retVal != CL_SUCCESS) {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
return createElf();
|
retVal = createElf(deviceBinary);
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BinaryEncoder::processBinary(const std::vector<std::string> &ptmFileLines, std::ostream &deviceBinary) {
|
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;
|
bool heapsCopiedSuccesfully = true;
|
||||||
|
|
||||||
// Use .asm if available, fallback to .dat
|
// Use .asm if available, fallback to .dat
|
||||||
if (fileExists(pathToDump + kernelName + "_KernelHeap.asm")) {
|
if (argHelper->fileExists(pathToDump + kernelName + "_KernelHeap.asm")) {
|
||||||
auto kernelAsAsm = readBinaryFile(pathToDump + kernelName + "_KernelHeap.asm");
|
auto kernelAsAsm = argHelper->readBinaryFile(pathToDump + kernelName + "_KernelHeap.asm");
|
||||||
std::string kernelAsBinary;
|
std::string kernelAsBinary;
|
||||||
messagePrinter.printf("Trying to assemble %s.asm\n", kernelName.c_str());
|
messagePrinter.printf("Trying to assemble %s.asm\n", kernelName.c_str());
|
||||||
if (false == iga->tryAssembleGenISA(std::string(kernelAsAsm.begin(), kernelAsAsm.end()), kernelAsBinary)) {
|
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
|
// 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 + "_GeneralStateHeap.bin", kernelBlob);
|
||||||
}
|
}
|
||||||
heapsCopiedSuccesfully = heapsCopiedSuccesfully && copyBinaryToBinary(pathToDump + kernelName + "_DynamicStateHeap.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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BinaryEncoder::validateInput(uint32_t argc, const char **argv) {
|
int BinaryEncoder::validateInput(const std::vector<std::string> &args) {
|
||||||
if (!strcmp(argv[argc - 1], "--help")) {
|
if ("-help" == args[args.size() - 1]) {
|
||||||
printHelp();
|
printHelp();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 2; i < argc; ++i) {
|
for (size_t argIndex = 2; argIndex < args.size(); ++argIndex) {
|
||||||
if (i < argc - 1) {
|
const auto &currArg = args[argIndex];
|
||||||
if (!strcmp(argv[i], "-dump")) {
|
const bool hasMoreArgs = (argIndex + 1 < args.size());
|
||||||
pathToDump = std::string(argv[++i]);
|
if ("-dump" == currArg && hasMoreArgs) {
|
||||||
addSlash(pathToDump);
|
pathToDump = args[++argIndex];
|
||||||
} else if (!strcmp(argv[i], "-device")) {
|
addSlash(pathToDump);
|
||||||
iga->setProductFamily(getProductFamilyFromDeviceName(argv[++i]));
|
} else if ("-device" == currArg && hasMoreArgs) {
|
||||||
} else if (!strcmp(argv[i], "-out")) {
|
iga->setProductFamily(getProductFamilyFromDeviceName(args[++argIndex]));
|
||||||
elfName = std::string(argv[++i]);
|
} else if ("-out" == currArg && hasMoreArgs) {
|
||||||
} else {
|
elfName = args[++argIndex];
|
||||||
messagePrinter.printf("Unknown argument %s\n", argv[i]);
|
} else if ("-ignore_isa_padding" == currArg) {
|
||||||
printHelp();
|
ignoreIsaPadding = true;
|
||||||
return -1;
|
} else if ("-q" == currArg) {
|
||||||
}
|
this->messagePrinter = MessagePrinter{true};
|
||||||
|
iga->setMessagePrinter(this->messagePrinter);
|
||||||
} else {
|
} else {
|
||||||
if (!strcmp(argv[i], "-ignore_isa_padding")) {
|
messagePrinter.printf("Unknown argument %s\n", currArg.c_str());
|
||||||
ignoreIsaPadding = true;
|
printHelp();
|
||||||
} else {
|
return -1;
|
||||||
messagePrinter.printf("Unknown argument %s\n", argv[i]);
|
|
||||||
printHelp();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pathToDump.empty()) {
|
if (pathToDump.empty()) {
|
||||||
messagePrinter.printf("Warning : Path to dump folder not specificed - using ./dump as default.\n");
|
if (!argHelper->outputEnabled()) {
|
||||||
pathToDump = "dump";
|
messagePrinter.printf("Warning : Path to dump folder not specificed - using ./dump as default.\n");
|
||||||
addSlash(pathToDump);
|
pathToDump = "dump";
|
||||||
|
addSlash(pathToDump);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (elfName.find(".bin") == std::string::npos) {
|
if (elfName.find(".bin") == std::string::npos) {
|
||||||
messagePrinter.printf(".bin extension is expected for binary file.\n");
|
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;
|
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
|
#pragma once
|
||||||
|
#include "offline_compiler/ocloc_arg_helper.h"
|
||||||
|
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include "iga_wrapper.h"
|
#include "iga_wrapper.h"
|
||||||
|
|
||||||
@@ -17,15 +19,20 @@ class BinaryEncoder {
|
|||||||
public:
|
public:
|
||||||
BinaryEncoder() : iga(new IgaWrapper) {
|
BinaryEncoder() : iga(new IgaWrapper) {
|
||||||
iga->setMessagePrinter(messagePrinter);
|
iga->setMessagePrinter(messagePrinter);
|
||||||
|
argHelper = std::make_unique<OclocArgHelper>();
|
||||||
}
|
}
|
||||||
BinaryEncoder(const std::string &dump, const std::string &elf)
|
BinaryEncoder(const std::string &dump, const std::string &elf)
|
||||||
: pathToDump(dump), elfName(elf){};
|
: pathToDump(dump), elfName(elf){};
|
||||||
|
BinaryEncoder(std::unique_ptr<OclocArgHelper> helper) : argHelper(std::move(helper)), iga(new IgaWrapper) {
|
||||||
|
iga->setMessagePrinter(messagePrinter);
|
||||||
|
}
|
||||||
int encode();
|
int encode();
|
||||||
int validateInput(uint32_t argc, const char **argv);
|
int validateInput(const std::vector<std::string> &args);
|
||||||
|
|
||||||
void setMessagePrinter(const MessagePrinter &messagePrinter);
|
void setMessagePrinter(const MessagePrinter &messagePrinter);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::unique_ptr<OclocArgHelper> argHelper = nullptr;
|
||||||
bool ignoreIsaPadding = false;
|
bool ignoreIsaPadding = false;
|
||||||
std::string pathToDump, elfName;
|
std::string pathToDump, elfName;
|
||||||
MessagePrinter messagePrinter;
|
MessagePrinter messagePrinter;
|
||||||
@@ -35,7 +42,7 @@ class BinaryEncoder {
|
|||||||
bool copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary) {
|
bool copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary) {
|
||||||
return copyBinaryToBinary(srcFileName, outBinary, nullptr);
|
return copyBinaryToBinary(srcFileName, outBinary, nullptr);
|
||||||
}
|
}
|
||||||
int createElf();
|
int createElf(std::stringstream &deviceBinary);
|
||||||
void printHelp();
|
void printHelp();
|
||||||
int processBinary(const std::vector<std::string> &ptmFile, std::ostream &deviceBinary);
|
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);
|
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);
|
void write(std::stringstream &in, std::ostream &deviceBinary);
|
||||||
int writeDeviceBinary(const std::string &line, std::ostream &deviceBinary);
|
int writeDeviceBinary(const std::string &line, std::ostream &deviceBinary);
|
||||||
void addPadding(std::ostream &out, size_t numBytes);
|
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
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "shared/source/os_interface/os_library.h"
|
#include "ocloc_wrapper.h"
|
||||||
|
|
||||||
#include "offline_compiler/multi_command.h"
|
int main(int argc, const char *argv[]) {
|
||||||
#include "offline_compiler/ocloc_fatbinary.h"
|
OclocWrapper oclocWrapper;
|
||||||
#include "offline_compiler/offline_compiler.h"
|
return oclocWrapper.invokeOcloc(argc, argv);
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
129
offline_compiler/ocloc_api.cpp
Normal file
129
offline_compiler/ocloc_api.cpp
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
offline_compiler/ocloc_api.h
Normal file
28
offline_compiler/ocloc_api.h
Normal file
@@ -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);
|
||||||
|
}
|
||||||
150
offline_compiler/ocloc_arg_helper.cpp
Normal file
150
offline_compiler/ocloc_arg_helper.cpp
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
77
offline_compiler/ocloc_arg_helper.h
Normal file
77
offline_compiler/ocloc_arg_helper.h
Normal file
@@ -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);
|
||||||
|
};
|
||||||
94
offline_compiler/ocloc_wrapper.cpp
Normal file
94
offline_compiler/ocloc_wrapper.cpp
Normal file
@@ -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();
|
||||||
|
}
|
||||||
33
offline_compiler/ocloc_wrapper.h
Normal file
33
offline_compiler/ocloc_wrapper.h
Normal file
@@ -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();
|
auto pOffCompiler = new OfflineCompiler();
|
||||||
|
|
||||||
if (pOffCompiler) {
|
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);
|
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");
|
oclocOptionsFileName.append("_ocloc_options.txt");
|
||||||
|
|
||||||
std::string oclocOptionsFromFile;
|
std::string oclocOptionsFromFile;
|
||||||
bool oclocOptionsRead = readOptionsFromFile(oclocOptionsFromFile, oclocOptionsFileName);
|
bool oclocOptionsRead = readOptionsFromFile(oclocOptionsFromFile, oclocOptionsFileName, argHelper);
|
||||||
if (oclocOptionsRead && !isQuiet()) {
|
if (oclocOptionsRead && !isQuiet()) {
|
||||||
printf("Building with ocloc options:\n%s\n", oclocOptionsFromFile.c_str());
|
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);
|
std::string optionsFileName = inputFile.substr(0, ext_start);
|
||||||
optionsFileName.append("_options.txt");
|
optionsFileName.append("_options.txt");
|
||||||
|
|
||||||
bool optionsRead = readOptionsFromFile(options, optionsFileName);
|
bool optionsRead = readOptionsFromFile(options, optionsFileName, argHelper);
|
||||||
if (optionsRead && !isQuiet()) {
|
if (optionsRead && !isQuiet()) {
|
||||||
printf("Building with options:\n%s\n", options.c_str());
|
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");
|
internalOptionsFileName.append("_internal_options.txt");
|
||||||
|
|
||||||
std::string internalOptionsFromFile;
|
std::string internalOptionsFromFile;
|
||||||
bool internalOptionsRead = readOptionsFromFile(internalOptionsFromFile, internalOptionsFileName);
|
bool internalOptionsRead = readOptionsFromFile(internalOptionsFromFile, internalOptionsFileName, argHelper);
|
||||||
if (internalOptionsRead && !isQuiet()) {
|
if (internalOptionsRead && !isQuiet()) {
|
||||||
printf("Building with internal options:\n%s\n", internalOptionsFromFile.c_str());
|
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();
|
parseDebugSettings();
|
||||||
|
|
||||||
// set up the device inside the program
|
// set up the device inside the program
|
||||||
sourceFromFile = loadDataFromFile(inputFile.c_str(), sourceFromFileSize);
|
sourceFromFile = argHelper->loadDataFromFile(inputFile, sourceFromFileSize);
|
||||||
if (sourceFromFileSize == 0) {
|
if (sourceFromFileSize == 0) {
|
||||||
retVal = INVALID_FILE;
|
retVal = INVALID_FILE;
|
||||||
return retVal;
|
return retVal;
|
||||||
@@ -507,7 +525,7 @@ int OfflineCompiler::parseCommandLine(size_t numArgs, const std::vector<std::str
|
|||||||
} else if (deviceName.empty()) {
|
} else if (deviceName.empty()) {
|
||||||
printf("Error: Device name missing.\n");
|
printf("Error: Device name missing.\n");
|
||||||
retVal = INVALID_COMMAND_LINE;
|
retVal = INVALID_COMMAND_LINE;
|
||||||
} else if (!fileExists(inputFile)) {
|
} else if (!argHelper->fileExists(inputFile)) {
|
||||||
printf("Error: Input file %s missing.\n", inputFile.c_str());
|
printf("Error: Input file %s missing.\n", inputFile.c_str());
|
||||||
retVal = INVALID_FILE;
|
retVal = INVALID_FILE;
|
||||||
} else {
|
} else {
|
||||||
@@ -828,24 +846,18 @@ void OfflineCompiler::writeOutAllFiles() {
|
|||||||
if (irBinary) {
|
if (irBinary) {
|
||||||
std::string irOutputFileName = generateFilePathForIr(fileBase) + generateOptsSuffix();
|
std::string irOutputFileName = generateFilePathForIr(fileBase) + generateOptsSuffix();
|
||||||
|
|
||||||
writeDataToFile(
|
argHelper->saveOutput(irOutputFileName, irBinary, irBinarySize);
|
||||||
irOutputFileName.c_str(),
|
|
||||||
irBinary,
|
|
||||||
irBinarySize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (genBinary) {
|
if (genBinary) {
|
||||||
std::string genOutputFile = generateFilePath(outputDirectory, fileBase, ".gen") + generateOptsSuffix();
|
std::string genOutputFile = generateFilePath(outputDirectory, fileBase, ".gen") + generateOptsSuffix();
|
||||||
|
|
||||||
writeDataToFile(
|
argHelper->saveOutput(genOutputFile, genBinary, genBinarySize);
|
||||||
genOutputFile.c_str(),
|
|
||||||
genBinary,
|
|
||||||
genBinarySize);
|
|
||||||
|
|
||||||
if (useCppFile) {
|
if (useCppFile) {
|
||||||
std::string cppOutputFile = generateFilePath(outputDirectory, fileBase, ".cpp");
|
std::string cppOutputFile = generateFilePath(outputDirectory, fileBase, ".cpp");
|
||||||
std::string cpp = parseBinAsCharArray((uint8_t *)genBinary, genBinarySize, fileTrunk);
|
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 {
|
} else {
|
||||||
elfOutputFile = generateFilePath(outputDirectory, fileBase, ".bin") + generateOptsSuffix();
|
elfOutputFile = generateFilePath(outputDirectory, fileBase, ".bin") + generateOptsSuffix();
|
||||||
}
|
}
|
||||||
writeDataToFile(
|
argHelper->saveOutput(
|
||||||
elfOutputFile.c_str(),
|
elfOutputFile,
|
||||||
elfBinary.data(),
|
elfBinary.data(),
|
||||||
elfBinary.size());
|
elfBinary.size());
|
||||||
}
|
}
|
||||||
@@ -865,19 +877,19 @@ void OfflineCompiler::writeOutAllFiles() {
|
|||||||
if (debugDataBinary) {
|
if (debugDataBinary) {
|
||||||
std::string debugOutputFile = generateFilePath(outputDirectory, fileBase, ".dbg") + generateOptsSuffix();
|
std::string debugOutputFile = generateFilePath(outputDirectory, fileBase, ".dbg") + generateOptsSuffix();
|
||||||
|
|
||||||
writeDataToFile(
|
argHelper->saveOutput(
|
||||||
debugOutputFile.c_str(),
|
debugOutputFile,
|
||||||
debugDataBinary,
|
debugDataBinary,
|
||||||
debugDataBinarySize);
|
debugDataBinarySize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OfflineCompiler::readOptionsFromFile(std::string &options, const std::string &file) {
|
bool OfflineCompiler::readOptionsFromFile(std::string &options, const std::string &file, std::unique_ptr<OclocArgHelper> &helper) {
|
||||||
if (!fileExists(file)) {
|
if (!helper->fileExists(file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t optionsSize = 0U;
|
size_t optionsSize = 0U;
|
||||||
auto optionsFromFile = loadDataFromFile(file.c_str(), optionsSize);
|
auto optionsFromFile = helper->loadDataFromFile(file, optionsSize);
|
||||||
if (optionsSize > 0) {
|
if (optionsSize > 0) {
|
||||||
// Remove comment containing copyright header
|
// Remove comment containing copyright header
|
||||||
options = optionsFromFile.get();
|
options = optionsFromFile.get();
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include "shared/source/utilities/arrayref.h"
|
#include "shared/source/utilities/arrayref.h"
|
||||||
#include "shared/source/utilities/const_stringref.h"
|
#include "shared/source/utilities/const_stringref.h"
|
||||||
|
|
||||||
|
#include "offline_compiler/ocloc_arg_helper.h"
|
||||||
|
|
||||||
#include "cif/common/cif_main.h"
|
#include "cif/common/cif_main.h"
|
||||||
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
||||||
#include "ocl_igc_interface/igc_ocl_device_ctx.h"
|
#include "ocl_igc_interface/igc_ocl_device_ctx.h"
|
||||||
@@ -38,6 +40,7 @@ std::string getDevicesTypes();
|
|||||||
class OfflineCompiler {
|
class OfflineCompiler {
|
||||||
public:
|
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);
|
||||||
|
static OfflineCompiler *create(size_t numArgs, const std::vector<std::string> &allArgs, bool dumpFiles, int &retVal, std::unique_ptr<OclocArgHelper> helper);
|
||||||
int build();
|
int build();
|
||||||
std::string &getBuildLog();
|
std::string &getBuildLog();
|
||||||
void printUsage();
|
void printUsage();
|
||||||
@@ -51,7 +54,9 @@ class OfflineCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string parseBinAsCharArray(uint8_t *binary, size_t size, std::string &fileName);
|
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() {
|
ArrayRef<const uint8_t> getPackedDeviceBinaryOutput() {
|
||||||
return this->elfBinary;
|
return this->elfBinary;
|
||||||
}
|
}
|
||||||
@@ -126,5 +131,7 @@ class OfflineCompiler {
|
|||||||
CIF::RAII::UPtr_t<CIF::CIFMain> fclMain = nullptr;
|
CIF::RAII::UPtr_t<CIF::CIFMain> fclMain = nullptr;
|
||||||
CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> fclDeviceCtx = nullptr;
|
CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> fclDeviceCtx = nullptr;
|
||||||
IGC::CodeType::CodeType_t preferredIntermediateRepresentation;
|
IGC::CodeType::CodeType_t preferredIntermediateRepresentation;
|
||||||
|
|
||||||
|
std::unique_ptr<OclocArgHelper> argHelper = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
|||||||
@@ -4,24 +4,27 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
#
|
#
|
||||||
|
|
||||||
set(CLOC_SRCS_UTILITIES
|
set(CLOC_LIB_SRCS_UTILITIES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/safety_caller.h
|
${CMAKE_CURRENT_SOURCE_DIR}/safety_caller.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/get_current_dir.h
|
${CMAKE_CURRENT_SOURCE_DIR}/get_current_dir.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/get_path.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
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_caller_windows.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/safety_guard_windows.h
|
${CMAKE_CURRENT_SOURCE_DIR}/windows/safety_guard_windows.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/seh_exception.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/windows/seh_exception.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/seh_exception.h
|
${CMAKE_CURRENT_SOURCE_DIR}/windows/seh_exception.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/windows/get_current_dir_windows.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/windows/get_current_dir_windows.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/windows/get_path.cpp
|
||||||
)
|
)
|
||||||
else()
|
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/safety_caller_linux.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/linux/get_current_dir_linux.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/linux/get_current_dir_linux.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/linux/get_path.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_sources(ocloc PRIVATE ${CLOC_SRCS_UTILITIES})
|
target_sources(ocloc_lib PRIVATE ${CLOC_LIB_SRCS_UTILITIES})
|
||||||
|
|||||||
10
offline_compiler/utilities/get_path.h
Normal file
10
offline_compiler/utilities/get_path.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern std::string getPath();
|
||||||
24
offline_compiler/utilities/linux/get_path.cpp
Normal file
24
offline_compiler/utilities/linux/get_path.cpp
Normal file
@@ -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("");
|
||||||
|
}
|
||||||
|
}
|
||||||
12
offline_compiler/utilities/windows/get_path.cpp
Normal file
12
offline_compiler/utilities/windows/get_path.cpp
Normal file
@@ -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)
|
set(cloc_cmd_prefix ocloc)
|
||||||
else()
|
else()
|
||||||
if(DEFINED NEO__IGC_LIBRARY_PATH)
|
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()
|
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()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND __cloc__options__ "-cl-kernel-arg-info")
|
list(APPEND __cloc__options__ "-cl-kernel-arg-info")
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${OUTPUT_FILES}
|
OUTPUT ${OUTPUT_FILES}
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ function(compile_kernel target gen_type platform_type kernel)
|
|||||||
set(cloc_cmd_prefix ocloc)
|
set(cloc_cmd_prefix ocloc)
|
||||||
else()
|
else()
|
||||||
if(DEFINED NEO__IGC_LIBRARY_PATH)
|
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()
|
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()
|
||||||
endif()
|
endif()
|
||||||
list(APPEND __cloc__options__ "-cl-kernel-arg-info")
|
list(APPEND __cloc__options__ "-cl-kernel-arg-info")
|
||||||
|
|||||||
@@ -205,9 +205,9 @@ if(WIN32)
|
|||||||
set(cloc_cmd_prefix ocloc)
|
set(cloc_cmd_prefix ocloc)
|
||||||
else()
|
else()
|
||||||
if(DEFINED NEO__IGC_LIBRARY_PATH)
|
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()
|
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()
|
||||||
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}/decoder/mock/mock_iga_wrapper.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_compiler.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_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/safety_caller.h
|
||||||
${NEO_SOURCE_DIR}/offline_compiler/utilities//get_current_dir.h
|
${NEO_SOURCE_DIR}/offline_compiler/utilities//get_current_dir.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
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_caller_windows.cpp
|
||||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/windows/safety_guard_windows.h
|
${NEO_SOURCE_DIR}/offline_compiler/utilities/windows/safety_guard_windows.h
|
||||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/windows/seh_exception.cpp
|
${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
|
${NEO_SOURCE_DIR}/offline_compiler/utilities/windows/get_current_dir_windows.cpp
|
||||||
)
|
)
|
||||||
else()
|
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_caller_linux.cpp
|
||||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/linux/safety_guard_linux.h
|
${NEO_SOURCE_DIR}/offline_compiler/utilities/linux/safety_guard_linux.h
|
||||||
${NEO_SOURCE_DIR}/offline_compiler/utilities/linux/get_current_dir_linux.cpp
|
${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_cloc}
|
||||||
${IGDRCL_SRCS_offline_compiler_mock}
|
${IGDRCL_SRCS_offline_compiler_mock}
|
||||||
${IGDRCL_SRCS_tests_compiler_mocks}
|
${IGDRCL_SRCS_tests_compiler_mocks}
|
||||||
${CLOC_SRCS_LIB}
|
${CLOC_LIB_SRCS_LIB}
|
||||||
${CLOC_SRCS_UTILITIES}
|
${CLOC_LIB_SRCS_UTILITIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
@@ -81,9 +82,9 @@ link_directories(${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
|||||||
add_executable(ocloc_tests ${IGDRCL_SRCS_offline_compiler_tests})
|
add_executable(ocloc_tests ${IGDRCL_SRCS_offline_compiler_tests})
|
||||||
|
|
||||||
target_include_directories(ocloc_tests PRIVATE
|
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)
|
target_link_libraries(ocloc_tests gmock-gtest)
|
||||||
|
|
||||||
@@ -95,25 +96,25 @@ if(UNIX)
|
|||||||
target_link_libraries(ocloc_tests dl pthread)
|
target_link_libraries(ocloc_tests dl pthread)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
get_property(CLOC_FOLDER TARGET ocloc PROPERTY FOLDER)
|
get_property(CLOC_LIB_FOLDER TARGET ocloc_lib PROPERTY FOLDER)
|
||||||
get_property(CLOC_COMPILE_FLAGS TARGET ocloc PROPERTY COMPILE_FLAGS)
|
get_property(CLOC_LIB_COMPILE_FLAGS TARGET ocloc_lib PROPERTY COMPILE_FLAGS)
|
||||||
set_property(TARGET ocloc_tests PROPERTY FOLDER ${CLOC_FOLDER})
|
set_property(TARGET ocloc_tests PROPERTY FOLDER ${CLOC_LIB_FOLDER})
|
||||||
set_property(TARGET ocloc_tests APPEND_STRING PROPERTY COMPILE_FLAGS ${CLOC_COMPILE_FLAGS})
|
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
|
add_custom_target(run_ocloc_tests ALL
|
||||||
DEPENDS ocloc_tests
|
DEPENDS ocloc_tests
|
||||||
)
|
)
|
||||||
macro(macro_for_each_platform)
|
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})
|
foreach(PLATFORM_TYPE ${PLATFORM_TYPES})
|
||||||
if(${PLATFORM_IT}_IS_${PLATFORM_TYPE})
|
if(${PLATFORM_IT}_IS_${PLATFORM_TYPE})
|
||||||
get_family_name_with_type(${GEN_TYPE} ${PLATFORM_TYPE})
|
get_family_name_with_type(${GEN_TYPE} ${PLATFORM_TYPE})
|
||||||
add_dependencies(run_ocloc_tests prepare_test_kernels_${family_name_with_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})
|
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})
|
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()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
@@ -123,17 +124,17 @@ macro(macro_for_each_gen)
|
|||||||
endmacro()
|
endmacro()
|
||||||
apply_macro_for_each_gen("TESTED")
|
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)
|
if(WIN32)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET run_ocloc_tests
|
TARGET run_ocloc_tests
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND echo deleting offline compiler files and directories...
|
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_LIB_DEFAULT_DEVICE}/copybuffer_${CLOC_LIB_DEFAULT_DEVICE}.bc
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/copybuffer_${CLOC_DEFAULT_DEVICE}.gen
|
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/copybuffer_${CLOC_LIB_DEFAULT_DEVICE}.gen
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/copybuffer_${CLOC_DEFAULT_DEVICE}.bin
|
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/copybuffer_${CLOC_LIB_DEFAULT_DEVICE}.bin
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TargetDir}/${CLOC_DEFAULT_DEVICE}/offline_compiler_test
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/offline_compiler_test
|
||||||
COMMAND ${run_tests_cmd}
|
COMMAND ${run_tests_cmd}
|
||||||
WORKING_DIRECTORY ${TargetDir}
|
WORKING_DIRECTORY ${TargetDir}
|
||||||
)
|
)
|
||||||
@@ -142,10 +143,10 @@ else()
|
|||||||
TARGET run_ocloc_tests
|
TARGET run_ocloc_tests
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND echo deleting offline compiler files and directories...
|
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_LIB_DEFAULT_DEVICE}/*.bc
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/*.gen
|
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/*.gen
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/*.ll
|
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/*.ll
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_DEFAULT_DEVICE}/*.bin
|
COMMAND ${CMAKE_COMMAND} -E remove ${TargetDir}/${CLOC_LIB_DEFAULT_DEVICE}/*.bin
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove_directory "${TargetDir}/offline_compiler_test"
|
COMMAND ${CMAKE_COMMAND} -E remove_directory "${TargetDir}/offline_compiler_test"
|
||||||
COMMAND ${run_tests_cmd}
|
COMMAND ${run_tests_cmd}
|
||||||
WORKING_DIRECTORY ${TargetDir}
|
WORKING_DIRECTORY ${TargetDir}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ SKernelBinaryHeaderCommon createKernelBinaryHeaderCommon(const uint32_t kernelNa
|
|||||||
|
|
||||||
namespace NEO {
|
namespace NEO {
|
||||||
TEST(DecoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
TEST(DecoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
||||||
const char *argv[] = {
|
std::vector<std::string> args = {
|
||||||
"ocloc",
|
"ocloc",
|
||||||
"decoder",
|
"decoder",
|
||||||
"-file",
|
"-file",
|
||||||
@@ -40,22 +40,22 @@ TEST(DecoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
|||||||
"test_files/created"};
|
"test_files/created"};
|
||||||
|
|
||||||
MockDecoder decoder;
|
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) {
|
TEST(DecoderTests, WhenMissingParametersThenValidateInputReturnsErrorCode) {
|
||||||
const char *argv[] = {
|
std::vector<std::string> args = {
|
||||||
"ocloc",
|
"ocloc",
|
||||||
"decoder",
|
"decoder",
|
||||||
"-patch",
|
"-patch",
|
||||||
"test_files"};
|
"test_files"};
|
||||||
|
|
||||||
MockDecoder decoder;
|
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) {
|
TEST(DecoderTests, GivenWrongParametersWhenParsingParametersThenValidateInputReturnsErrorCode) {
|
||||||
const char *argv[] = {
|
std::vector<std::string> args = {
|
||||||
"cloc",
|
"cloc",
|
||||||
"decoder",
|
"decoder",
|
||||||
"-file",
|
"-file",
|
||||||
@@ -66,7 +66,7 @@ TEST(DecoderTests, GivenWrongParametersWhenParsingParametersThenValidateInputRet
|
|||||||
"test_files/created"};
|
"test_files/created"};
|
||||||
|
|
||||||
MockDecoder decoder;
|
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) {
|
TEST(DecoderTests, GivenValidSizeStringWhenGettingSizeThenProperOutcomeIsExpectedAndExceptionIsNotThrown) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
namespace NEO {
|
namespace NEO {
|
||||||
TEST(EncoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
TEST(EncoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
||||||
const char *argv[] = {
|
std::vector<std::string> args = {
|
||||||
"ocloc",
|
"ocloc",
|
||||||
"asm",
|
"asm",
|
||||||
"-dump",
|
"-dump",
|
||||||
@@ -26,11 +26,11 @@ TEST(EncoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
|||||||
"test_files/binary_gen.bin"};
|
"test_files/binary_gen.bin"};
|
||||||
|
|
||||||
MockEncoder encoder;
|
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) {
|
TEST(EncoderTests, WhenMissingParametersThenErrorCodeIsReturned) {
|
||||||
const char *argv[] = {
|
std::vector<std::string> args = {
|
||||||
"ocloc",
|
"ocloc",
|
||||||
"asm",
|
"asm",
|
||||||
"-dump",
|
"-dump",
|
||||||
@@ -38,11 +38,11 @@ TEST(EncoderTests, WhenMissingParametersThenErrorCodeIsReturned) {
|
|||||||
"-out"};
|
"-out"};
|
||||||
|
|
||||||
MockEncoder encoder;
|
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) {
|
TEST(EncoderTests, GivenWrongParametersWhenParsingParametersThenErrorCodeIsReturned) {
|
||||||
const char *argv[] = {
|
std::vector<std::string> args = {
|
||||||
"ocloc",
|
"ocloc",
|
||||||
"asm",
|
"asm",
|
||||||
"-dump",
|
"-dump",
|
||||||
@@ -51,7 +51,7 @@ TEST(EncoderTests, GivenWrongParametersWhenParsingParametersThenErrorCodeIsRetur
|
|||||||
"rasputin"};
|
"rasputin"};
|
||||||
|
|
||||||
MockEncoder encoder;
|
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) {
|
TEST(EncoderTests, WhenTryingToCopyNonExistingFileThenErrorCodeIsReturned) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ struct MockDecoder : public BinaryDecoder {
|
|||||||
: BinaryDecoder(file, patch, dump) {
|
: BinaryDecoder(file, patch, dump) {
|
||||||
this->iga.reset(new MockIgaWrapper);
|
this->iga.reset(new MockIgaWrapper);
|
||||||
setMessagePrinter(MessagePrinter{true});
|
setMessagePrinter(MessagePrinter{true});
|
||||||
|
argHelper = std::make_unique<OclocArgHelper>();
|
||||||
};
|
};
|
||||||
using BinaryDecoder::binaryFile;
|
using BinaryDecoder::binaryFile;
|
||||||
using BinaryDecoder::decode;
|
using BinaryDecoder::decode;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "shared/source/helpers/hash.h"
|
#include "shared/source/helpers/hash.h"
|
||||||
|
|
||||||
#include "offline_compiler/decoder/binary_encoder.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"
|
#include "mock_iga_wrapper.h"
|
||||||
|
|
||||||
@@ -21,8 +22,11 @@ struct MockEncoder : public BinaryEncoder {
|
|||||||
: BinaryEncoder(dump, elf) {
|
: BinaryEncoder(dump, elf) {
|
||||||
this->iga.reset(new MockIgaWrapper);
|
this->iga.reset(new MockIgaWrapper);
|
||||||
setMessagePrinter(MessagePrinter{true});
|
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 {
|
bool copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary, uint32_t *binaryLength) override {
|
||||||
auto it = filesMap.find(srcFileName);
|
auto it = filesMap.find(srcFileName);
|
||||||
if (it == filesMap.end()) {
|
if (it == filesMap.end()) {
|
||||||
@@ -34,16 +38,6 @@ struct MockEncoder : public BinaryEncoder {
|
|||||||
}
|
}
|
||||||
return true;
|
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::addPadding;
|
||||||
using BinaryEncoder::calculatePatchListSizes;
|
using BinaryEncoder::calculatePatchListSizes;
|
||||||
using BinaryEncoder::copyBinaryToBinary;
|
using BinaryEncoder::copyBinaryToBinary;
|
||||||
@@ -60,6 +54,4 @@ struct MockEncoder : public BinaryEncoder {
|
|||||||
MockIgaWrapper *getMockIga() const {
|
MockIgaWrapper *getMockIga() const {
|
||||||
return static_cast<MockIgaWrapper *>(iga.get());
|
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;
|
using OfflineCompiler::useOptionsSuffix;
|
||||||
|
|
||||||
MockOfflineCompiler() : OfflineCompiler() {
|
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) {
|
int initialize(size_t numArgs, const std::vector<std::string> &argv) {
|
||||||
|
|||||||
@@ -1051,7 +1051,8 @@ TEST(OfflineCompilerTest, givenNonExistingFilenameWhenUsedToReadOptionsThenReadO
|
|||||||
std::string file("non_existing_file");
|
std::string file("non_existing_file");
|
||||||
ASSERT_FALSE(fileExists(file.c_str()));
|
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);
|
EXPECT_FALSE(result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ function(compile_builtin gen_type platform_type builtin bits builtin_options)
|
|||||||
set(cloc_cmd_prefix ocloc)
|
set(cloc_cmd_prefix ocloc)
|
||||||
else()
|
else()
|
||||||
if(DEFINED NEO__IGC_LIBRARY_PATH)
|
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()
|
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()
|
||||||
endif()
|
endif()
|
||||||
list(APPEND __cloc__options__ "-cl-kernel-arg-info")
|
list(APPEND __cloc__options__ "-cl-kernel-arg-info")
|
||||||
|
|||||||
Reference in New Issue
Block a user