Skip to content

Commit effba6f

Browse files
Request manager configuration class
1 parent f682870 commit effba6f

5 files changed

Lines changed: 91 additions & 55 deletions

File tree

examples/basic/policy.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
{
1414
"Capacity": 32,
1515
"Size": 16384
16-
},
17-
"User Interface":
18-
{
19-
"Input": "Catheti",
20-
"Output": "Hypotenuse"
2116
}
2217
},
18+
"Request Manager":
19+
{
20+
"Input": "Catheti",
21+
"Output": "Hypotenuse"
22+
},
2323
"Partitions": [
2424
{
2525
"Name": "Entry Partition",

include/hllm/configuration/deployment.hpp

Lines changed: 30 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "partition.hpp"
44
#include "edge.hpp"
5+
#include "requestManager.hpp"
56
#include <vector>
67
#include <memory>
78
#include <string>
@@ -58,26 +59,10 @@ class Deployment final
5859
std::shared_ptr<HiCR::MemorySpace> memorySpace = nullptr;
5960
};
6061

61-
/**
62-
* User interface relates to how the user connects to hLLM, feeds a prompt and gets a response
63-
*/
64-
struct userInterface_t
65-
{
66-
// Indicates which input in the execution graph is fed by the user
67-
std::string input;
68-
69-
// Indicates which output in the execution graph is fed to the user
70-
std::string output;
71-
72-
// Indicates which instance Id to assign to the user interface -- determined at runtime
73-
HiCR::Instance::instanceId_t instanceId = 0;
74-
};
75-
7662
struct settings_t
7763
{
7864
heartbeat_t heartbeat;
7965
controlBuffer_t controlBuffer;
80-
userInterface_t userInterface;
8166
};
8267

8368
Deployment(const std::string& name) : _name(name) {};
@@ -95,7 +80,7 @@ class Deployment final
9580
[[nodiscard]] __INLINE__ auto& getHeartbeat() const { return _settings.heartbeat; }
9681
[[nodiscard]] __INLINE__ auto& getControlBuffer() { return _settings.controlBuffer; }
9782
[[nodiscard]] __INLINE__ auto& getControlBufferConst() const { return _settings.controlBuffer; }
98-
[[nodiscard]] __INLINE__ auto& getUserInterface() const { return _settings.userInterface; }
83+
[[nodiscard]] __INLINE__ auto& getRequestManager() const { return _requestManager; }
9984

10085
[[nodiscard]] __INLINE__ nlohmann::json serialize() const
10186
{
@@ -111,6 +96,8 @@ class Deployment final
11196
for (const auto& e : _edges) edgesJs.push_back(e->serialize());
11297
js["Edges"] = edgesJs;
11398

99+
js["Request Manager"] = _requestManager->serialize();
100+
114101
////////////////////// Parsing settings
115102
auto settings = std::map<std::string, nlohmann::json>();
116103

@@ -128,13 +115,6 @@ class Deployment final
128115
controlBuffer["Size"] = _settings.controlBuffer.size;
129116
settings["Control Buffer"] = controlBuffer;
130117

131-
// User Interface
132-
auto userInterface = std::map<std::string, nlohmann::json>();
133-
userInterface["Input"] = _settings.userInterface.input;
134-
userInterface["Output"] = _settings.userInterface.output;
135-
userInterface["Instance Id"] = _settings.userInterface.instanceId;
136-
settings["User Interface"] = userInterface;
137-
138118
js["Settings"] = settings;
139119

140120
return js;
@@ -154,6 +134,9 @@ class Deployment final
154134
const auto& edges = hicr::json::getArray<nlohmann::json>(js, "Edges");
155135
for (const auto& e : edges) _edges.push_back(std::make_shared<Edge>(e));
156136

137+
const auto& requestManagerJs = hicr::json::getObject(js, "Request Manager");
138+
_requestManager = std::make_shared<RequestManager>(requestManagerJs);
139+
157140
// Getting settings
158141
nlohmann::json settingsJs = hicr::json::getObject(js, "Settings");
159142

@@ -166,16 +149,15 @@ class Deployment final
166149
nlohmann::json controlBufferJs = hicr::json::getObject(settingsJs, "Control Buffer");
167150
_settings.controlBuffer.capacity = hicr::json::getNumber<size_t>(controlBufferJs, "Capacity");
168151
_settings.controlBuffer.size = hicr::json::getNumber<size_t>(controlBufferJs, "Size");
169-
170-
nlohmann::json userInterfaceJs = hicr::json::getObject(settingsJs, "User Interface");
171-
_settings.userInterface.input = hicr::json::getString(userInterfaceJs, "Input");
172-
_settings.userInterface.output = hicr::json::getString(userInterfaceJs, "Output");
173-
if (userInterfaceJs.contains("Instance Id")) _settings.userInterface.instanceId = hicr::json::getNumber<HiCR::Instance::instanceId_t>(userInterfaceJs, "Instance Id");
174152
}
175153

176154
// Includes all kinds of sanity checks relevant to a deployment
177155
__INLINE__ void verify() const
178156
{
157+
// Getting rqeuest manager input and output edges
158+
const auto& requestManagerInputEdge = _requestManager->getInput();
159+
const auto& requestManagerOutputEdge = _requestManager->getOutput();
160+
179161
// Getting all partition's edges in a set
180162
std::set<std::string> partitionNameSet;
181163
for (const auto& partition : _partitions) partitionNameSet.insert(partition->getName());
@@ -239,9 +221,9 @@ class Deployment final
239221
inputSet.insert(input);
240222

241223
// Check the task that contains the user interface input does not receive any other inputs
242-
if (input == _settings.userInterface.input) userInterfaceInputPartition = partition;
243-
if (input == _settings.userInterface.output) HICR_THROW_LOGIC("Deployment specifies task '%s' with user interface output '%s' which is being used as input\n", task->getFunctionName(), input.c_str());
244-
if (input == _settings.userInterface.input && task->getInputs().size() > 1) HICR_THROW_LOGIC("Deployment specifies task '%s' with user interface input '%s' which is not the only input of that task\n", task->getFunctionName(), input.c_str());
224+
if (input == requestManagerInputEdge) userInterfaceInputPartition = partition;
225+
if (input == requestManagerOutputEdge) HICR_THROW_LOGIC("Deployment specifies task '%s' with user interface output '%s' which is being used as input\n", task->getFunctionName(), input.c_str());
226+
if (input == requestManagerInputEdge && task->getInputs().size() > 1) HICR_THROW_LOGIC("Deployment specifies task '%s' with user interface input '%s' which is not the only input of that task\n", task->getFunctionName(), input.c_str());
245227
}
246228

247229
// Make sure all tasks have at least one output
@@ -256,18 +238,18 @@ class Deployment final
256238
outputSet.insert(output);
257239

258240
// Check the task that contains the user interface input does not receive any other inputs
259-
if (output == _settings.userInterface.output) userInterfaceOutputPartition = partition;
260-
if (output == _settings.userInterface.input) HICR_THROW_LOGIC("Deployment specifies task '%s' with user interface input '%s' which is being used as output\n", task->getFunctionName(), output.c_str());
261-
if (output == _settings.userInterface.output && task->getOutputs().size() > 1) HICR_THROW_LOGIC("Deployment specifies task '%s' with user interface output '%s' which is not the only output of task\n", task->getFunctionName(), output.c_str());
241+
if (output == requestManagerOutputEdge) userInterfaceOutputPartition = partition;
242+
if (output == requestManagerInputEdge) HICR_THROW_LOGIC("Deployment specifies task '%s' with user interface input '%s' which is being used as output\n", task->getFunctionName(), output.c_str());
243+
if (output == requestManagerOutputEdge && task->getOutputs().size() > 1) HICR_THROW_LOGIC("Deployment specifies task '%s' with user interface output '%s' which is not the only output of task\n", task->getFunctionName(), output.c_str());
262244
}
263245
}
264246

