Introduction
Philote provides client classes for connecting to and interacting with remote discipline servers. Clients handle all gRPC communication and provide a simple interface for function and gradient evaluations.
Explicit Discipline Clients
Basic Connection
#include <grpcpp/grpcpp.h>
auto channel = grpc::CreateChannel("localhost:50051",
grpc::InsecureChannelCredentials());
return 0;
}
void GetInfo()
Get the discipline info.
void GetVariableDefinitions()
Get the variable definitions from the server.
void Setup()
Setup the discipline.
Client class for calling a remote explicit discipline.
Definition explicit.h:418
void ConnectChannel(std::shared_ptr< grpc::ChannelInterface > channel)
Connects the client stub to a gRPC channel.
int main()
Definition paraboloid_client.cpp:50
Computing Functions
inputs.at("x")(0) = 5.0;
inputs.at("y")(0) = -2.0;
std::cout << "f(5, -2) = " << outputs.at("f_xy")(0) << std::endl;
Variables ComputeFunction(const Variables &inputs)
Calls the remote analysis server function evaluation via gRPC.
A class for storing continuous and discrete variables.
Definition variable.h:85
std::map< std::string, philote::Variable > Variables
Definition variable.h:404
Computing Gradients
double df_dx = gradients[{"f_xy", "x"}](0);
double df_dy = gradients[{"f_xy", "y"}](0);
std::cout << "∂f/∂x = " << df_dx << std::endl;
std::cout << "∂f/∂y = " << df_dy << std::endl;
void GetPartialDefinitions()
Get the partial definitions from the server.
Partials ComputeGradient(const Variables &inputs)
Calls the remote analysis server gradient evaluation via gRPC.
std::map< std::pair< std::string, std::string >, philote::Variable > Partials
Definition variable.h:405
Complete Workflow
Here's a complete explicit client workflow:
auto channel = grpc::CreateChannel("localhost:50051",
grpc::InsecureChannelCredentials());
for (const auto& name : var_names) {
if (meta.type() == philote::kInput) {
inputs[name](0) = 1.0;
}
}
VariableMetaData GetVariableMeta(const std::string &name)
Get the variable meta data.
std::vector< std::string > GetVariableNames()
Get the variable names.
Implicit Discipline Clients
Basic Connection
#include <grpcpp/grpcpp.h>
auto channel = grpc::CreateChannel("localhost:50051",
grpc::InsecureChannelCredentials());
return 0;
}
Client class for calling a remote implicit discipline.
Definition implicit.h:506
void ConnectChannel(std::shared_ptr< grpc::ChannelInterface > channel)
Connects the client stub to a gRPC channel.
Solving for Outputs
inputs.at("a")(0) = 1.0;
inputs.at("b")(0) = -5.0;
inputs.at("c")(0) = 6.0;
std::cout << "Solution: x = " << outputs.at("x")(0) << std::endl;
Variables SolveResiduals(const Variables &vars)
Calls the remote analysis server to solve via gRPC.
Computing Residuals
For verification or optimization, you can compute residuals directly:
vars.at("a")(0) = 1.0;
vars.at("b")(0) = -5.0;
vars.at("c")(0) = 6.0;
vars.at("x")(0) = 2.0;
std::cout << "R(x=2) = " << residuals.at("x")(0) << std::endl;
Variables ComputeResiduals(const Variables &vars)
Calls the remote analysis server residuals evaluation via gRPC.
Computing Residual Gradients
double dR_da = gradients[{"x", "a"}](0);
double dR_db = gradients[{"x", "b"}](0);
double dR_dc = gradients[{"x", "c"}](0);
double dR_dx = gradients[{"x", "x"}](0);
Partials ComputeResidualGradients(const Variables &vars)
Calls the remote analysis server gradient evaluation via gRPC.
Complete Implicit Workflow
auto channel = grpc::CreateChannel("localhost:50051",
grpc::InsecureChannelCredentials());
inputs["a"](0) = 1.0;
for (const auto& [name, var] : outputs) {
combined[name] = var;
}
Connection Management
Channel Creation
auto channel = grpc::CreateChannel("localhost:50051",
grpc::InsecureChannelCredentials());
auto creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
auto channel = grpc::CreateChannel("myserver.com:50051", creds);
Channel Options
grpc::ChannelArguments args;
args.SetMaxReceiveMessageSize(100 * 1024 * 1024);
args.SetMaxSendMessageSize(100 * 1024 * 1024);
auto channel = grpc::CreateCustomChannel("localhost:50051",
grpc::InsecureChannelCredentials(),
args);
Multiple Servers
auto aero_channel = grpc::CreateChannel("localhost:50051",
grpc::InsecureChannelCredentials());
auto struct_channel = grpc::CreateChannel("localhost:50052",
grpc::InsecureChannelCredentials());
Error Handling
Always handle potential errors:
try {
} catch (const std::exception& e) {
std::cerr << "Client error: " << e.what() << std::endl;
return 1;
}
Initialization Sequence
The client initialization must follow this order:
- ConnectChannel() - Establish gRPC connection
- GetInfo() - Retrieve discipline properties
- Setup() - Initialize the remote discipline
- GetVariableDefinitions() - Get variable metadata
- GetPartialDefinitions() - (Optional) Get gradient metadata
Important: Calling methods out of order will result in errors.
Querying Variable Information
Get All Variable Names
for (const auto& name : names) {
std::cout << "Variable: " << name << std::endl;
}
Get Variable Metadata
std::cout << "Name: " << meta.name() << std::endl;
std::cout << "Type: " << (meta.type() == philote::kInput ? "Input" : "Output")
<< std::endl;
std::cout << "Units: " << meta.units() << std::endl;
std::cout << "Shape: ";
for (int64_t dim : meta.shape()) {
std::cout << dim << " ";
}
std::cout << std::endl;
Get Partials Metadata
std::vector<philote::PartialsMetaData> partials = client.
GetPartialsMeta();
for (const auto& partial : partials) {
std::cout << "∂" << partial.name() << "/∂" << partial.subname() << std::endl;
}
std::vector< philote::PartialsMetaData > GetPartialsMeta()
Get the partials meta data.
Best Practices
- Initialize in order: Follow the required initialization sequence
- Reuse clients: Create client once and reuse for multiple evaluations
- Check connectivity: Verify channel state before operations
- Handle timeouts: Set appropriate timeout values for long-running computations
- Sequential operations: Don't call client methods concurrently
- Error handling: Wrap client calls in try-catch blocks
- Variable shapes: Always create inputs with correct shapes from metadata
Common Patterns
Repeated Evaluations
for (double x = 0.0; x < 10.0; x += 0.1) {
inputs.at("x")(0) = x;
}
Parameter Sweeps
std::vector<double> x_values = {1.0, 2.0, 3.0, 4.0, 5.0};
std::vector<double> y_values;
for (double x : x_values) {
inputs.at("x")(0) = x;
y_values.push_back(outputs.at("y")(0));
}
Limitations
- No concurrent RPCs: One RPC at a time per client
- Sequential operations: All client methods must be called sequentially
- Single connection: Each client connects to one server
- No auto-reconnect: If connection drops, create new client
See Also