Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

Commit a88c066

Browse files
sarnexv-klochkov
andauthored
[SYCL][ESIMD] Add large GRF test (#1686)
Signed-off-by: Sarnie, Nick <[email protected]> Co-authored-by: Vyacheslav Klochkov <[email protected]>
1 parent d578db9 commit a88c066

File tree

1 file changed

+195
-0
lines changed

1 file changed

+195
-0
lines changed

SYCL/ESIMD/large-grf.cpp

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
//==----------- large_grf.cpp - DPC++ ESIMD on-device test ---------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// This test verifies effect of
9+
// set_kernel_properties(kernel_properties::use_large_grf);
10+
// API call in device code:
11+
// - ESIMD/SYCL splitting happens as usual
12+
// - ESIMD module is further split into callgraphs for entry points requesting
13+
// "large GRF" and callgraphs for entry points which are not
14+
// - ESIMD device binary images requesting "large GRF" must be compiled with
15+
// -doubleGRF option
16+
17+
// REQUIRES: gpu-intel-pvc
18+
// UNSUPPORTED: cuda || hip
19+
// TODO/FIXME: esimd_emulator does not support online compilation that
20+
// invokes 'piProgramBuild'/'piKernelCreate'
21+
// UNSUPPORTED: esimd_emulator
22+
// RUN: %clangxx -fsycl %s -o %t.out
23+
// RUN: env SYCL_PI_TRACE=-1 %GPU_RUN_PLACEHOLDER %t.out 2>&1 %GPU_CHECK_PLACEHOLDER --check-prefixes=CHECK,CHECK-NO-VAR
24+
// RUN: env SYCL_PROGRAM_COMPILE_OPTIONS="-g" SYCL_PI_TRACE=-1 %GPU_RUN_PLACEHOLDER %t.out 2>&1 %GPU_CHECK_PLACEHOLDER --check-prefixes=CHECK,CHECK-WITH-VAR
25+
26+
#include "esimd_test_utils.hpp"
27+
28+
#include <iostream>
29+
#include <sycl/ext/intel/esimd.hpp>
30+
#include <sycl/ext/intel/experimental/kernel_properties.hpp>
31+
#include <sycl/sycl.hpp>
32+
33+
using namespace sycl;
34+
using namespace sycl::ext::intel::esimd;
35+
using namespace sycl::ext::intel::experimental;
36+
using namespace sycl::ext::intel::experimental::esimd;
37+
38+
bool checkResult(const std::vector<float> &A, int Inc) {
39+
int err_cnt = 0;
40+
unsigned Size = A.size();
41+
42+
for (unsigned i = 0; i < Size; ++i) {
43+
if (A[i] != i + Inc)
44+
if (++err_cnt < 10)
45+
std::cerr << "failed at A[" << i << "]: " << A[i] << " != " << i + Inc
46+
<< "\n";
47+
}
48+
49+
if (err_cnt > 0) {
50+
std::cout << " pass rate: "
51+
<< ((float)(Size - err_cnt) / (float)Size) * 100.0f << "% ("
52+
<< (Size - err_cnt) << "/" << Size << ")\n";
53+
return false;
54+
}
55+
return true;
56+
}
57+
58+
// Make the large GRF request from non-inlineable function - compiler should
59+
// mark the caller kernel as "large GRF" anyway.
60+
__attribute__((noinline)) void large_grf_marker() {
61+
set_kernel_properties(kernel_properties::use_large_grf);
62+
}
63+
64+
int main(void) {
65+
constexpr unsigned Size = 32;
66+
constexpr unsigned VL = 16;
67+
68+
std::vector<float> A(Size);
69+
70+
for (unsigned i = 0; i < Size; ++i) {
71+
A[i] = i;
72+
}
73+
74+
try {
75+
buffer<float, 1> bufa(A.data(), range<1>(Size));
76+
queue q(gpu_selector{}, esimd_test::createExceptionHandler());
77+
78+
auto dev = q.get_device();
79+
std::cout << "Running on " << dev.get_info<info::device::name>() << "\n";
80+
81+
auto e = q.submit([&](handler &cgh) {
82+
auto PA = bufa.get_access<access::mode::read_write>(cgh);
83+
cgh.parallel_for<class SyclKernel>(Size,
84+
[=](id<1> i) { PA[i] = PA[i] + 1; });
85+
});
86+
e.wait();
87+
} catch (sycl::exception const &e) {
88+
std::cout << "SYCL exception caught: " << e.what() << '\n';
89+
return 2;
90+
}
91+
92+
if (checkResult(A, 1)) {
93+
std::cout << "SYCL kernel passed\n";
94+
} else {
95+
std::cout << "SYCL kernel failed\n";
96+
return 1;
97+
}
98+
99+
try {
100+
buffer<float, 1> bufa(A.data(), range<1>(Size));
101+
queue q(esimd_test::ESIMDSelector, esimd_test::createExceptionHandler());
102+
103+
auto dev = q.get_device();
104+
std::cout << "Running on " << dev.get_info<info::device::name>() << "\n";
105+
106+
auto e = q.submit([&](handler &cgh) {
107+
auto PA = bufa.get_access<access::mode::read_write>(cgh);
108+
cgh.parallel_for<class EsimdKernel>(Size, [=](id<1> i) SYCL_ESIMD_KERNEL {
109+
unsigned int offset = i * VL * sizeof(float);
110+
simd<float, VL> va;
111+
va.copy_from(PA, offset);
112+
simd<float, VL> vc = va + 1;
113+
vc.copy_to(PA, offset);
114+
});
115+
});
116+
e.wait();
117+
} catch (sycl::exception const &e) {
118+
std::cout << "SYCL exception caught: " << e.what() << '\n';
119+
return 2;
120+
}
121+
122+
if (checkResult(A, 2)) {
123+
std::cout << "ESIMD kernel passed\n";
124+
} else {
125+
std::cout << "ESIMD kernel failed\n";
126+
return 1;
127+
}
128+
129+
try {
130+
buffer<float, 1> bufa(A.data(), range<1>(Size));
131+
queue q(esimd_test::ESIMDSelector, esimd_test::createExceptionHandler());
132+
133+
auto dev = q.get_device();
134+
std::cout << "Running on " << dev.get_info<info::device::name>() << "\n";
135+
136+
auto e = q.submit([&](handler &cgh) {
137+
auto PA = bufa.get_access<access::mode::read_write>(cgh);
138+
cgh.parallel_for<class EsimdKernelLargeGRF>(
139+
Size, [=](id<1> i) SYCL_ESIMD_KERNEL {
140+
large_grf_marker();
141+
unsigned int offset = i * VL * sizeof(float);
142+
simd<float, VL> va;
143+
va.copy_from(PA, offset);
144+
simd<float, VL> vc = va + 1;
145+
vc.copy_to(PA, offset);
146+
});
147+
});
148+
e.wait();
149+
} catch (sycl::exception const &e) {
150+
std::cout << "SYCL exception caught: " << e.what() << '\n';
151+
return 2;
152+
}
153+
154+
if (checkResult(A, 3)) {
155+
std::cout << "ESIMD large GRF kernel passed\n";
156+
} else {
157+
std::cout << "ESIMD large GRF kernel failed\n";
158+
return 1;
159+
}
160+
161+
return 0;
162+
}
163+
164+
// Regular SYCL kernel is compiled without -vc-codegen option
165+
166+
// CHECK-LABEL: ---> piProgramBuild(
167+
// CHECK-NOT: -vc-codegen
168+
// CHECK-WITH-VAR: -g
169+
// CHECK-NOT: -vc-codegen
170+
// CHECK: ) ---> pi_result : PI_SUCCESS
171+
// CHECK-LABEL: ---> piKernelCreate(
172+
// CHECK: <const char *>: {{.*}}SyclKernel
173+
// CHECK: ) ---> pi_result : PI_SUCCESS
174+
175+
// For ESIMD kernels, -vc-codegen option is always preserved,
176+
// regardless of SYCL_PROGRAM_COMPILE_OPTIONS value.
177+
178+
// CHECK-LABEL: ---> piProgramBuild(
179+
// CHECK-NO-VAR: -vc-codegen -disable-finalizer-msg
180+
// CHECK-WITH-VAR: -g -vc-codegen -disable-finalizer-msg
181+
// CHECK: ) ---> pi_result : PI_SUCCESS
182+
// CHECK-LABEL: ---> piKernelCreate(
183+
// CHECK: <const char *>: {{.*}}EsimdKernel
184+
// CHECK: ) ---> pi_result : PI_SUCCESS
185+
186+
// Kernels requesting larger GRF are grouped into separate module and compiled
187+
// with -largeGRF regardless of SYCL_PROGRAM_COMPILE_OPTIONS value.
188+
189+
// CHECK-LABEL: ---> piProgramBuild(
190+
// CHECK-NO-VAR: -vc-codegen -disable-finalizer-msg -doubleGRF
191+
// CHECK-WITH-VAR: -g -vc-codegen -disable-finalizer-msg -doubleGRF
192+
// CHECK: ) ---> pi_result : PI_SUCCESS
193+
// CHECK-LABEL: ---> piKernelCreate(
194+
// CHECK: <const char *>: {{.*}}EsimdKernelLargeGRF
195+
// CHECK: ) ---> pi_result : PI_SUCCESS

0 commit comments

Comments
 (0)