265247
// Check whether all edges have consumer+producer partitions that do exist
266248
for (const auto& edge : _edges)
267249
{
268250
const auto& edgeName = edge->getName();
269-
if (edgeName != _settings.userInterface.input)
270-
if (edgeName != _settings.userInterface.output)
251+
if (edgeName != requestManagerInputEdge)
252+
if (edgeName != requestManagerOutputEdge)
271253
if (consumerPartitionMap.contains(edgeName) == false || producerPartitionMap.contains(edgeName) == false)
272254
HICR_THROW_LOGIC("Deployment specifies edge '%s' but it is either not used as input or output (or neither)\n", edge->getName().c_str());
273255

@@ -284,40 +266,40 @@ class Deployment final
284266
}
285267

286268
// Make sure all inputs are also used as outputs, as long as it is not the user interface input
287-
for (const auto& input : inputSet) if (input != _settings.userInterface.input) if (outputSet.contains(input) == false) HICR_THROW_LOGIC("Deployment input '%s' is not associated to any output\n", input.c_str());
288-
for (const auto& output : outputSet) if (output != _settings.userInterface.output) if (inputSet.contains(output) == false) HICR_THROW_LOGIC("Deployment output '%s' is not associated to any input\n", output.c_str());
269+
for (const auto& input : inputSet) if (input != requestManagerInputEdge) if (outputSet.contains(input) == false) HICR_THROW_LOGIC("Deployment input '%s' is not associated to any output\n", input.c_str());
270+
for (const auto& output : outputSet) if (output != requestManagerOutputEdge) if (inputSet.contains(output) == false) HICR_THROW_LOGIC("Deployment output '%s' is not associated to any input\n", output.c_str());
289271

