forked from NVIDIA/cuda-quantum
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIntrinsics.h
More file actions
173 lines (142 loc) · 7.58 KB
/
Intrinsics.h
File metadata and controls
173 lines (142 loc) · 7.58 KB
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/****************************************************************-*- C++ -*-****
* Copyright (c) 2022 - 2025 NVIDIA Corporation & Affiliates. *
* All rights reserved. *
* *
* This source code and the accompanying materials are made available under *
* the terms of the Apache License 2.0 which accompanies this distribution. *
******************************************************************************/
#pragma once
#include "cudaq/Optimizer/Builder/Factory.h"
namespace cudaq {
namespace cc {
class GlobalOp;
}
/// This is the name of a dummy builtin to identify a std::move() call. These
/// calls will be erased before code gen.
static constexpr const char stdMoveBuiltin[] = ".std::move";
static constexpr const char llvmMemCopyIntrinsic[] =
"llvm.memcpy.p0i8.p0i8.i64";
// cudaq::range(count);
static constexpr const char setCudaqRangeVector[] = "__nvqpp_CudaqRangeInit";
// cudaq::range(start, stop, step);
static constexpr const char setCudaqRangeVectorTriple[] =
"__nvqpp_CudaqRangeInitTriple";
// Computes the number of iterations as from a semi-open interval as given by a
// cudaq::range() triple.
static constexpr const char getCudaqSizeFromTriple[] =
"__nvqpp_CudaqSizeFromTriple";
// Convert a sequence of booleans (as bytes) into a std::vector<bool> (which is
// typically specialized to be bit packed).
static constexpr const char stdvecBoolCtorFromInitList[] =
"__nvqpp_initializer_list_to_vector_bool";
// Convert a (likely packed) std::vector<bool> into a sequence of bytes, each
// holding a boolean value.
static constexpr const char stdvecBoolUnpackToInitList[] =
"__nvqpp_vector_bool_to_initializer_list";
// Free any temporary buffers used to hold std::vector<bool> data.
static constexpr const char stdvecBoolFreeTemporaryLists[] =
"__nvqpp_vector_bool_free_temporary_initlists";
// The internal data of the cudaq::state object must be `2**n` in length. This
// function returns the value `n`.
static constexpr const char getNumQubitsFromCudaqState[] =
"__nvqpp_cudaq_state_numberOfQubits";
// Create a new state from data.
static constexpr const char createCudaqStateFromDataFP64[] =
"__nvqpp_cudaq_state_createFromData_fp64";
static constexpr const char createCudaqStateFromDataFP32[] =
"__nvqpp_cudaq_state_createFromData_fp32";
// Delete a state created by the runtime functions above.
static constexpr const char deleteCudaqState[] = "__nvqpp_cudaq_state_delete";
/// Builder for lowering the clang AST to an IR for CUDA-Q. Lowering includes
/// the transformation of both quantum and classical computation. Different
/// features of the CUDA-Q programming model are lowered into different dialects
/// of MLIR. This builder makes heavy use of the Quake (QUAntum Kernel
/// Execution) and CC (Classical Computation) dialects.
///
/// This builder also allows for the inclusion of predefined intrinsics into
/// the `ModuleOp` on demand. Intrinsics exist in a map accessed by a symbol
/// name.
class IRBuilder : public mlir::OpBuilder {
public:
using OpBuilder::OpBuilder;
/// Create IRBuilder such that it has the same insertion point as \p builder.
IRBuilder(const mlir::OpBuilder &builder);
mlir::LLVM::ConstantOp genLlvmI32Constant(mlir::Location loc,
std::int32_t val) {
return opt::factory::genLlvmI32Constant(loc, *this, val);
}
/// Create a global for a C-style string. (A pointer to a NUL terminated
/// sequence of bytes.) `cstring` must have the NUL character appended \b
/// prior to calling this builder function.
mlir::LLVM::GlobalOp genCStringLiteral(mlir::Location loc,
mlir::ModuleOp module,
llvm::StringRef cstring);
/// Helper function to create a C-style string from a string that is not
/// already NUL terminated. No checks are made, so if the string already is
/// NUL terminated, a second NUL is appended.
mlir::LLVM::GlobalOp genCStringLiteralAppendNul(mlir::Location loc,
mlir::ModuleOp module,
llvm::StringRef cstring) {
auto buffer = cstring.str();
buffer += '\0';
return genCStringLiteral(loc, module, buffer);
}
cc::GlobalOp genVectorOfConstants(mlir::Location loc, mlir::ModuleOp module,
llvm::StringRef name,
mlir::DenseElementsAttr values,
mlir::Type elementType);
cc::GlobalOp genVectorOfConstants(
mlir::Location loc, mlir::ModuleOp module, llvm::StringRef name,
const llvm::SmallVectorImpl<std::complex<double>> &values);
cc::GlobalOp genVectorOfConstants(
mlir::Location loc, mlir::ModuleOp module, llvm::StringRef name,
const llvm::SmallVectorImpl<std::complex<float>> &values);
cc::GlobalOp
genVectorOfConstants(mlir::Location loc, mlir::ModuleOp module,
llvm::StringRef name,
const llvm::SmallVectorImpl<double> &values);
cc::GlobalOp genVectorOfConstants(mlir::Location loc, mlir::ModuleOp module,
llvm::StringRef name,
const llvm::SmallVectorImpl<float> &values);
cc::GlobalOp
genVectorOfConstants(mlir::Location loc, mlir::ModuleOp module,
llvm::StringRef name,
const llvm::SmallVectorImpl<std::int64_t> &values);
cc::GlobalOp
genVectorOfConstants(mlir::Location loc, mlir::ModuleOp module,
llvm::StringRef name,
const llvm::SmallVectorImpl<std::int32_t> &values);
cc::GlobalOp
genVectorOfConstants(mlir::Location loc, mlir::ModuleOp module,
llvm::StringRef name,
const llvm::SmallVectorImpl<std::int16_t> &values);
cc::GlobalOp
genVectorOfConstants(mlir::Location loc, mlir::ModuleOp module,
llvm::StringRef name,
const llvm::SmallVectorImpl<std::int8_t> &values);
cc::GlobalOp genVectorOfConstants(mlir::Location loc, mlir::ModuleOp module,
llvm::StringRef name,
const llvm::SmallVectorImpl<bool> &values);
/// Load an intrinsic into \p module. The intrinsic to load has name \p name.
/// This will automatically load any intrinsics that \p name depends upon.
/// Return `failure()` when \p name is not in the table of known intrinsics.
mlir::LogicalResult loadIntrinsic(mlir::ModuleOp module,
llvm::StringRef name);
llvm::StringRef getIntrinsicText(llvm::StringRef name);
mlir::LogicalResult loadIntrinsicWithAliases(mlir::ModuleOp module,
llvm::StringRef name,
llvm::StringRef prefix);
std::string hashStringByContent(llvm::StringRef sref);
/// Generates code that yields the size of any type that can be reified in
/// memory. Otherwise returns a `nullptr` Value.
mlir::Value getByteSizeOfType(mlir::Location loc, mlir::Type ty);
static IRBuilder atBlockEnd(mlir::Block *block) {
return IRBuilder(block, block->end(), nullptr);
}
static IRBuilder atBlockTerminator(mlir::Block *block) {
auto *terminator = block->getTerminator();
assert(terminator && "block has no terminator");
return IRBuilder(block, mlir::Block::iterator(terminator), nullptr);
}
};
} // namespace cudaq