Skip to content

Commit 0bb7221

Browse files
authored
[SYCL] Device config file implementation (#9846)
Prototype implementation for default Device Config File designed in #9371. Part of the testing is not present yet, nor is the ability to extend the default config file. --------- Signed-off-by: Maronas, Marcos <[email protected]>
1 parent d88441c commit 0bb7221

File tree

11 files changed

+627
-0
lines changed

11 files changed

+627
-0
lines changed

llvm/include/llvm/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ add_subdirectory(IR)
77
add_subdirectory(Support)
88
add_subdirectory(Frontend)
99
add_subdirectory(TargetParser)
10+
add_subdirectory(SYCLLowerIR)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Use LLVM for each `tablegen(LLVM)`
2+
# LLVM_HEADERS_TABLEGEN (which is the default for this directory)
3+
# points to `llvm-min-tblgen`, but we need `llvm-tblgen`
4+
set(LLVM_TABLEGEN_PROJECT LLVM)
5+
6+
set(LLVM_TARGET_DEFINITIONS DeviceConfigFile.td)
7+
tablegen(LLVM DeviceConfigFile.inc -gen-dynamic-tables)
8+
add_public_tablegen_target(DeviceConfigFile)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//==--- DeviceConfigFile.hpp - Device Config File for SYCL ------*- C++ -*-==//
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+
9+
#include <map>
10+
#include <string>
11+
#include <vector>
12+
13+
class StringRef;
14+
15+
namespace DeviceConfigFile {
16+
17+
// This struct is used in DeviceConfigFile.td. Both the fields and the name of
18+
// this struct must match the definition in DeviceConfigFile.td. Thus, any
19+
// modification to this struct in this file must be mirrored in
20+
// DeviceConfigFile.td.
21+
struct TargetInfo {
22+
bool maySupportOtherAspects;
23+
std::vector<llvm::StringRef> aspects;
24+
std::vector<unsigned> subGroupSizes;
25+
std::string aotToolchain;
26+
std::string aotToolchainOptions;
27+
};
28+
using TargetTable_t = std::map<std::string, TargetInfo>;
29+
30+
#define GET_TargetTable_IMPL
31+
#include "llvm/SYCLLowerIR/DeviceConfigFile.inc"
32+
#undef GET_TargetTable_IMPL
33+
}; // namespace DeviceConfigFile
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//===-DeviceConfigFile.td - Device Config File for SYCL ---*--- tablegen -*-==//
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+
9+
include "llvm/TableGen/DynamicTable.td"
10+
11+
class Aspect<string name> {
12+
string Name = name;
13+
}
14+
15+
def AspectCpu : Aspect<"cpu">;
16+
def AspectGpu : Aspect<"gpu">;
17+
def AspectAccelerator : Aspect<"accelerator">;
18+
def AspectCustom : Aspect<"custom">;
19+
def AspectFp16 : Aspect<"fp16">;
20+
def AspectFp64 : Aspect<"fp64">;
21+
def AspectImage : Aspect<"image">;
22+
def AspectOnline_compiler : Aspect<"online_compiler">;
23+
def AspectOnline_linker : Aspect<"online_linker">;
24+
def AspectQueue_profiling : Aspect<"queue_profiling">;
25+
def AspectUsm_device_allocations : Aspect<"usm_device_allocations">;
26+
def AspectUsm_host_allocations : Aspect<"usm_host_allocations">;
27+
def AspectUsm_shared_allocations : Aspect<"usm_shared_allocations">;
28+
def AspectUsm_system_allocations : Aspect<"usm_system_allocations">;
29+
def AspectExt_intel_pci_address : Aspect<"ext_intel_pci_address">;
30+
def AspectExt_intel_gpu_eu_count : Aspect<"ext_intel_gpu_eu_count">;
31+
def AspectExt_intel_gpu_eu_simd_width : Aspect<"ext_intel_gpu_eu_simd_width">;
32+
def AspectExt_intel_gpu_slices : Aspect<"ext_intel_gpu_slices">;
33+
def AspectExt_intel_gpu_subslices_per_slice : Aspect<"ext_intel_gpu_subslices_per_slice">;
34+
def AspectExt_intel_gpu_eu_count_per_subslice : Aspect<"ext_intel_gpu_eu_count_per_subslice">;
35+
def AspectExt_intel_max_mem_bandwidth : Aspect<"ext_intel_max_mem_bandwidth">;
36+
def AspectExt_intel_mem_channel : Aspect<"ext_intel_mem_channel">;
37+
def AspectUsm_atomic_host_allocations : Aspect<"usm_atomic_host_allocations">;
38+
def AspectUsm_atomic_shared_allocations : Aspect<"usm_atomic_shared_allocations">;
39+
def AspectAtomic64 : Aspect<"atomic64">;
40+
def AspectExt_intel_device_info_uuid : Aspect<"ext_intel_device_info_uuid">;
41+
def AspectExt_oneapi_srgb : Aspect<"ext_oneapi_srgb">;
42+
def AspectExt_oneapi_native_assert : Aspect<"ext_oneapi_native_assert">;
43+
def AspectHost_debuggable : Aspect<"host_debuggable">;
44+
def AspectExt_intel_gpu_hw_threads_per_eu : Aspect<"ext_intel_gpu_hw_threads_per_eu">;
45+
def AspectExt_oneapi_cuda_async_barrier : Aspect<"ext_oneapi_cuda_async_barrier">;
46+
def AspectExt_oneapi_bfloat16_math_functions : Aspect<"ext_oneapi_bfloat16_math_functions">;
47+
def AspectExt_intel_free_memory : Aspect<"ext_intel_free_memory">;
48+
def AspectExt_intel_device_id : Aspect<"ext_intel_device_id">;
49+
def AspectExt_intel_memory_clock_rate : Aspect<"ext_intel_memory_clock_rate">;
50+
def AspectExt_intel_memory_bus_width : Aspect<"ext_intel_memory_bus_width">;
51+
def AspectEmulated : Aspect<"emulated">;
52+
def AspectExt_intel_legacy_image : Aspect<"ext_intel_legacy_image">;
53+
// Deprecated aspects
54+
def AspectInt64_base_atomics : Aspect<"int64_base_atomics">;
55+
def AspectInt64_extended_atomics : Aspect<"int64_extended_atomics">;
56+
def AspectUsm_system_allocator : Aspect<"usm_system_allocator">;
57+
def AspectUsm_restricted_shared_allocations : Aspect<"usm_restricted_shared_allocations">;
58+
def AspectHost : Aspect<"host">;
59+
defvar AllUSMAspects = [AspectUsm_device_allocations, AspectUsm_host_allocations,
60+
AspectUsm_shared_allocations, AspectUsm_system_allocations, AspectUsm_atomic_host_allocations,
61+
AspectUsm_atomic_shared_allocations];
62+
63+
64+
def TargetTable : DynamicTable {
65+
let FilterClass = "TargetInfo";
66+
let Fields = ["DeviceId", "maySupportOtherAspects", "aspects",
67+
"subGroupSizes", "aotToolchain", "aotToolchainOptions"];
68+
string TypeOf_aspects = "list<Aspect>";
69+
string TypeOf_subGroupSizes = "list<int>";
70+
}
71+
72+
// TargetInfo is a cpp struct defined in DeviceConfigFile.hpp. Both the fields
73+
// and the name must match those in DeviceConfigFile.hpp. Thus, any
74+
// modification to this definition in this file must be mirrored in
75+
// DeviceConfigFile.hpp.
76+
class TargetInfo<string targetName, list<Aspect> aspectList, list<int> subGroupSizesList, string toolchain = "", string options = "", bit maySupportOtherAspects_init = 0> {
77+
string DeviceId = targetName;
78+
bits<1> maySupportOtherAspects = maySupportOtherAspects_init;
79+
list<Aspect> aspects = aspectList;
80+
list<int> subGroupSizes = subGroupSizesList;
81+
string aotToolchain = toolchain;
82+
string aotToolchainOptions = options;
83+
}
84+
85+
// This definition serves the only purpose of testing whether the aspect list defined in here and in SYCL RT match.
86+
def : TargetInfo<"__TestAspectList",
87+
[AspectCpu, AspectGpu, AspectAccelerator, AspectCustom, AspectFp16, AspectFp64, AspectImage, AspectOnline_compiler,
88+
AspectOnline_linker, AspectQueue_profiling, AspectUsm_device_allocations, AspectUsm_host_allocations,
89+
AspectUsm_shared_allocations, AspectUsm_system_allocations, AspectExt_intel_pci_address,
90+
AspectExt_intel_gpu_eu_count, AspectExt_intel_gpu_eu_simd_width, AspectExt_intel_gpu_slices,
91+
AspectExt_intel_gpu_subslices_per_slice, AspectExt_intel_gpu_eu_count_per_subslice,
92+
AspectExt_intel_max_mem_bandwidth, AspectExt_intel_mem_channel, AspectUsm_atomic_host_allocations,
93+
AspectUsm_atomic_shared_allocations, AspectAtomic64, AspectExt_intel_device_info_uuid, AspectExt_oneapi_srgb,
94+
AspectExt_oneapi_native_assert, AspectHost_debuggable, AspectExt_intel_gpu_hw_threads_per_eu,
95+
AspectExt_oneapi_cuda_async_barrier, AspectExt_oneapi_bfloat16_math_functions, AspectExt_intel_free_memory,
96+
AspectExt_intel_device_id, AspectExt_intel_memory_clock_rate, AspectExt_intel_memory_bus_width, AspectEmulated,
97+
AspectExt_intel_legacy_image],
98+
[]>;
99+
// This definition serves the only purpose of testing whether the deprecated aspect list defined in here and in SYCL RT
100+
// match.
101+
def : TargetInfo<"__TestDeprecatedAspectList",
102+
[AspectInt64_base_atomics, AspectInt64_extended_atomics, AspectUsm_system_allocator,
103+
AspectUsm_restricted_shared_allocations, AspectHost],
104+
[]>;
105+
106+
// Examples of how to use a combination of explicitly specified values + predefined lists
107+
//defvar AspectList = [AspectCpu] # AllUSMAspects;
108+
//def : TargetInfo<"Test", AspectList, []>;
109+
//def : TargetInfo<"Test2", [AspectCpu] # AllUSMAspects, []>;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===- DynamicTable.td ----------------------------------*- tablegen -*-===//
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+
//
9+
// This file defines the key top-level classes needed to produce a reasonably
10+
// generic dynamic table that can be updated in runtime. DynamicTable objects
11+
// can be defined using the class in this file:
12+
// 1. (Dynamic) Tables. By instantiating the DynamicTable
13+
// class once, a table with the name of the instantiating def is generated and
14+
// guarded by the GET_name_IMPL preprocessor guard.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
// Define a record derived from this class to generate a dynamic table. This
19+
// table resembles a hashtable with a key-value pair, and can updated in runtime.
20+
//
21+
// The name of the record is used as the name of the global primary array of
22+
// entries of the table in C++.
23+
class DynamicTable {
24+
// Name of a class. The table will have one entry for each record that
25+
// derives from that class.
26+
string FilterClass;
27+
28+
// Name of the C++ struct/class type that holds table entries. The
29+
// declaration of this type is not generated automatically.
30+
string CppTypeName = FilterClass;
31+
32+
// List of the names of fields of collected records that contain the data for
33+
// table entries, in the order that is used for initialization in C++.
34+
//
35+
// TableGen needs to know the type of the fields so that it can format
36+
// the initializers correctly.
37+
//
38+
// For each field of the table named xxx, TableGen will look for a field
39+
// named TypeOf_xxx and use that as a more detailed description of the
40+
// type of the field.
41+
42+
// class MyTableEntry {
43+
// MyEnum V;
44+
// ...
45+
// }
46+
//
47+
// def MyTable : DynamicTable {
48+
// let FilterClass = "MyTableEntry";
49+
// let Fields = ["V", ...];
50+
// string TypeOf_V = "list<int>";
51+
// }
52+
list<string> Fields;
53+
}

llvm/lib/SYCLLowerIR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ add_llvm_component_library(LLVMSYCLLowerIR
8080
LLVMGenXIntrinsics
8181
LLVMDemangle
8282
LLVMTransformUtils
83+
DeviceConfigFile
8384

8485
LINK_LIBS
8586
LLVMGenXIntrinsics

llvm/test/TableGen/dynamic-tables.td

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// RUN: llvm-tblgen -gen-dynamic-tables -I %p/../../include %s | FileCheck %s
2+
// RUN: not llvm-tblgen -gen-dynamic-tables -I %p/../../include -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
3+
// XFAIL: vg_leak
4+
5+
include "llvm/TableGen/DynamicTable.td"
6+
7+
// CHECK-LABEL: GET_ATable_IMPL
8+
// CHECK: std::map<std::string, AEntry> ATable = {
9+
// CHECK: { "bar", {0x5, 0x3 }}, // 0
10+
// CHECK: { "baz", {0x2, 0x6 }}, // 1
11+
// CHECK: { "foo", {0x4, 0x4 }}, // 2
12+
// CHECK: { "foobar", {0x4, 0x5 }}, // 3
13+
// CHECK: };
14+
15+
class AEntry<string str, int val1, int val2> {
16+
string Str = str;
17+
bits<8> Val1 = val1;
18+
bits<10> Val2 = val2;
19+
}
20+
21+
def : AEntry<"bar", 5, 3>;
22+
def : AEntry<"baz", 2, 6>;
23+
def : AEntry<"foo", 4, 4>;
24+
def : AEntry<"foobar", 4, 5>;
25+
26+
def ATable : DynamicTable {
27+
let FilterClass = "AEntry";
28+
let Fields = ["Str", "Val1", "Val2"];
29+
}
30+
31+
32+
// CHECK-LABEL: GET_BTable_IMPL
33+
// CHECK: std::map<std::string, BTypeName> BTable = {
34+
// CHECK: { "BAlice", {0xAC, false, }}, // 0
35+
// CHECK: { "BBob", {0x14, false, Bob == 13 }}, // 1
36+
// CHECK: { "BCharlie", {0x80, true, Charlie == 42 }}, // 2
37+
// CHECK: { "BEve", {0x4C, true, Eve == 108 }}, // 3
38+
// CHECK: };
39+
40+
class BEntry<bits<16> enc, bit flag = 0, code test = [{}]> {
41+
string Name = NAME;
42+
bits<16> Encoding = enc;
43+
bit Flag = flag;
44+
code Test = test;
45+
}
46+
47+
def BAlice : BEntry<0xac>;
48+
def BBob : BEntry<0x14, 0, [{Bob == 13}]>;
49+
def BCharlie : BEntry<0x80, 1, "Charlie == 42">;
50+
def BEve : BEntry<0x4c, 1, [{Eve == }] # 108>;
51+
52+
def BTable : DynamicTable {
53+
let FilterClass = "BEntry";
54+
string CppTypeName = "BTypeName";
55+
let Fields = ["Name", "Encoding", "Flag", "Test"];
56+
string TypeOf_Test = "code";
57+
}
58+
59+
// CHECK-LABEL: GET_CTable_IMPL
60+
// CHECK: std::map<std::string, CEntry> CTable = {
61+
// CHECK: { "alice", {0xA }}, // 0
62+
// CHECK: { "alice", {0xD }}, // 1
63+
// CHECK: { "bob", {0xF }}, // 2
64+
// CHECK: };
65+
66+
class CEntry<string name, int enc> {
67+
string Name = name;
68+
bits<16> Encoding = enc;
69+
}
70+
71+
def : CEntry<"alice", 10>;
72+
def : CEntry<"alice", 13>;
73+
def : CEntry<"bob", 15>;
74+
75+
def CTable : DynamicTable {
76+
let FilterClass = "CEntry";
77+
let Fields = ["Name", "Encoding"];
78+
}
79+
80+
// CHECK-LABEL: GET_DTable_IMPL
81+
// CHECK: std::map<std::string, DEntry> DTable = {
82+
// CHECK: };
83+
84+
class DEntry<string name> {
85+
string Name = name;
86+
}
87+
88+
def DTable : DynamicTable {
89+
let FilterClass = "DEntry";
90+
let Fields = ["Name"];
91+
}
92+
93+
#ifdef ERROR1
94+
95+
class EEntry<string str, int val1> {
96+
string Str = str;
97+
bits<8> Val1 = val1;
98+
}
99+
100+
def EFoo : EEntry<"foo", 1>;
101+
// ERROR1: [[@LINE+1]]:5: error: Record 'EBar' for table 'ETable' is missing field 'Val1'
102+
def EBar : EEntry<"bar", ?>;
103+
104+
def ETable : DynamicTable {
105+
let FilterClass = "EEntry";
106+
let Fields = ["Str", "Val1"];
107+
}
108+
109+
#endif // ERROR1

llvm/utils/TableGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ add_tablegen(llvm-tblgen LLVM
5757
DFAPacketizerEmitter.cpp
5858
DisassemblerEmitter.cpp
5959
DXILEmitter.cpp
60+
DynamicTableEmitter.cpp
6061
ExegesisEmitter.cpp
6162
FastISelEmitter.cpp
6263
GICombinerEmitter.cpp

0 commit comments

Comments
 (0)