File indexing completed on 2026-05-10 08:43:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_ANALYSIS_RELEASEMODEMODELRUNNER_H
0015 #define LLVM_ANALYSIS_RELEASEMODEMODELRUNNER_H
0016
0017 #include "llvm/ADT/StringExtras.h"
0018 #include "llvm/Analysis/MLModelRunner.h"
0019 #include "llvm/Analysis/TensorSpec.h"
0020 #include "llvm/Support/ErrorHandling.h"
0021 #include "llvm/Support/MD5.h"
0022
0023 #include <memory>
0024
0025 namespace llvm {
0026
0027
0028
0029 struct EmbeddedModelRunnerOptions {
0030
0031
0032
0033 StringRef FeedPrefix = "feed_";
0034 StringRef FetchPrefix = "fetch_";
0035
0036
0037
0038 StringRef ModelSelector = "";
0039
0040 EmbeddedModelRunnerOptions &setFeedPrefix(StringRef Value) {
0041 FeedPrefix = Value;
0042 return *this;
0043 }
0044 EmbeddedModelRunnerOptions &setFetchPrefix(StringRef Value) {
0045 FetchPrefix = Value;
0046 return *this;
0047 }
0048 EmbeddedModelRunnerOptions &setModelSelector(StringRef Value) {
0049 ModelSelector = Value;
0050 return *this;
0051 }
0052 };
0053
0054 template <class TGen>
0055 class ReleaseModeModelRunner final : public MLModelRunner {
0056 public:
0057
0058
0059 template <class FType>
0060 ReleaseModeModelRunner(LLVMContext &Ctx, const FType &InputSpec,
0061 StringRef DecisionName,
0062 const EmbeddedModelRunnerOptions &Options = {})
0063 : MLModelRunner(Ctx, MLModelRunner::Kind::Release, InputSpec.size() + 1),
0064 CompiledModel(std::make_unique<TGen>()) {
0065 assert(CompiledModel && "The CompiledModel should be valid");
0066
0067
0068
0069
0070
0071
0072 bool InputIsPresent = true;
0073 populateTensor(InputSpec.size(),
0074 TensorSpec::createSpec<uint64_t>("model_selector", {2}),
0075 Options.FeedPrefix, InputIsPresent);
0076
0077
0078
0079
0080 if (Options.ModelSelector.empty() && InputIsPresent)
0081 Ctx.emitError(
0082 "A model selector was not specified but the underlying model "
0083 "requires selecting one because it exposes a model_selector input");
0084 uint64_t High = 0;
0085 uint64_t Low = 0;
0086 if (!Options.ModelSelector.empty()) {
0087 if (!InputIsPresent)
0088 Ctx.emitError("A model selector was specified but the underlying model "
0089 "does not expose a model_selector input");
0090 const auto Hash = MD5::hash(arrayRefFromStringRef(Options.ModelSelector));
0091 High = Hash.high();
0092 Low = Hash.low();
0093 }
0094 getTensor<uint64_t>(InputSpec.size())[0] = High;
0095 getTensor<uint64_t>(InputSpec.size())[1] = Low;
0096
0097
0098
0099
0100
0101 for (size_t I = 0; I < InputSpec.size(); ++I)
0102 populateTensor(I, InputSpec[I], Options.FeedPrefix, InputIsPresent);
0103
0104 ResultIndex = CompiledModel->LookupResultIndex(Options.FetchPrefix.str() +
0105 DecisionName.str());
0106 assert(ResultIndex >= 0 && "Cannot find DecisionName in inlining model");
0107 }
0108
0109 virtual ~ReleaseModeModelRunner() = default;
0110
0111 static bool classof(const MLModelRunner *R) {
0112 return R->getKind() == MLModelRunner::Kind::Release;
0113 }
0114
0115 private:
0116
0117
0118
0119 void populateTensor(size_t Pos, const TensorSpec &Spec, StringRef Prefix,
0120 bool &InputIsPresent) {
0121 const int Index =
0122 CompiledModel->LookupArgIndex((Prefix + Spec.name()).str());
0123 void *Buffer = nullptr;
0124 InputIsPresent = Index >= 0;
0125 if (InputIsPresent)
0126 Buffer = CompiledModel->arg_data(Index);
0127 setUpBufferForTensor(Pos, Spec, Buffer);
0128 }
0129
0130 void *evaluateUntyped() override {
0131 CompiledModel->Run();
0132 return CompiledModel->result_data(ResultIndex);
0133 }
0134
0135 int32_t ResultIndex = -1;
0136 std::unique_ptr<TGen> CompiledModel;
0137 };
0138
0139
0140
0141
0142 class NoopSavedModelImpl final {
0143 #define NOOP_MODEL_ERRMSG \
0144 "The mock AOT-ed saved model is a compile-time stub and should not be " \
0145 "called."
0146
0147 public:
0148 NoopSavedModelImpl() = default;
0149 int LookupArgIndex(const std::string &) { llvm_unreachable(NOOP_MODEL_ERRMSG); }
0150 int LookupResultIndex(const std::string &) { llvm_unreachable(NOOP_MODEL_ERRMSG); }
0151 void Run() { llvm_unreachable(NOOP_MODEL_ERRMSG); }
0152 void *result_data(int) { llvm_unreachable(NOOP_MODEL_ERRMSG); }
0153 void *arg_data(int) { llvm_unreachable(NOOP_MODEL_ERRMSG); }
0154 #undef NOOP_MODEL_ERRMSG
0155 };
0156
0157 template <class T> bool isEmbeddedModelEvaluatorValid() { return true; }
0158
0159 template <> inline bool isEmbeddedModelEvaluatorValid<NoopSavedModelImpl>() {
0160 return false;
0161 }
0162 }
0163
0164 #endif