From 3389f530fb19247889048f9a2b2eedda14f3fea2 Mon Sep 17 00:00:00 2001 From: Viet-Hoa Do Date: Wed, 5 Jul 2023 17:36:40 +0100 Subject: Add kernel and kernel writer skeletons * Add the skeleton for kernel, kernel writer and their respective OpenCL implementation. * Add method to write code comment and its test. Resolves: COMPMID-6343 Signed-off-by: Viet-Hoa Do Change-Id: Ib986228154f7a00da7a5fd3b7105941325fe13b1 Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/9889 Tested-by: Arm Jenkins Reviewed-by: Gunes Bayir Comments-Addressed: Arm Jenkins Benchmark: Arm Jenkins --- compute_kernel_writer/CMakeLists.txt | 6 +- compute_kernel_writer/include/ckw/Error.h | 65 ++++++++++++++- compute_kernel_writer/include/ckw/Kernel.h | 61 ++++++++++++++ compute_kernel_writer/include/ckw/KernelWriter.h | 95 ++++++++++++++++++++++ .../include/ckw/types/TargetArchitecture.h | 40 +++++++++ .../include/ckw/types/TargetLanguage.h | 40 +++++++++ compute_kernel_writer/src/Kernel.cpp | 45 ++++++++++ compute_kernel_writer/src/KernelWriter.cpp | 48 +++++++++++ compute_kernel_writer/src/cl/CLKernelWriter.cpp | 64 +++++++++++++++ compute_kernel_writer/src/cl/CLKernelWriter.h | 91 +++++++++++++++++++++ compute_kernel_writer/validation/Validation.cpp | 3 + .../validation/tests/CLKernelWriterTest.h | 70 ++++++++++++++++ .../tests/common/KernelWriterInterceptor.h | 90 ++++++++++++++++++++ 13 files changed, 712 insertions(+), 6 deletions(-) create mode 100644 compute_kernel_writer/include/ckw/Kernel.h create mode 100644 compute_kernel_writer/include/ckw/KernelWriter.h create mode 100644 compute_kernel_writer/include/ckw/types/TargetArchitecture.h create mode 100644 compute_kernel_writer/include/ckw/types/TargetLanguage.h create mode 100644 compute_kernel_writer/src/Kernel.cpp create mode 100644 compute_kernel_writer/src/KernelWriter.cpp create mode 100644 compute_kernel_writer/src/cl/CLKernelWriter.cpp create mode 100644 compute_kernel_writer/src/cl/CLKernelWriter.h create mode 100644 compute_kernel_writer/validation/tests/CLKernelWriterTest.h create mode 100644 compute_kernel_writer/validation/tests/common/KernelWriterInterceptor.h diff --git a/compute_kernel_writer/CMakeLists.txt b/compute_kernel_writer/CMakeLists.txt index 3bc2aeda63..d763bc6de5 100644 --- a/compute_kernel_writer/CMakeLists.txt +++ b/compute_kernel_writer/CMakeLists.txt @@ -124,6 +124,8 @@ target_sources(ckw PRIVATE src/TensorUtils.cpp src/TileInfo.cpp src/ITileOperand.cpp + src/Kernel.cpp + src/KernelWriter.cpp ) if(CKW_ENABLE_OPENCL) @@ -132,6 +134,7 @@ if(CKW_ENABLE_OPENCL) src/cl/CLHelpers.cpp src/cl/CLTile.cpp src/cl/ICLTile.cpp + src/cl/CLKernelWriter.cpp ) endif() @@ -145,9 +148,6 @@ target_include_directories(ckw if(CKW_BUILD_TESTING) add_executable(ckw_validation - validation/tests/common/Common.h - validation/tests/TensorBitMaskTest.hpp - validation/tests/UtilsTest.hpp validation/Validation.cpp ) if(CKW_ENABLE_OPENCL) diff --git a/compute_kernel_writer/include/ckw/Error.h b/compute_kernel_writer/include/ckw/Error.h index 2793791802..100bdc48fe 100644 --- a/compute_kernel_writer/include/ckw/Error.h +++ b/compute_kernel_writer/include/ckw/Error.h @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef COMPUTE_KERNEL_WRITER_INCLUDE_CKW_ERROR_H -#define COMPUTE_KERNEL_WRITER_INCLUDE_CKW_ERROR_H +#ifndef CKW_INCLUDE_CKW_ERROR_H +#define CKW_INCLUDE_CKW_ERROR_H #include #include @@ -55,6 +55,65 @@ create_error_msg(const std::string &file, const std::string &func, const std::st std::runtime_error(create_error_msg(arg0, arg1, arg2, arg3)); \ } while(false) +/** Mark the variables as unused. + * + * @param[in] ... Variables which are unused. + */ +#define CKW_UNUSED(...) ckw::ignore_unused(__VA_ARGS__) // NOLINT + +/** Mark the variables as unused. + * + * @param[in] ... Variables which are unused. + */ +template +inline void ignore_unused(T &&...) +{ +} + +/** Throw an std::runtime_error with the specified message. + * + * @param[in] msg The error message. + */ +#define CKW_THROW_MSG(msg) \ + do \ + { \ + const std::string file(__FILE__); \ + const std::string func(__func__); \ + const std::string line(std::to_string(__LINE__)); \ + const std::string message(msg); \ + \ + throw std::runtime_error(ckw::create_error_msg(file, func, line, message)); \ + } while(false) + +#ifdef COMPUTE_KERNEL_WRITER_ASSERTS_ENABLED + +/** If the condition is not met, throw an std::runtime_error with the specified message. + * + * @param[in] cond The condition that is expected to be true. + * @param[in] msg The error message when the condition is not met. + */ +#define CKW_ASSERT_MSG(cond, msg) \ + do \ + { \ + if(!(cond)) \ + { \ + CKW_THROW_MSG(msg); \ + } \ + } while(false) + +/** If the condition is not met, throw an std::runtime_error. + * + * @param[in] cond The condition that is expected to be true. + */ +#define CKW_ASSERT(cond) CKW_ASSERT_MSG(cond, #cond) + +#else // COMPUTE_KERNEL_WRITER_ASSERTS_ENABLED + +#define CKW_ASSERT_MSG(cond, msg) +#define CKW_ASSERT(cond) + +#endif // COMPUTE_KERNEL_WRITER_ASSERTS_ENABLED + } // namespace ckw -#endif /* COMPUTE_KERNEL_WRITER_INCLUDE_CKW_ERROR_H */ +#endif // CKW_INCLUDE_CKW_ERROR_H diff --git a/compute_kernel_writer/include/ckw/Kernel.h b/compute_kernel_writer/include/ckw/Kernel.h new file mode 100644 index 0000000000..0cab713c48 --- /dev/null +++ b/compute_kernel_writer/include/ckw/Kernel.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef CKW_INCLUDE_CKW_KERNEL_H +#define CKW_INCLUDE_CKW_KERNEL_H + +#include "ckw/types/TargetLanguage.h" +#include + +namespace ckw +{ + +/** The kernel that has been emitted by the kernel writer. + * + * It contains all the necessary information to compile and execute the kernel. + */ +class Kernel +{ +public: + /** Initialize a new instance of @ref Kernel class with all emitted kernel information. + * + * @param[in] language The target language of the kernel. + * @param[in] source_code The source code of the kernel. + */ + Kernel(TargetLanguage language, const std::string &source_code); + + /** Get the target language. */ + TargetLanguage target_language() const; + + /** Get the source code. */ + const std::string &source_code() const; + +private: + TargetLanguage _language; + std::string _source_code; +}; + +} // namespace ckw + +#endif // CKW_INCLUDE_CKW_KERNEL_H diff --git a/compute_kernel_writer/include/ckw/KernelWriter.h b/compute_kernel_writer/include/ckw/KernelWriter.h new file mode 100644 index 0000000000..ba8a6015e6 --- /dev/null +++ b/compute_kernel_writer/include/ckw/KernelWriter.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef CKW_INCLUDE_CKW_KERNELWRITER_H +#define CKW_INCLUDE_CKW_KERNELWRITER_H + +#include "ckw/types/TargetArchitecture.h" +#include "ckw/types/TargetLanguage.h" +#include +#include + +namespace ckw +{ + +class Kernel; + +/** A kernel writer. + * + * This class is used to construct a new kernel by defining arguments, declaring variable and writing code. + * + * Use @ref KernelWriter::create_instance method to create the kernel writer for the specific target architecture and language. + * + * After having finished constructing the kernel, call @ref KernelWriter::emit_kernel to get the kernel object. + */ +class KernelWriter +{ +public: + // ============================================================================================= + // Construtors and destructor + // ============================================================================================= + + /** Initialize a new instance of @ref KernelWriter class for the specific architecture and language. + * + * Supported target architectures and languages: + * + * Architecture | Languages | + * ------------------------------|------------------------------| + * GpuArmMaliValhall | OpenCL | + * + * @param[in] architecture The architecture on which the kernel is executed. + * @param[in] language The language to write the kernel. + */ + static std::unique_ptr create_instance(TargetArchitecture architecture, TargetLanguage language); + + /** Destructor */ + virtual ~KernelWriter(); + + // ============================================================================================= + // Misc + // ============================================================================================= + + /** Write the line comment in debug build. + * This function does not take effect on release build. + * + * The comment must only contain one line (i.e. no newline character is allowed). + * + * @param[in] text The comment to be written. + */ + virtual void comment(const std::string &text) = 0; + + // ============================================================================================= + // Code generation + // ============================================================================================= + + /** Emit the kernel object. + * + * @param[in] name The name of the kernel object to be generated. + */ + virtual std::unique_ptr emit_kernel(const std::string &name) = 0; +}; + +} // namespace ckw + +#endif // CKW_INCLUDE_CKW_KERNELWRITER_H diff --git a/compute_kernel_writer/include/ckw/types/TargetArchitecture.h b/compute_kernel_writer/include/ckw/types/TargetArchitecture.h new file mode 100644 index 0000000000..25662a01f0 --- /dev/null +++ b/compute_kernel_writer/include/ckw/types/TargetArchitecture.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2023 Arm Limited. +* +* SPDX-License-Identifier: MIT +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ + +#ifndef CKW_INCLUDE_CKW_TYPES_TARGETARCHITECTURE_H +#define CKW_INCLUDE_CKW_TYPES_TARGETARCHITECTURE_H + +namespace ckw +{ + +/** Target platform architecture. */ +enum class TargetArchitecture +{ + Unknown, + GpuArmMaliValhall, +}; + +} // namespace ckw + +#endif // CKW_INCLUDE_CKW_TYPES_TARGETARCHITECTURE_H diff --git a/compute_kernel_writer/include/ckw/types/TargetLanguage.h b/compute_kernel_writer/include/ckw/types/TargetLanguage.h new file mode 100644 index 0000000000..1f507573dd --- /dev/null +++ b/compute_kernel_writer/include/ckw/types/TargetLanguage.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2023 Arm Limited. +* +* SPDX-License-Identifier: MIT +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ + +#ifndef CKW_INCLUDE_CKW_TYPES_TARGETLANGUAGE_H +#define CKW_INCLUDE_CKW_TYPES_TARGETLANGUAGE_H + +namespace ckw +{ + +/** Target language. */ +enum class TargetLanguage +{ + Unknown, + OpenCL +}; + +} // namespace ckw + +#endif // CKW_INCLUDE_CKW_TYPES_TARGETLANGUAGE_H diff --git a/compute_kernel_writer/src/Kernel.cpp b/compute_kernel_writer/src/Kernel.cpp new file mode 100644 index 0000000000..ccc68ecefb --- /dev/null +++ b/compute_kernel_writer/src/Kernel.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "ckw/Kernel.h" + +namespace ckw +{ + +Kernel::Kernel(TargetLanguage language, const std::string &source_code) + : _language(language), _source_code(source_code) +{ +} + +TargetLanguage Kernel::target_language() const +{ + return _language; +} + +const std::string &Kernel::source_code() const +{ + return _source_code; +} + +} // namespace ckw diff --git a/compute_kernel_writer/src/KernelWriter.cpp b/compute_kernel_writer/src/KernelWriter.cpp new file mode 100644 index 0000000000..eb8399a7ef --- /dev/null +++ b/compute_kernel_writer/src/KernelWriter.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "ckw/KernelWriter.h" +#include "ckw/Error.h" +#include "src/cl/CLKernelWriter.h" + +namespace ckw +{ + +std::unique_ptr KernelWriter::create_instance(TargetArchitecture architecture, TargetLanguage language) +{ + switch(language) + { + case TargetLanguage::OpenCL: + // Currently this is the oldest and the only supported GPU architecture. + CKW_ASSERT(architecture == TargetArchitecture::GpuArmMaliValhall); + return std::make_unique(); + + default: + CKW_THROW_MSG("Language not supported!"); + } +} + +KernelWriter::~KernelWriter() = default; + +} // namespace ckw diff --git a/compute_kernel_writer/src/cl/CLKernelWriter.cpp b/compute_kernel_writer/src/cl/CLKernelWriter.cpp new file mode 100644 index 0000000000..231d321c22 --- /dev/null +++ b/compute_kernel_writer/src/cl/CLKernelWriter.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "src/cl/CLKernelWriter.h" +#include "ckw/Error.h" + +namespace ckw +{ + +CLKernelWriter::CLKernelWriter() +{ +} + +CLKernelWriter::~CLKernelWriter() = default; + +std::unique_ptr CLKernelWriter::emit_kernel(const std::string &name) +{ + CKW_UNUSED(name); + CKW_THROW_MSG("Not implemented!"); +} + +void CLKernelWriter::comment(const std::string &text) +{ +#ifdef COMPUTE_KERNEL_WRITER_DEBUG_ENABLED + + CKW_ASSERT(text.find("\n") == text.npos); + CKW_ASSERT(text.find("\r") == text.npos); + + append_code("// ", text, "\n"); + +#else // COMPUTE_KERNEL_WRITER_DEBUG_ENABLED + + CKW_UNUSED(text); + +#endif // COMPUTE_KERNEL_WRITER_DEBUG_ENABLED +} + +const std::string &CLKernelWriter::body_source_code() const +{ + return _body_source_code; +} + +} // namespace ckw diff --git a/compute_kernel_writer/src/cl/CLKernelWriter.h b/compute_kernel_writer/src/cl/CLKernelWriter.h new file mode 100644 index 0000000000..e6f0641538 --- /dev/null +++ b/compute_kernel_writer/src/cl/CLKernelWriter.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef CKW_SRC_CL_CLKERNELWRITER_H +#define CKW_SRC_CL_CLKERNELWRITER_H + +#include "ckw/KernelWriter.h" +#include + +namespace ckw +{ + +/** OpenCL kernel writer. */ +class CLKernelWriter : public KernelWriter +{ +public: + // ============================================================================================= + // Construtors and destructor + // ============================================================================================= + + /** Initialize a new instance of @ref CLKernelWriter class. */ + CLKernelWriter(); + + /** Destructor */ + ~CLKernelWriter(); + + // ============================================================================================= + // Misc + // ============================================================================================= + + void comment(const std::string &text) override; + + // ============================================================================================= + // Code generation + // ============================================================================================= + + std::unique_ptr emit_kernel(const std::string &name) override; + +protected: + /** Append the specified code to the kernel body source code. */ + template + void append_code(T &&code, TArgs &&...args) + { + append_code(std::forward(code)); + append_code(std::forward(args)...); + } + + /** Append the specified code to the kernel body source code. */ + template + void append_code(T &&code) + { + _body_source_code += std::forward(code); + } + + /** Get the current kernel body source code. */ + const std::string &body_source_code() const; + +private: + /** This string contains the kernel body source code, not the full CL source code. + * The full source code will only be generated when the user calls @ref KernelWriter::emit_kernel. + * + * In order to add code to this, use @ref CLKernelWriter::append_code. + * Do not attempt to concatenate and alter this string directly. + */ + std::string _body_source_code{}; +}; + +} // namespace ckw + +#endif // CKW_SRC_CL_CLKERNELWRITER_H diff --git a/compute_kernel_writer/validation/Validation.cpp b/compute_kernel_writer/validation/Validation.cpp index 16c0d7696d..c0bdaaa0dc 100644 --- a/compute_kernel_writer/validation/Validation.cpp +++ b/compute_kernel_writer/validation/Validation.cpp @@ -26,6 +26,7 @@ #include "tests/CLTileTest.hpp" #include "tests/TensorBitMaskTest.hpp" #include "tests/UtilsTest.hpp" +#include "tests/CLKernelWriterTest.h" #include #include @@ -59,6 +60,7 @@ int32_t main() const auto test12 = std::make_unique(); const auto test13 = std::make_unique(); const auto test14 = std::make_unique(); + const auto test15 = std::make_unique(); tests.push_back(test3.get()); tests.push_back(test4.get()); @@ -72,6 +74,7 @@ int32_t main() tests.push_back(test12.get()); tests.push_back(test13.get()); tests.push_back(test14.get()); + tests.push_back(test15.get()); #endif /* COMPUTE_KERNEL_WRITER_OPENCL_ENABLED */ bool all_test_passed = true; diff --git a/compute_kernel_writer/validation/tests/CLKernelWriterTest.h b/compute_kernel_writer/validation/tests/CLKernelWriterTest.h new file mode 100644 index 0000000000..ff09ea8073 --- /dev/null +++ b/compute_kernel_writer/validation/tests/CLKernelWriterTest.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef CKW_VALIDATION_TESTS_CLKERNELTEST_H +#define CKW_VALIDATION_TESTS_CLKERNELTEST_H + +#include "src/cl/CLKernelWriter.h" +#include "validation/tests/common/Common.h" +#include "validation/tests/common/KernelWriterInterceptor.h" + +namespace ckw +{ + +class CLKernelWriterCommentTest : public ITest +{ +public: + CLKernelWriterCommentTest() + { + } + + bool run() override + { + bool all_tests_passed = true; + + KernelWriterInterceptor writer; + + writer.comment("previous code"); + + writer.start_capture_code(); + + writer.comment("code under test 0"); + writer.comment("code under test 1"); + + constexpr auto expected_code = "// code under test 0\n// code under test 1\n"; + + VALIDATE_TEST(writer.check_added_code(expected_code), all_tests_passed, 0); + + return all_tests_passed; + } + + std::string name() override + { + return "CLKernelWriterCommentTest"; + } +}; + +} // namespace ckw + +#endif // CKW_VALIDATION_TESTS_CLKERNELTEST_H diff --git a/compute_kernel_writer/validation/tests/common/KernelWriterInterceptor.h b/compute_kernel_writer/validation/tests/common/KernelWriterInterceptor.h new file mode 100644 index 0000000000..89bb76e37f --- /dev/null +++ b/compute_kernel_writer/validation/tests/common/KernelWriterInterceptor.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef CKW_VALIDATION_TESTS_COMMON_KERNELWRITERINTERCEPTOR_H +#define CKW_VALIDATION_TESTS_COMMON_KERNELWRITERINTERCEPTOR_H + +#include +#include + +namespace ckw +{ + +/** This class provides the ability to capture only the code changed after a point + * and compares that part of code with the expected value. + * + * It is useful for testing purpose when a particular sequence of instructions is interested + * while the rest of the initialization code is out of scope. + */ +template +class KernelWriterInterceptor : public T +{ +public: + template + KernelWriterInterceptor(const TArgs &&...args) + : T(std::forward(args)...) + { + } + + /** Mark this point in the source code as the start position to capture. + * Only source code added after this function is considered when check_add_code is called. + */ + void start_capture_code() + { + _start_code = this->body_source_code(); + } + + /** Compare the source code added after start_capture_code is called the the specified expected code. */ + bool check_added_code(const std::string &expected_added_code) + { + const auto &end_code = this->body_source_code(); + + // Code can only grow over time. + if(end_code.length() < _start_code.length()) + { + return false; + } + + // New code must be added to the source code without changing the already existed code. + if(end_code.substr(0, _start_code.length()) != _start_code) + { + return false; + } + + // The newly added code must match the expected value. + if(end_code.substr(_start_code.length(), end_code.length() - _start_code.length()) != expected_added_code) + { + return false; + } + + return true; + } + +private: + std::string _start_code{}; +}; + +} // namespace ckw + +#endif // CKW_VALIDATION_TESTS_COMMON_KERNELWRITERINTERCEPTOR_H -- cgit v1.2.1