290272
// Check the user interface input/output are being used
291-
if (userInterfaceInputPartition == nullptr) HICR_THROW_LOGIC("User interface input '%s' is not associated to any partition\n", _settings.userInterface.input.c_str());
292-
if (userInterfaceOutputPartition == nullptr) HICR_THROW_LOGIC("User interface output '%s' is not associated to any partition\n", _settings.userInterface.output.c_str());
273+
if (userInterfaceInputPartition == nullptr) HICR_THROW_LOGIC("User interface input '%s' is not associated to any partition\n", requestManagerInputEdge.c_str());
274+
if (userInterfaceOutputPartition == nullptr) HICR_THROW_LOGIC("User interface output '%s' is not associated to any partition\n", requestManagerOutputEdge.c_str());
293275

294276
// Make sure the partition which contains the user interface input does not contain any cross-partition inputs
295277
for (const auto& task : userInterfaceInputPartition->getTasks())
296278
for (const auto& input : task->getInputs())
297-
if (input != _settings.userInterface.input)
279+
if (input != requestManagerInputEdge)
298280
if (producerPartitionMap.at(input) != userInterfaceInputPartition->getName())
299-
HICR_THROW_LOGIC("Partition %s consumes the user interface input '%s' but also has other inter-partition inputs (e.g.,: '%s')\n", userInterfaceInputPartition->getName().c_str(), _settings.userInterface.input.c_str(), input.c_str());
281+
HICR_THROW_LOGIC("Partition %s consumes the user interface input '%s' but also has other inter-partition inputs (e.g.,: '%s')\n", userInterfaceInputPartition->getName().c_str(), requestManagerInputEdge.c_str(), input.c_str());
300282

301283
// Make sure the partition which contains the user interface output does not contain any cross-partition outputs
302284
for (const auto& task : userInterfaceOutputPartition->getTasks())
303285
for (const auto& output : task->getOutputs())
304-
if (output != _settings.userInterface.output)
286+
if (output != requestManagerOutputEdge)
305287
if (consumerPartitionMap.at(output) != userInterfaceOutputPartition->getName())
306-
HICR_THROW_LOGIC("Partition %s produces the user interface output '%s' but also has other inter-partition inputs (e.g.,: '%s')\n", userInterfaceOutputPartition->getName().c_str(), _settings.userInterface.output.c_str(), output.c_str());
288+
HICR_THROW_LOGIC("Partition %s produces the user interface output '%s' but also has other inter-partition inputs (e.g.,: '%s')\n", userInterfaceOutputPartition->getName().c_str(), requestManagerOutputEdge.c_str(), output.c_str());
307289

