33#include <disciplines.grpc.pb.h>
42 class ImplicitDiscipline;
84 grpc::ServerReaderWriter<::
philote::Array,
95 grpc::ServerReaderWriter<::
philote::Array,
106 grpc::ServerReaderWriter<::
philote::Array,
110 template<typename StreamType>
113 template<typename StreamType>
116 template<typename StreamType>
121 grpc::ServerReaderWriterInterface<::
philote::Array,
127 grpc::ServerReaderWriterInterface<::philote::Array,
128 ::philote::Array> *stream) {
133 grpc::ServerReaderWriterInterface<::philote::Array,
134 ::philote::Array> *stream) {
140 std::shared_ptr<philote::ImplicitDiscipline> implementation_;
519 void ConnectChannel(std::shared_ptr<grpc::ChannelInterface> channel);
556 void SetStub(std::unique_ptr<ImplicitService::StubInterface> stub)
558 stub_ = std::move(stub);
563 std::unique_ptr<ImplicitService::StubInterface> stub_;
568#include <unordered_map>
570template<
typename StreamType>
573 if (!implementation_)
575 return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION,
"Discipline implementation not linked");
580 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
"Stream is null");
584 if (context && context->IsCancelled())
586 return grpc::Status(grpc::StatusCode::CANCELLED,
"Request cancelled before start");
589 philote::Array array;
596 return grpc::Status(grpc::StatusCode::INTERNAL,
"Failed to cast implementation to Discipline");
599 for (
const auto &var : discipline->var_meta())
601 std::string name = var.name();
602 if (var.type() == kInput)
604 if (var.type() == kOutput)
606 outputs[var.name()] =
Variable(var);
607 residuals[var.name()] =
Variable(var);
612 std::unordered_map<std::string, const VariableMetaData*> var_lookup;
613 for (
const auto &var : discipline->var_meta())
615 var_lookup[var.name()] = &var;
618 while (stream->Read(&array))
621 const std::string &name = array.name();
624 auto var_it = var_lookup.find(name);
625 if (var_it == var_lookup.end())
627 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
"Variable not found: " + name);
629 const VariableMetaData* var = var_it->second;
632 if (array.type() != var->type())
634 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
635 "Type mismatch for variable " + name +
": expected " +
636 std::to_string(var->type()) +
" but received " + std::to_string(array.type()));
640 if (var->type() == VariableType::kInput)
644 inputs[name].AssignChunk(array);
646 catch (
const std::exception &e)
648 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
649 "Failed to assign chunk for input " + name +
": " + e.what());
652 else if (var->type() == VariableType::kOutput)
656 outputs[name].AssignChunk(array);
658 catch (
const std::exception &e)
660 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
661 "Failed to assign chunk for output " + name +
": " + e.what());
666 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
667 "Invalid variable type received for variable: " + name);
672 if (context && context->IsCancelled())
674 return grpc::Status(grpc::StatusCode::CANCELLED,
"Request cancelled before computation");
678 discipline->SetContext(context);
683 implementation_->ComputeResiduals(inputs, outputs, residuals);
685 catch (
const std::exception &e)
687 discipline->ClearContext();
688 return grpc::Status(grpc::StatusCode::INTERNAL,
689 "Failed to compute residuals: " + std::string(e.what()));
693 discipline->ClearContext();
696 if (context && context->IsCancelled())
698 return grpc::Status(grpc::StatusCode::CANCELLED,
"Request cancelled before sending results");
702 for (
const auto &res : residuals)
704 const std::string &name = res.first;
707 res.second.Send(name,
"", stream, discipline->stream_opts().num_double(), context);
709 catch (
const std::exception &e)
711 return grpc::Status(grpc::StatusCode::INTERNAL,
712 "Failed to send residual " + name +
": " + e.what());
716 return grpc::Status::OK;
719template<
typename StreamType>
722 if (!implementation_)
724 return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION,
"Discipline implementation not linked");
729 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
"Stream is null");
733 if (context && context->IsCancelled())
735 return grpc::Status(grpc::StatusCode::CANCELLED,
"Request cancelled before start");
738 philote::Array array;
745 return grpc::Status(grpc::StatusCode::INTERNAL,
"Failed to cast implementation to Discipline");
748 for (
const auto &var : discipline->var_meta())
750 std::string name = var.name();
751 if (var.type() == kInput)
756 std::unordered_map<std::string, const VariableMetaData*> var_lookup;
757 for (
const auto &var : discipline->var_meta())
759 var_lookup[var.name()] = &var;
762 while (stream->Read(&array))
765 const std::string &name = array.name();
768 auto var_it = var_lookup.find(name);
769 if (var_it == var_lookup.end())
771 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
"Variable not found: " + name);
773 const VariableMetaData* var = var_it->second;
776 if (var->type() == VariableType::kInput)
780 inputs[name].AssignChunk(array);
782 catch (
const std::exception &e)
784 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
785 "Failed to assign chunk for input " + name +
": " + e.what());
790 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
791 "Expected input variable but received different type for: " + name);
797 for (
const VariableMetaData &var : discipline->var_meta())
799 if (var.type() == kOutput)
800 outputs[var.name()] =
Variable(var);
804 if (context && context->IsCancelled())
806 return grpc::Status(grpc::StatusCode::CANCELLED,
"Request cancelled before computation");
810 discipline->SetContext(context);
815 implementation_->SolveResiduals(inputs, outputs);
817 catch (
const std::exception &e)
819 discipline->ClearContext();
820 return grpc::Status(grpc::StatusCode::INTERNAL,
821 "Failed to solve residuals: " + std::string(e.what()));
825 discipline->ClearContext();
828 if (context && context->IsCancelled())
830 return grpc::Status(grpc::StatusCode::CANCELLED,
"Request cancelled before sending results");
834 for (
const auto &var : outputs)
836 const std::string &name = var.first;
839 var.second.Send(name,
"", stream, discipline->stream_opts().num_double(), context);
841 catch (
const std::exception &e)
843 return grpc::Status(grpc::StatusCode::INTERNAL,
844 "Failed to send output " + name +
": " + e.what());
848 return grpc::Status::OK;
851template<
typename StreamType>
854 if (!implementation_)
856 return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION,
"Discipline implementation not linked");
861 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
"Stream is null");
865 if (context && context->IsCancelled())
867 return grpc::Status(grpc::StatusCode::CANCELLED,
"Request cancelled before start");
870 philote::Array array;
877 return grpc::Status(grpc::StatusCode::INTERNAL,
"Failed to cast implementation to Discipline");
880 for (
const auto &var : discipline->var_meta())
882 const std::string &name = var.name();
883 if (var.type() == kInput)
885 if (var.type() == kOutput)
890 std::unordered_map<std::string, const VariableMetaData*> var_lookup;
891 for (
const auto &var : discipline->var_meta())
893 var_lookup[var.name()] = &var;
896 while (stream->Read(&array))
899 const std::string &name = array.name();
902 auto var_it = var_lookup.find(name);
903 if (var_it == var_lookup.end())
905 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
"Variable not found: " + name);
907 const VariableMetaData* var = var_it->second;
910 if (array.type() != var->type())
912 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
913 "Type mismatch for variable " + name +
": expected " +
914 std::to_string(var->type()) +
" but received " + std::to_string(array.type()));
918 if (var->type() == VariableType::kInput)
922 inputs[name].AssignChunk(array);
924 catch (
const std::exception &e)
926 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
927 "Failed to assign chunk for input " + name +
": " + e.what());
930 else if (var->type() == VariableType::kOutput)
934 outputs[name].AssignChunk(array);
936 catch (
const std::exception &e)
938 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
939 "Failed to assign chunk for output " + name +
": " + e.what());
944 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
945 "Invalid variable type received for variable: " + name);
951 for (
const PartialsMetaData &par : discipline->partials_meta())
953 std::vector<size_t> shape;
954 for (
const int64_t &dim : par.shape())
955 shape.push_back(dim);
957 partials[std::make_pair(par.name(), par.subname())] =
Variable(kOutput, shape);
961 if (context && context->IsCancelled())
963 return grpc::Status(grpc::StatusCode::CANCELLED,
"Request cancelled before computation");
967 discipline->SetContext(context);
972 implementation_->ComputeResidualGradients(inputs, outputs, partials);
974 catch (
const std::exception &e)
976 discipline->ClearContext();
977 return grpc::Status(grpc::StatusCode::INTERNAL,
978 "Failed to compute residual gradients: " + std::string(e.what()));
982 discipline->ClearContext();
985 if (context && context->IsCancelled())
987 return grpc::Status(grpc::StatusCode::CANCELLED,
"Request cancelled before sending results");
991 for (
const auto &par : partials)
993 const std::string &name = par.first.first;
994 const std::string &subname = par.first.second;
997 par.second.Send(name, subname, stream, discipline->stream_opts().num_double(), context);
999 catch (
const std::exception &e)
1001 return grpc::Status(grpc::StatusCode::INTERNAL,
1002 "Failed to send partial " + name +
"/" + subname +
": " + e.what());
1006 return grpc::Status::OK;
Client class for interacting with a discipline server.
Definition discipline_client.h:55
Base class for all analysis discipline servers.
Definition discipline_server.h:57
Definition of the discipline base class.
Definition discipline.h:62
Client class for calling a remote implicit discipline.
Definition implicit.h:506
ImplicitClient()=default
Constructor.
~ImplicitClient() noexcept=default
Destructor.
Implicit discipline class.
Definition implicit.h:291
void DeclarePartials(const std::string &f, const std::string &x)
Declare a (set of) partial(s) for the discipline.
~ImplicitDiscipline() noexcept
Destroy the Implicit Discipline object.
virtual void SolveResiduals(const philote::Variables &inputs, philote::Variables &outputs)
Solves the residuals to obtain the outputs for the discipline.
virtual void ComputeResidualGradients(const philote::Variables &inputs, const philote::Variables &outputs, Partials &partials)
Computes the gradients of the residuals evaluation for the discipline.
virtual void ComputeResiduals(const philote::Variables &inputs, const philote::Variables &outputs, philote::Variables &residuals)
Computes the residual for the discipline.
void RegisterServices(grpc::ServerBuilder &builder)
Registers all services with a gRPC channel.
ImplicitDiscipline()
Construct a new Implicit Discipline object.
Implicit server class.
Definition implicit.h:54
grpc::Status SolveResidualsImpl(grpc::ServerContext *context, StreamType *stream)
Definition implicit.h:720
grpc::Status ComputeResidualsImpl(grpc::ServerContext *context, StreamType *stream)
Definition implicit.h:571
grpc::Status ComputeResidualsForTesting(grpc::ServerContext *context, grpc::ServerReaderWriterInterface<::philote::Array, ::philote::Array > *stream)
Definition implicit.h:120
grpc::Status ComputeResidualGradientsForTesting(grpc::ServerContext *context, grpc::ServerReaderWriterInterface<::philote::Array, ::philote::Array > *stream)
Definition implicit.h:132
grpc::Status SolveResiduals(grpc::ServerContext *context, grpc::ServerReaderWriter<::philote::Array, ::philote::Array > *stream)
RPC that computes the residual evaluation.
grpc::Status ComputeResidualGradients(grpc::ServerContext *context, grpc::ServerReaderWriter<::philote::Array, ::philote::Array > *stream)
RPC that computes the residual evaluation.
ImplicitServer()=default
Constructor.
grpc::Status SolveResidualsForTesting(grpc::ServerContext *context, grpc::ServerReaderWriterInterface<::philote::Array, ::philote::Array > *stream)
Definition implicit.h:126
void UnlinkPointers()
Dereferences all pointers.
void LinkPointers(std::shared_ptr< philote::ImplicitDiscipline > implementation)
Links the explicit server to the discipline server and explicit discipline via pointers.
grpc::Status ComputeResiduals(grpc::ServerContext *context, grpc::ServerReaderWriter<::philote::Array, ::philote::Array > *stream)
RPC that computes the residual evaluation.
~ImplicitServer() noexcept
Destructor.
grpc::Status ComputeResidualGradientsImpl(grpc::ServerContext *context, StreamType *stream)
Definition implicit.h:852
A class for storing continuous and discrete variables.
Definition variable.h:85
Definition discipline.h:43
std::map< std::string, philote::Variable > Variables
Definition variable.h:404
std::map< std::pair< std::string, std::string >, philote::Variable > Partials
Definition variable.h:405