24#include "neml2/csrc/eager/Model.h"
25#include "neml2/csrc/eager/load_model.h"
26#include "neml2/csrc/dispatchers/factory.h"
27#include "neml2/csrc/dispatchers/DispatchedModel.h"
28#include "neml2/csrc/dispatchers/MPISimpleScheduler.h"
52 virtual const std::vector<std::string> &
input_names()
const = 0;
63 virtual std::map<std::string, at::Tensor>
64 value(
const std::map<std::string, at::Tensor> & inputs)
const = 0;
66 virtual std::pair<std::map<std::string, at::Tensor>, neml2::aoti::VariablePairJacobian>
67 jacobian(
const std::map<std::string, at::Tensor> & inputs)
const = 0;
69 virtual std::pair<std::map<std::string, at::Tensor>, neml2::aoti::VariablePairJacobian>
72 virtual void set_parameter(
const std::string & name,
const at::Tensor & value) = 0;
76 virtual at::Device
device()
const = 0;
87 const std::string & model_name,
89 const std::vector<std::string> & load)
90 :
_m(input_file, model_name,
device, load)
94 const std::vector<std::string> &
input_names()
const override {
return _m.input_names(); }
95 const std::vector<std::string> &
output_names()
const override {
return _m.output_names(); }
98 return _m.input_base_shapes();
102 return _m.output_base_shapes();
106 return _m.parameter_base_shapes();
109 std::pair<std::map<std::string, at::Tensor>, neml2::aoti::VariablePairJacobian>
110 jacobian(
const std::map<std::string, at::Tensor> & inputs)
const override
112 return _m.jacobian(inputs);
114 std::pair<std::map<std::string, at::Tensor>, neml2::aoti::VariablePairJacobian>
117 return _m.param_jacobian(inputs);
119 void set_parameter(
const std::string & name,
const at::Tensor & value)
override
121 _m.set_parameter(name, value);
123 std::map<std::string, at::Tensor>
124 value(
const std::map<std::string, at::Tensor> & inputs)
const override
126 return _m.forward(inputs);
128 at::Device
device()
const override {
return _m.device(); }
131 neml2::eager::Model
_m;
151 const std::string & model_name,
152 const std::vector<std::string> & devices,
153 const std::vector<std::size_t> & batch_sizes,
155 :
_m(
load(input, model_name, devices, batch_sizes, comm))
159 const std::vector<std::string> &
input_names()
const override {
return _m.input_names(); }
160 const std::vector<std::string> &
output_names()
const override {
return _m.output_names(); }
163 return _m.input_base_shapes();
167 return _m.output_base_shapes();
171 return _m.parameter_base_shapes();
174 std::pair<std::map<std::string, at::Tensor>, neml2::aoti::VariablePairJacobian>
175 jacobian(
const std::map<std::string, at::Tensor> & inputs)
const override
177 return _m.jacobian(inputs);
179 std::pair<std::map<std::string, at::Tensor>, neml2::aoti::VariablePairJacobian>
182 return _m.param_jacobian(inputs);
184 void set_parameter(
const std::string & name,
const at::Tensor & value)
override
186 _m.set_parameter(name, value);
188 std::map<std::string, at::Tensor>
189 value(
const std::map<std::string, at::Tensor> & inputs)
const override
191 return _m.forward(inputs);
193 at::Device
device()
const override {
return _m.device(); }
206 static neml2::aoti::DispatchedModel
load(
const std::string & input,
207 const std::string & model_name,
208 const std::vector<std::string> & devices,
209 const std::vector<std::size_t> & batch_sizes,
212 neml2::aoti::MPISimpleScheduler::Config config;
213 config.devices = devices;
214 config.batch_sizes = batch_sizes;
216 auto scheduler = std::make_shared<neml2::aoti::MPISimpleScheduler>(config);
218 const std::filesystem::path path(input);
219 if (std::filesystem::is_directory(path))
220 return neml2::aoti::DispatchedModel(path, scheduler);
221 if (path.filename() ==
"metadata.json")
222 return neml2::aoti::DispatchedModel(path.parent_path(), scheduler);
223 return neml2::aoti::load_model(input, model_name, scheduler);
226 neml2::aoti::DispatchedModel
_m;
247inline std::unique_ptr<NEML2ModelHandle>
249 const std::string & input,
250 const std::string & model,
251 const std::vector<std::string> & devices,
252 const std::vector<std::size_t> & batch_sizes,
254 const std::vector<std::string> & load)
257 return std::make_unique<EagerModelHandle>(input, model, at::Device(devices.at(0)), load);
258 return std::make_unique<AOTIModelHandle>(input, model, devices, batch_sizes, comm);
std::unique_ptr< NEML2ModelHandle > makeNEML2ModelHandle(bool eager, const std::string &input, const std::string &model, const std::vector< std::string > &devices, const std::vector< std::size_t > &batch_sizes, const void *comm, const std::vector< std::string > &load)
Construct a NEML2 model handle for the requested runtime.
Handle wrapping the cpp-aoti runtime: a neml2::aoti::DispatchedModel backed by the self-describing ar...
AOTIModelHandle(const std::string &input, const std::string &model_name, const std::vector< std::string > &devices, const std::vector< std::size_t > &batch_sizes, const void *comm)
std::pair< std::map< std::string, at::Tensor >, neml2::aoti::VariablePairJacobian > param_jacobian(const std::map< std::string, at::Tensor > &inputs) const override
Evaluate the model and its parameter Jacobian (d output / d parameter).
const std::vector< std::string > & output_names() const override
std::pair< std::map< std::string, at::Tensor >, neml2::aoti::VariablePairJacobian > jacobian(const std::map< std::string, at::Tensor > &inputs) const override
Evaluate the model and its full input Jacobian.
const std::vector< std::vector< int64_t > > & output_base_shapes() const override
at::Device device() const override
The compute device this rank's workload runs on (for cpp-aoti, the scheduler-assigned device).
static neml2::aoti::DispatchedModel load(const std::string &input, const std::string &model_name, const std::vector< std::string > &devices, const std::vector< std::size_t > &batch_sizes, const void *comm)
Build the MPI scheduler (round-robin device list over the node's ranks) and load the dispatched aoti ...
const std::map< std::string, std::vector< int64_t > > & parameter_base_shapes() const override
void set_parameter(const std::string &name, const at::Tensor &value) override
Replace a (runtime-flexible) model parameter's value.
neml2::aoti::DispatchedModel _m
const std::vector< std::string > & input_names() const override
const std::vector< std::vector< int64_t > > & input_base_shapes() const override
std::map< std::string, at::Tensor > value(const std::map< std::string, at::Tensor > &inputs) const override
Handle wrapping the cpp-eager runtime (embeds CPython; loads from a source .i).
at::Device device() const override
The compute device this rank's workload runs on (for cpp-aoti, the scheduler-assigned device).
const std::map< std::string, std::vector< int64_t > > & parameter_base_shapes() const override
const std::vector< std::string > & input_names() const override
const std::vector< std::string > & output_names() const override
const std::vector< std::vector< int64_t > > & input_base_shapes() const override
std::map< std::string, at::Tensor > value(const std::map< std::string, at::Tensor > &inputs) const override
EagerModelHandle(const std::string &input_file, const std::string &model_name, const at::Device &device, const std::vector< std::string > &load)
std::pair< std::map< std::string, at::Tensor >, neml2::aoti::VariablePairJacobian > param_jacobian(const std::map< std::string, at::Tensor > &inputs) const override
Evaluate the model and its parameter Jacobian (d output / d parameter).
const std::vector< std::vector< int64_t > > & output_base_shapes() const override
std::pair< std::map< std::string, at::Tensor >, neml2::aoti::VariablePairJacobian > jacobian(const std::map< std::string, at::Tensor > &inputs) const override
Evaluate the model and its full input Jacobian.
void set_parameter(const std::string &name, const at::Tensor &value) override
Replace a (runtime-flexible) model parameter's value.
Runtime-agnostic handle over a NEML2 v3 model.
virtual ~NEML2ModelHandle()=default
virtual const std::vector< std::string > & input_names() const =0
virtual std::pair< std::map< std::string, at::Tensor >, neml2::aoti::VariablePairJacobian > jacobian(const std::map< std::string, at::Tensor > &inputs) const =0
Evaluate the model and its full input Jacobian.
virtual at::Device device() const =0
The compute device this rank's workload runs on (for cpp-aoti, the scheduler-assigned device).
virtual const std::vector< std::vector< int64_t > > & output_base_shapes() const =0
virtual void set_parameter(const std::string &name, const at::Tensor &value)=0
Replace a (runtime-flexible) model parameter's value.
virtual std::pair< std::map< std::string, at::Tensor >, neml2::aoti::VariablePairJacobian > param_jacobian(const std::map< std::string, at::Tensor > &inputs) const =0
Evaluate the model and its parameter Jacobian (d output / d parameter).
virtual std::map< std::string, at::Tensor > value(const std::map< std::string, at::Tensor > &inputs) const =0
virtual const std::map< std::string, std::vector< int64_t > > & parameter_base_shapes() const =0
virtual const std::vector< std::vector< int64_t > > & input_base_shapes() const =0
virtual const std::vector< std::string > & output_names() const =0