308290
// Setting producer partition for user interface input to be the same as the consumer
309291
for (const auto& edge : _edges)
310292
{
311293
const auto& edgeName = edge->getName();
312294

313-
if (edgeName == _settings.userInterface.input)
295+
if (edgeName == requestManagerInputEdge)
314296
{
315297
edge->setProducer(userInterfaceInputPartition->getName());
316298
edge->setConsumer(userInterfaceInputPartition->getName());
317299
edge->setPromptEdge(true);
318300
}
319301

320-
if (edgeName == _settings.userInterface.output)
302+
if (edgeName == requestManagerOutputEdge)
321303
{
322304
edge->setProducer(userInterfaceOutputPartition->getName());
323305
edge->setConsumer(userInterfaceOutputPartition->getName());
@@ -331,6 +313,7 @@ class Deployment final
331313
std::string _name;
332314
std::vector<std::shared_ptr<Partition>> _partitions;
333315
std::vector<std::shared_ptr<Edge>> _edges;
316+
std::shared_ptr<RequestManager> _requestManager;
334317
settings_t _settings;
335318

336319

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include <nlohmann_json/parser.hpp>
5+
#include <hicr/core/definitions.hpp>
6+
#include <hicr/core/instance.hpp>
7+
8+
namespace hLLM::configuration
9+
{
10+
11+
class RequestManager final
12+
{
13+
public:
14+
15+
RequestManager(const nlohmann::json js) { deserialize(js); };
16+
RequestManager(const std::string& input, const std::string& output) : _input(input), _output(output) {}
17+
~RequestManager() = default;
18+
19+
__INLINE__ void setInput(const std::string& input) { _input = input; }
20+
__INLINE__ void setOutput(const std::string& output) { _output = output; }
21+
__INLINE__ void setInstanceId(const HiCR::Instance::instanceId_t instanceId) { _instanceId = instanceId; }
22+
23+
[[nodiscard]] __INLINE__ auto getInput() const { return _input; }
24+
[[nodiscard]] __INLINE__ auto getOutput() const { return _output; }
25+
[[nodiscard]] __INLINE__ auto getInstanceId() const { return _instanceId; }
26+
27+
[[nodiscard]] __INLINE__ nlohmann::json serialize() const
28+
{
29+
nlohmann::json js;
30+
31+
js["Input"] = _input;
32+
js["Output"] = _output;
33+
js["Instance Id"] = _instanceId;
34+
35+
return js;
36+
}
37+
38+
__INLINE__ void deserialize (const nlohmann::json& js)
39+
{
40+
_input = hicr::json::getString(js, "Input");
41+
_output = hicr::json::getString(js, "Output");
42+
if (js.contains("Instance Id")) _instanceId = hicr::json::getNumber<HiCR::Instance::instanceId_t>(js, "Instance Id"); // Optional, as it is determined at runtime
43+
}
44+
45+
private:
46+
47+
std::string _input;
48+
std::string _output;
49+
HiCR::Instance::instanceId_t _instanceId;
50+
51+
}; // class RequestManager
52+
53+
} // namespace hLLM::configuration

include/hllm/engine.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ class Engine final
315315
}
316316

317317
// If I am a Request Manager, construct the role now
318-
if (_deployment.getUserInterface().instanceId == _instanceId)
318+
if (_deployment.getRequestManager()->getInstanceId() == _instanceId)
319319
{
320320
printf("[Instance %lu] I am the request manager\n", _instanceId);
321321
_requestManagerRole = std::make_shared<roles::RequestManager>(_deployment, _taskr);

include/hllm/roles/requestManager.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ class RequestManager final : public hLLM::Role
2929
) : Role(deployment, taskr)
3030
{
3131
// Name of the prompt input
32-
const auto& promptInputName = _deployment.getUserInterface().input;
33-
const auto& resultOutputName = _deployment.getUserInterface().output;
32+
const auto& promptInputName = _deployment.getRequestManager()->getInput();
33+
const auto& resultOutputName = _deployment.getRequestManager()->getOutput();
3434

3535
// Getting partition list
3636
const auto& partitions = _deployment.getPartitions();

0 commit comments

Comments
 (0)