1// Copyright (c) 2015-2016 The Khronos Group Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// Assembler tests for instructions in the "Device-Side Enqueue Instructions" 16// section of the SPIR-V spec. 17 18#include <string> 19#include <vector> 20 21#include "gmock/gmock.h" 22#include "test/test_fixture.h" 23#include "test/unit_spirv.h" 24 25namespace spvtools { 26namespace { 27 28using spvtest::MakeInstruction; 29using ::testing::Eq; 30 31// Test OpEnqueueKernel 32 33struct KernelEnqueueCase { 34 std::string local_size_source; 35 std::vector<uint32_t> local_size_operands; 36}; 37 38using OpEnqueueKernelGood = 39 spvtest::TextToBinaryTestBase<::testing::TestWithParam<KernelEnqueueCase>>; 40 41TEST_P(OpEnqueueKernelGood, Sample) { 42 const std::string input = 43 "%result = OpEnqueueKernel %type %queue %flags %NDRange %num_events" 44 " %wait_events %ret_event %invoke %param %param_size %param_align " + 45 GetParam().local_size_source; 46 EXPECT_THAT(CompiledInstructions(input), 47 Eq(MakeInstruction(spv::Op::OpEnqueueKernel, 48 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, 49 GetParam().local_size_operands))); 50} 51 52INSTANTIATE_TEST_SUITE_P( 53 TextToBinaryTest, OpEnqueueKernelGood, 54 ::testing::ValuesIn(std::vector<KernelEnqueueCase>{ 55 // Provide IDs for pointer-to-local arguments for the 56 // invoked function. 57 // Test up to 10 such arguments. 58 // I (dneto) can't find a limit on the number of kernel 59 // arguments in OpenCL C 2.0 Rev 29, e.g. in section 6.9 60 // Restrictions. 61 {"", {}}, 62 {"%l0", {13}}, 63 {"%l0 %l1", {13, 14}}, 64 {"%l0 %l1 %l2", {13, 14, 15}}, 65 {"%l0 %l1 %l2 %l3", {13, 14, 15, 16}}, 66 {"%l0 %l1 %l2 %l3 %l4", {13, 14, 15, 16, 17}}, 67 {"%l0 %l1 %l2 %l3 %l4 %l5", {13, 14, 15, 16, 17, 18}}, 68 {"%l0 %l1 %l2 %l3 %l4 %l5 %l6", {13, 14, 15, 16, 17, 18, 19}}, 69 {"%l0 %l1 %l2 %l3 %l4 %l5 %l6 %l7", {13, 14, 15, 16, 17, 18, 19, 20}}, 70 {"%l0 %l1 %l2 %l3 %l4 %l5 %l6 %l7 %l8", 71 {13, 14, 15, 16, 17, 18, 19, 20, 21}}, 72 {"%l0 %l1 %l2 %l3 %l4 %l5 %l6 %l7 %l8 %l9", 73 {13, 14, 15, 16, 17, 18, 19, 20, 21, 22}}, 74 })); 75 76// Test some bad parses of OpEnqueueKernel. For other cases, we're relying 77// on the uniformity of the parsing algorithm. The following two tests, ensure 78// that every required ID operand is specified, and is actually an ID operand. 79using OpKernelEnqueueBad = spvtest::TextToBinaryTest; 80 81TEST_F(OpKernelEnqueueBad, MissingLastOperand) { 82 EXPECT_THAT( 83 CompileFailure( 84 "%result = OpEnqueueKernel %type %queue %flags %NDRange %num_events" 85 " %wait_events %ret_event %invoke %param %param_size"), 86 Eq("Expected operand for OpEnqueueKernel instruction, but found the end " 87 "of the stream.")); 88} 89 90TEST_F(OpKernelEnqueueBad, InvalidLastOperand) { 91 EXPECT_THAT( 92 CompileFailure( 93 "%result = OpEnqueueKernel %type %queue %flags %NDRange %num_events" 94 " %wait_events %ret_event %invoke %param %param_size 42"), 95 Eq("Expected id to start with %.")); 96} 97 98// TODO(dneto): OpEnqueueMarker 99// TODO(dneto): OpGetKernelNDRangeSubGroupCount 100// TODO(dneto): OpGetKernelNDRangeMaxSubGroupSize 101// TODO(dneto): OpGetKernelWorkGroupSize 102// TODO(dneto): OpGetKernelPreferredWorkGroupSizeMultiple 103// TODO(dneto): OpRetainEvent 104// TODO(dneto): OpReleaseEvent 105// TODO(dneto): OpCreateUserEvent 106// TODO(dneto): OpSetUserEventStatus 107// TODO(dneto): OpCaptureEventProfilingInfo 108// TODO(dneto): OpGetDefaultQueue 109// TODO(dneto): OpBuildNDRange 110// TODO(dneto): OpBuildNDRange 111 112} // namespace 113} // namespace spvtools 114