83 lines · cpp
1//===- InteractiveModelRunner.cpp - noop ML model runner ----------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// A runner that communicates with an external agent via 2 file descriptors.10//===----------------------------------------------------------------------===//11#include "llvm/Analysis/InteractiveModelRunner.h"12#include "llvm/Analysis/MLModelRunner.h"13#include "llvm/Analysis/TensorSpec.h"14#include "llvm/Support/CommandLine.h"15#include "llvm/Support/ErrorHandling.h"16#include "llvm/Support/FileSystem.h"17#include "llvm/Support/raw_ostream.h"18 19using namespace llvm;20 21static cl::opt<bool> DebugReply(22 "interactive-model-runner-echo-reply", cl::init(false), cl::Hidden,23 cl::desc("The InteractiveModelRunner will echo back to stderr "24 "the data received from the host (for debugging purposes)."));25 26InteractiveModelRunner::InteractiveModelRunner(27 LLVMContext &Ctx, const std::vector<TensorSpec> &Inputs,28 const TensorSpec &Advice, StringRef OutboundName, StringRef InboundName)29 : MLModelRunner(Ctx, MLModelRunner::Kind::Interactive, Inputs.size()),30 InputSpecs(Inputs), OutputSpec(Advice),31 InEC(sys::fs::openFileForRead(InboundName, Inbound)),32 OutputBuffer(OutputSpec.getTotalTensorBufferSize()) {33 if (InEC) {34 Ctx.emitError("Cannot open inbound file: " + InEC.message());35 return;36 }37 {38 auto OutStream = std::make_unique<raw_fd_ostream>(OutboundName, OutEC);39 if (OutEC) {40 Ctx.emitError("Cannot open outbound file: " + OutEC.message());41 return;42 }43 Log = std::make_unique<Logger>(std::move(OutStream), InputSpecs, Advice,44 /*IncludeReward=*/false, Advice);45 }46 // Just like in the no inference case, this will allocate an appropriately47 // sized buffer.48 for (size_t I = 0; I < InputSpecs.size(); ++I)49 setUpBufferForTensor(I, InputSpecs[I], nullptr);50 Log->flush();51}52 53InteractiveModelRunner::~InteractiveModelRunner() {54 sys::fs::file_t FDAsOSHandle = sys::fs::convertFDToNativeFile(Inbound);55 sys::fs::closeFile(FDAsOSHandle);56}57 58void *InteractiveModelRunner::evaluateUntyped() {59 Log->startObservation();60 for (size_t I = 0; I < InputSpecs.size(); ++I)61 Log->logTensorValue(I, reinterpret_cast<const char *>(getTensorUntyped(I)));62 Log->endObservation();63 Log->flush();64 65 size_t InsPoint = 0;66 char *Buff = OutputBuffer.data();67 const size_t Limit = OutputBuffer.size();68 while (InsPoint < Limit) {69 auto ReadOrErr = ::sys::fs::readNativeFile(70 sys::fs::convertFDToNativeFile(Inbound),71 {Buff + InsPoint, OutputBuffer.size() - InsPoint});72 if (ReadOrErr.takeError()) {73 Ctx.emitError("Failed reading from inbound file");74 break;75 }76 InsPoint += *ReadOrErr;77 }78 if (DebugReply)79 dbgs() << OutputSpec.name() << ": "80 << tensorValueToString(OutputBuffer.data(), OutputSpec) << "\n";81 return OutputBuffer.data();82}83