File: VLD_SPIRVSplitter.hpp

package info (click to toggle)
intel-graphics-compiler 1.0.17791.18-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 102,312 kB
  • sloc: cpp: 935,343; lisp: 286,143; ansic: 16,196; python: 3,279; yacc: 2,487; lex: 1,642; pascal: 300; sh: 174; makefile: 27
file content (138 lines) | stat: -rw-r--r-- 4,761 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*========================== begin_copyright_notice ============================

Copyright (C) 2023 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

#include "spirv-tools/libspirv.h"
#include <llvm/Support/Error.h>
#include <unordered_set>
#include <unordered_map>
#include <vector>

#include "VLD.hpp"

#pragma once

namespace IGC {
namespace VLD {

using ProgramStreamType = std::vector<uint32_t>;

// Splits SPIR-V module that contains ESIMD and SPMD parts into separate
// SPIR-V modules.
// Returns a pair of binaries: first is SPMD module, second is ESIMD module.
llvm::Expected<std::pair<ProgramStreamType, ProgramStreamType>>
SplitSPMDAndESIMD(const char *spvBuffer, uint32_t spvBufferSizeInBytes);

// Detects the type of the SPIR-V module, e.g. SPMD, ESIMD, SPMD+ESIMD
llvm::Expected<SPVMetadata> GetVLDMetadata(const char* spv_buffer,
  uint32_t spv_buffer_size_in_bytes);

// Class used to split SPMD and ESIMD parts of input SPIR-V module.
class SpvSplitter {
public:
  // Splits SPIR-V module that contains ESIMD and SPMD parts into separate
  // SPIR-V modules.
  // Returns a pair of binaries: first is SPMD module, second is ESIMD module.
  llvm::Expected<std::pair<ProgramStreamType, ProgramStreamType>>
  Split(const char *spv_buffer, uint32_t spv_buffer_size_in_bytes);

  // Parses the SPIR-V module and returns metadata necessary for visa linking.
  llvm::Expected<SPVMetadata>
  Parse(const char *spv_buffer, uint32_t spv_buffer_size_in_bytes);

  const std::string& GetErrorMessage() const;

  const uint32_t GetForcedSubgroupSize() const;

  bool HasError() const;

  bool HasEntryPoints() const;

  const std::vector<std::string>& GetExportedFunctions() const;

  const std::vector<std::string>& GetImportedFunctions() const;

  SPVMetadata GetVLDMetadata() const;

  void Reset();

  // Callbacks used by SPIR-V Tools parser.
  static spv_result_t
  HandleInstructionCallback(void *user_data,
                            const spv_parsed_instruction_t *parsed_instruction);

  static spv_result_t HandleHeaderCallback(void *user_data,
                                           spv_endianness_t endian,
                                           uint32_t magic, uint32_t version,
                                           uint32_t generator,
                                           uint32_t id_bound, uint32_t schema);

  const ProgramStreamType &spmd_program() const { return spmd_program_; }
  const ProgramStreamType &esimd_program() const { return esimd_program_; }

private:
  spv_result_t HandleHeader(spv_endianness_t endian, uint32_t magic,
                            uint32_t version, uint32_t generator,
                            uint32_t id_bound, uint32_t schema);

  spv_result_t
  HandleInstruction(const spv_parsed_instruction_t *parsed_instruction);

  spv_result_t
  HandleDecorate(const spv_parsed_instruction_t *parsed_instruction);

  spv_result_t
  HandleGroupDecorate(const spv_parsed_instruction_t *parsed_instruction);

  spv_result_t
  HandleFunctionStart(const spv_parsed_instruction_t *parsed_instruction);

  spv_result_t
  HandleFunctionParameter(const spv_parsed_instruction_t *parsed_instruction);

  spv_result_t
  HandleFunctionEnd(const spv_parsed_instruction_t *parsed_instruction);

  spv_result_t
  HandleEntryPoint(const spv_parsed_instruction_t *parsed_instruction);

  spv_result_t
  HandleExecutionMode(const spv_parsed_instruction_t *parsed_instruction);

  void AddInstToProgram(const spv_parsed_instruction_t *parsed_instruction,
                        ProgramStreamType &program);

  llvm::Expected<spv_result_t> ParseSPIRV(const char* spv_buffer, uint32_t spv_buffer_size_in_bytes);

  // Returns current SPIR-V Module type. Must be called after ParseSPIRV
  SPIRVTypeEnum GetCurrentSPIRVType() const;

  // When this flag is set to true, instructions will not be added to
  // spmd_program_ and esimd_program_ buffers.
  bool only_detect_ = false;

  ProgramStreamType spmd_program_;
  ProgramStreamType esimd_program_;
  std::unordered_set<uint32_t> esimd_decorated_ids_;
  std::unordered_set<uint32_t> entry_points_;
  std::unordered_map<uint32_t, ProgramStreamType> esimd_function_declarations_;
  std::unordered_set<uint32_t> esimd_functions_to_declare_;
  std::unordered_map<uint32_t, uint32_t> entry_point_to_subgroup_size_map_;
  std::vector<std::string> exported_functions_;
  std::vector<std::string> imported_functions_;

  bool is_inside_spmd_function_ = false;
  bool is_inside_esimd_function_ = false;
  bool has_spmd_functions_ = false;
  bool has_esimd_functions_ = false;
  int cur_esimd_function_id_ = -1;

  std::string error_message_;
};

} // namespace VLD
} // namespace IGC