From: David Neto Date: Wed, 30 Sep 2015 15:44:34 +0000 (-0400) Subject: Add assembler test for OpEnqueueKernel. X-Git-Tag: upstream/2018.6~1511^2~69 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ff5dce48a17d4b1b27f0edc9300418a96d01d143;p=platform%2Fupstream%2FSPIRV-Tools.git Add assembler test for OpEnqueueKernel. Adds a form of spvtest::MakeInstruction which takes two vectors of operands. That leads to simpler test code. We can clean up some other test code, in another CL. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index e0e853a..1e07b0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,6 +192,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES}) ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Constant.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.ControlFlow.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Debug.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.DeviceSideEnqueue.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Function.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Group.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Image.cpp diff --git a/test/TextToBinary.DeviceSideEnqueue.cpp b/test/TextToBinary.DeviceSideEnqueue.cpp new file mode 100644 index 0000000..f12c5fd --- /dev/null +++ b/test/TextToBinary.DeviceSideEnqueue.cpp @@ -0,0 +1,120 @@ +// Copyright (c) 2015 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are 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 Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE 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 +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +// Assembler tests for instructions in the "Device-Side Enqueue Instructions" +// section of the SPIR-V spec. + +#include "UnitSPIRV.h" + +#include "gmock/gmock.h" +#include "TestFixture.h" + +namespace { + +using spvtest::MakeInstruction; +using ::testing::Eq; + +// Test OpEnqueueKernel + +struct KernelEnqueueCase { + std::string local_size_source; + std::vector local_size_operands; +}; + +using OpEnqueueKernelGood = + spvtest::TextToBinaryTestBase<::testing::TestWithParam>; + +TEST_P(OpEnqueueKernelGood, Sample) { + std::string input = + "%result = OpEnqueueKernel %type %queue %flags %NDRange %num_events" + " %wait_events %ret_event %invoke %param %param_size %param_align " + + GetParam().local_size_source; + EXPECT_THAT(CompiledInstructions(input), + Eq(MakeInstruction(spv::OpEnqueueKernel, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, + GetParam().local_size_operands))); +} + +INSTANTIATE_TEST_CASE_P( + TextToBinaryTest, OpEnqueueKernelGood, + ::testing::ValuesIn(std::vector{ + // Provide IDs for pointer-to-local arguments for the + // invoked function. + // Test up to 10 such arguments. + // I (dneto) can't find a limit on the number of kernel + // arguments in OpenCL C 2.0 Rev 29, e.g. in section 6.9 + // Restrictions. + {"", {}}, + {"%l0", {13}}, + {"%l0 %l1", {13, 14}}, + {"%l0 %l1 %l2", {13, 14, 15}}, + {"%l0 %l1 %l2 %l3", {13, 14, 15, 16}}, + {"%l0 %l1 %l2 %l3 %l4", {13, 14, 15, 16, 17}}, + {"%l0 %l1 %l2 %l3 %l4 %l5", {13, 14, 15, 16, 17, 18}}, + {"%l0 %l1 %l2 %l3 %l4 %l5 %l6", {13, 14, 15, 16, 17, 18, 19}}, + {"%l0 %l1 %l2 %l3 %l4 %l5 %l6 %l7", {13, 14, 15, 16, 17, 18, 19, 20}}, + {"%l0 %l1 %l2 %l3 %l4 %l5 %l6 %l7 %l8", + {13, 14, 15, 16, 17, 18, 19, 20, 21}}, + {"%l0 %l1 %l2 %l3 %l4 %l5 %l6 %l7 %l8 %l9", + {13, 14, 15, 16, 17, 18, 19, 20, 21, 22}}, + })); + +// Test some bad parses of OpEnqueueKernel. For other cases, we're relying +// on the uniformity of the parsing algorithm. The following two tests, ensure +// that every required ID operand is specified, and is actually an ID operand. +using OpKernelEnqueueBad = spvtest::TextToBinaryTest; + +TEST_F(OpKernelEnqueueBad, MissingLastOperand) { + EXPECT_THAT( + CompileFailure( + "%result = OpEnqueueKernel %type %queue %flags %NDRange %num_events" + " %wait_events %ret_event %invoke %param %param_size"), + Eq("Expected operand, found end of stream.")); +} + +TEST_F(OpKernelEnqueueBad, InvalidLastOperand) { + EXPECT_THAT( + CompileFailure( + "%result = OpEnqueueKernel %type %queue %flags %NDRange %num_events" + " %wait_events %ret_event %invoke %param %param_size 42"), + Eq("Expected id to start with %.")); +} + +// TODO(dneto): OpEnqueueMarker +// TODO(dneto): OpGetKernelNDRangeSubGroupCount +// TODO(dneto): OpGetKernelNDRangeMaxSubGroupSize +// TODO(dneto): OpGetKernelWorkGroupSize +// TODO(dneto): OpGetKernelPreferredWorkGroupSizeMultiple +// TODO(dneto): OpRetainEvent +// TODO(dneto): OpReleaseEvent +// TODO(dneto): OpCreateUserEvent +// TODO(dneto): OpSetUserEventStatus +// TODO(dneto): OpCaptureEventProfilingInfo +// TODO(dneto): OpGetDefaultQueue +// TODO(dneto): OpBuildNDRange +// TODO(dneto): OpBuildNDRange + +} // anonymous namespace diff --git a/test/UnitSPIRV.h b/test/UnitSPIRV.h index 0ba10bc..8920209 100644 --- a/test/UnitSPIRV.h +++ b/test/UnitSPIRV.h @@ -109,14 +109,24 @@ inline void PrintTo(const WordVector& words, ::std::ostream* os) { // Returns a vector of words representing a single instruction with the // given opcode and operand words as a vector. -inline std::vector MakeInstruction(spv::Op opcode, - std::vector args) { +inline std::vector MakeInstruction( + spv::Op opcode, const std::vector& args) { std::vector result{ spvOpcodeMake(uint16_t(args.size() + 1), opcode)}; result.insert(result.end(), args.begin(), args.end()); return result; } +// Returns a vector of words representing a single instruction with the +// given opcode and whose operands are the concatenation of the two given +// argument lists. +inline std::vector MakeInstruction( + spv::Op opcode, std::vector args, + const std::vector& extra_args) { + args.insert(args.end(), extra_args.begin(), extra_args.end()); + return MakeInstruction(opcode, args); +} + // Encodes a string as a sequence of words, using the SPIR-V encoding. inline std::vector MakeVector(std::string input) { std::vector result;