Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added C++ REST API #497

Merged
merged 115 commits into from
Oct 20, 2021
Merged
Changes from 1 commit
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
c20de3d
Allowed to ground some nodes of the cag with external functions.
May 10, 2021
8f1b4ee
Added code to distinguish between dependent and independent nodes of the
May 25, 2021
1b594bf
Modeling root nodes separately.
May 28, 2021
6d72733
A script to analyze and visualize rain data
Jun 7, 2021
96f6870
Experimenting with using partition median and relative change between
Jun 14, 2021
29fa9c0
Tidying up the head node modeling code
Jun 15, 2021
5649dde
More tidying up head node modeling code.
Jun 16, 2021
6cf939d
more tyding up head node modeling code
Jun 16, 2021
05bf812
more tyding up head node modeling code
Jun 16, 2021
352d732
fixed a logical bug
Jun 16, 2021
e3a1986
Added another graph
Jun 22, 2021
e549984
The head node model that was demoed for 2021 June embed.
Jun 22, 2021
10cf87d
Updated the head node modeling code with a guard to prevent a segment…
Jun 22, 2021
3da99de
Updated the code so that:
Jun 23, 2021
dc9cbb6
Integrated head node modeling component with Causemose
Jul 30, 2021
843b7e4
Pached an old (could be obsolete) method to fix a segmentation fault …
Jul 30, 2021
39bd25f
Accumulating log likelihoods
Jul 31, 2021
15858e9
MAP Sample
Aug 2, 2021
553ec61
Fixed a place that gave a segmentation fault due to faulty logic
Aug 3, 2021
e7dcdaa
Fixed an initialization bug
Aug 3, 2021
2c84eb5
Fixed a bug
Aug 10, 2021
5c0ab70
Generating synthetic CAGs
Aug 19, 2021
b1a0e2e
Cleanup
Aug 23, 2021
c70f374
More cleaning
Aug 23, 2021
8cecf28
Created a class to perform timing
Aug 25, 2021
6a7ab55
Fixed CMakeLists.txt
Aug 25, 2021
65b0910
Changed a file name
Aug 25, 2021
dcd0f92
A basic macro profiler completed.
Aug 30, 2021
f5724d6
Added some progress messages to the timer.
Aug 30, 2021
2290f0b
Added proper error checking for opening delphi.db
Sep 1, 2021
4beb2fd
Improved the newly created delphi.db open method to accept the database
Sep 1, 2021
54b2bf7
Improved the Delphi macro timing program to accept command line options.
Sep 9, 2021
b5919a7
Removed inclusion of dbg.h in main source files.
Sep 9, 2021
9a0fa36
Fixed the help option in timer.
Sep 9, 2021
43c7700
The june embed jupytre notebook got opened and some version number go…
Sep 24, 2021
51f44b2
Seasonal curve from a Fourier series
Sep 24, 2021
efb1c08
Commented out some unused synthetic data generating methods.
Oct 7, 2021
f6fea8b
Deleted commented code related to synthetic data generation.
Oct 7, 2021
d05a596
Added a stub to export a create model json file.
Oct 9, 2021
b68f8fd
Updated the debugger.py script to test synthetic CAG generation.
Oct 10, 2021
caf8b38
Updated the seasonal_fourier.py script
Oct 10, 2021
a8b003d
Changing terminology
Oct 10, 2021
a01e097
Some refactoring
Oct 10, 2021
e2239b2
Added two scripts to perform some regression testing:
Oct 13, 2021
b783508
Added mean and standard deviation of the snapshot differences to the
Oct 13, 2021
170c5df
Added source files from branch 'delphi_modeling_1_dev'
jastier Oct 15, 2021
8ebc0b4
Added test scripts
jastier Oct 15, 2021
ce71507
Added delphi_rest_api CI tests
jastier Oct 15, 2021
e7df4c2
Moved file
jastier Oct 15, 2021
e51c8fc
added wm_test and Bash get_system_status test
jastier Oct 15, 2021
c1ba856
Commended out 'test_wm' test to debug CI failure
jastier Oct 15, 2021
a6832c6
Commented out pip installs for CI debugging
jastier Oct 15, 2021
596e905
commented out delphi_rest_api tests to debug test_wm CI issue
jastier Oct 15, 2021
156e35d
moved test_wm after the served installation
jastier Oct 15, 2021
512ab6d
added 'sudo' to failing commands
jastier Oct 15, 2021
6732c54
CI debugging
jastier Oct 15, 2021
fe4bead
Move 'test_wm' ahead of a directory change
jastier Oct 15, 2021
864d671
Added pwd output
jastier Oct 15, 2021
c480061
debug output
jastier Oct 15, 2021
78e0481
better comment visibility
jastier Oct 15, 2021
e475dc3
added output for test_wm build diretory
jastier Oct 15, 2021
aa31008
current directory output
jastier Oct 15, 2021
3eb5ea6
directory change
jastier Oct 15, 2021
5e1b926
Building WM only
jastier Oct 16, 2021
d44d441
Adding served to WM build
jastier Oct 16, 2021
c75995c
sudo commands
jastier Oct 16, 2021
ee1f33f
sudo mkdir build
jastier Oct 16, 2021
2ae3b6c
Uncommented missing file
jastier Oct 16, 2021
ce44362
Added file, commented out DelphiPython from CMakeLists.txt
jastier Oct 18, 2021
9dbbd7e
Turned on Python build
jastier Oct 18, 2021
aaadf2a
Trying another CMakeLists.txt
jastier Oct 18, 2021
786f34d
Added missing file
jastier Oct 18, 2021
00a5ae8
Building pybind11 from source
jastier Oct 18, 2021
e9b9c90
pybind11 install in ci.yml
jastier Oct 18, 2021
c9c99ae
Removed pybind11 install from CMakeLists.txt
jastier Oct 18, 2021
5c74047
cd into scripts dir
jastier Oct 18, 2021
f04ac1f
install pytest
jastier Oct 18, 2021
c7e8f56
pybind11
jastier Oct 18, 2021
4ad4380
Better directory navigation
jastier Oct 18, 2021
9b252fc
Directory navigation
jastier Oct 18, 2021
30d17a4
Directory navigation
jastier Oct 18, 2021
21aaadd
Directory navigation
jastier Oct 18, 2021
00726e3
commented out test_wm
jastier Oct 18, 2021
fa1de49
Added REST API build to CI
jastier Oct 18, 2021
feecff6
Commented out 'test_cpp_rest_api.py' test
jastier Oct 18, 2021
a8790f5
Directory navigation
jastier Oct 18, 2021
6550613
Uncommented test_wm
jastier Oct 18, 2021
c856cbe
DELPHI_DB check
jastier Oct 19, 2021
b635d24
Fully matrix exponential compatible periodic LDS.
Oct 19, 2021
cde89b8
Modifying ci.yml
adarshp Oct 19, 2021
e6a4408
Added script to test delphi_rest_api progress endpoint
jastier Oct 19, 2021
ae2b871
Removing apps/test_cpp_rest_api.py
adarshp Oct 19, 2021
2917470
Added stub code for the REST API progress function
jastier Oct 19, 2021
667c321
Fixing compilation error related to range-v3 on macOS Big Sur
adarshp Jun 3, 2021
5b9122a
Cleaned up CMakeLists.txt a bit with best practices
adarshp Oct 19, 2021
70a4ef8
Removing delphi/setup.py
adarshp Oct 19, 2021
e8c2531
Added stub code for the REST API stop_computation function
jastier Oct 19, 2021
81820b6
adding #pragma once to DatabaseHelper.cpp, autoformatting
adarshp Oct 19, 2021
8419965
Removing scripts/timer.cpp
adarshp Oct 19, 2021
40ed93d
Moving served installation to earlier in the CI workflow
adarshp Oct 19, 2021
b2053fc
Fixing typo in ci.yml
adarshp Oct 19, 2021
eda8ea7
Deleted a lot of commented code and print statements.
Oct 19, 2021
0816a15
Did some more cleaning.
Oct 19, 2021
bc098f3
trying removing sudo
adarshp Oct 19, 2021
eac9426
pulling origin/delphi_modeling_1_dev
adarshp Oct 19, 2021
851c1d6
Added a utility function for database access
jastier Oct 19, 2021
6a743dd
Fixed printf debugging
jastier Oct 19, 2021
9bdce89
started database query
jastier Oct 19, 2021
f2a1966
removing pybind_tester_driver
adarshp Oct 19, 2021
5130174
trying removing sudo
adarshp Oct 20, 2021
5484631
removing unnecessary call to mkdir
adarshp Oct 20, 2021
db3861d
fixing compilation errors
adarshp Oct 20, 2021
38be6d3
Merge branch 'dev_joseph_2_ap' of github.com:ml4ai/delphi into dev_jo…
adarshp Oct 20, 2021
1a317e3
Replaced deprecated add_stylesheet call in conf.py
jastier Oct 20, 2021
9685f1e
Merge branch 'dev_joseph_2' of github.com:ml4ai/delphi into dev_joseph_2
jastier Oct 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Modeling root nodes separately.
This is the dumbest model. Each root node predict close to the average
of the observation series.
Manujinda Wathugala committed May 28, 2021
commit 1b594bf5d86b94010252641ca555d2a54b56bab2
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -77,7 +77,7 @@ add_library(Delphi
lib/format_output.cpp
lib/database.cpp
#lib/PybindTester.hpp
)
lib/independent_nodes.cpp)

target_link_libraries(Delphi
PRIVATE ${Boost_LIBRARIES}
22 changes: 22 additions & 0 deletions lib/AnalysisGraph.hpp
Original file line number Diff line number Diff line change
@@ -243,6 +243,8 @@ class AnalysisGraph {

std::unordered_set<int> dependent_nodes = {};
std::unordered_set<int> independent_nodes = {};
std::vector<double> generated_latent_sequence;
int generated_concept;

/*
============================================================================
@@ -419,6 +421,8 @@ class AnalysisGraph {

std::vector<Eigen::MatrixXd> transition_matrix_collection;
std::vector<Eigen::VectorXd> initial_latent_state_collection;
std::vector<std::vector<double>> latent_mean_collection;
std::vector<std::vector<double>> latent_std_collection;

std::vector<Eigen::VectorXd> synthetic_latent_state_sequence;
bool synthetic_data_experiment = false;
@@ -894,6 +898,24 @@ class AnalysisGraph {

void revert_back_to_previous_state();


/*
============================================================================
Private: Modeling independent nodes (in independent_nodes.cpp)
============================================================================
*/

void generate_from_data_mean_and_std_gussian(double mean,
double std,
int num_timesteps);

void generate_independent_node_latent_sequences(int samp, int num_timesteps);

void update_independent_node_latent_state_with_generated_derivatives(
int ts, int concept_id, std::vector<double>& latent_sequence);

void update_latent_state_with_generated_derivatives(int ts);

/*
============================================================================
Private: Prediction (in prediction.cpp)
3 changes: 3 additions & 0 deletions lib/Node.hpp
Original file line number Diff line number Diff line change
@@ -9,6 +9,9 @@
class Node {
public:
std::string name = "";
double mean = 0;
double std = 1;
std::vector<double> generated_latent_sequence = {};
bool visited;
LatentVar rv;
std::string to_string() { return this->name; }
60 changes: 60 additions & 0 deletions lib/independent_nodes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Modeling independent CAG nodes

#include "AnalysisGraph.hpp"

using namespace std;

void AnalysisGraph::generate_from_data_mean_and_std_gussian(double mean,
double std,
int num_timesteps) {
this->generated_latent_sequence = vector<double>(num_timesteps);

for (int ts = 0; ts < num_timesteps; ts++) {
this->generated_latent_sequence[ts] = mean + std
* norm_dist(this->rand_num_generator);
}
}

void AnalysisGraph::generate_independent_node_latent_sequences(int samp, int num_timesteps) {
for (int v : this->independent_nodes) {
Node &n = (*this)[v];

double mean;
double std;

if (samp > -1) {
mean = this->latent_mean_collection[samp][v];
std = this->latent_std_collection[samp][v];
}
else {
mean = n.mean;
std = n.std;
}

this->generate_from_data_mean_and_std_gussian(mean,
std,
num_timesteps);
n.generated_latent_sequence.clear();
n.generated_latent_sequence = this->generated_latent_sequence;
}
}

void AnalysisGraph::
update_independent_node_latent_state_with_generated_derivatives(
int ts, int concept_id, vector<double>& latent_sequence) {
if (concept_id > -1 && ts < latent_sequence.size() - 1) {
this->current_latent_state[2 * concept_id + 1] = latent_sequence[ts + 1]
- latent_sequence[ts];

if (ts == 0) {
this->current_latent_state[2 * concept_id] = latent_sequence[0];
}
}
}

void AnalysisGraph::update_latent_state_with_generated_derivatives(int ts) {
for (int v : this->independent_nodes) {
Node &n = (*this)[v];
this->update_independent_node_latent_state_with_generated_derivatives(ts, v, n.generated_latent_sequence);
}
}
19 changes: 19 additions & 0 deletions lib/parameter_initialization.cpp
Original file line number Diff line number Diff line change
@@ -34,13 +34,18 @@ void AnalysisGraph::initialize_parameters(int res,
this->set_transition_matrix_from_betas();
this->derivative_prior_variance = 0.1;
this->set_default_initial_state(initial_derivative);
this->generate_independent_node_latent_sequences(-1, this->n_timesteps);
this->set_log_likelihood();

this->transition_matrix_collection.clear();
this->initial_latent_state_collection.clear();
this->latent_mean_collection.clear();
this->latent_std_collection.clear();

this->transition_matrix_collection = vector<Eigen::MatrixXd>(this->res);
this->initial_latent_state_collection = vector<Eigen::VectorXd>(this->res);
this->latent_mean_collection = vector<vector<double>>(this->res);
this->latent_std_collection = vector<vector<double>>(this->res);
}

void AnalysisGraph::init_betas_to(InitialBeta ib) {
@@ -216,6 +221,20 @@ void AnalysisGraph::set_indicator_means_and_standard_deviations() {
// To avoid division by zero error later on
ind.set_mean(0.0001);
}

// Set mean and standard deviation of the concept based on the mean
// and the standard deviation of the first indicator attached to it.
if (i == 0) {
n.mean = delphi::utils::mean(mean_sequence);

if (mean_sequence.size() > 1) {
n.std = delphi::utils::standard_deviation(n.mean, mean_sequence)
/ (n.indicators[0].mean * n.indicators[0].mean);
}

// Scale the mean to latent space
n.mean /= n.indicators[0].mean;
}
}
}
}
24 changes: 15 additions & 9 deletions lib/prediction.cpp
Original file line number Diff line number Diff line change
@@ -60,29 +60,34 @@ void AnalysisGraph::generate_latent_state_sequences(
// length Δt
A = this->transition_matrix_collection[samp];

this->generate_independent_node_latent_sequences(samp, initial_prediction_step
+ this->pred_timesteps);

// Evolving the system till the initial_prediction_step
this->predicted_latent_state_sequences[samp][0] =
this->initial_latent_state_collection[samp];
this->current_latent_state = this->initial_latent_state_collection[samp];

for (int ts = 0; ts < initial_prediction_step; ts++) {
this->update_latent_state_with_generated_derivatives(ts);

// Set derivatives for frozen nodes
for (const auto & [ v, deriv_func ] : this->external_concepts) {
const Indicator& ind = this->graph[v].indicators[0];
this->predicted_latent_state_sequences[samp][0][2 * v + 1] =
deriv_func(ts, ind.mean);
this->current_latent_state[2 * v + 1] = deriv_func(ts, ind.mean);
}

this->predicted_latent_state_sequences[samp][0] =
A * this->predicted_latent_state_sequences[samp][0];
this->current_latent_state = A * this->current_latent_state;
}

this->update_latent_state_with_generated_derivatives(initial_prediction_step);

// Set derivatives for frozen nodes
for (const auto & [ v, deriv_func ] : this->external_concepts) {
const Indicator& ind = this->graph[v].indicators[0];
this->predicted_latent_state_sequences[samp][0][2 * v + 1] =
this->current_latent_state[2 * v + 1] =
deriv_func(initial_prediction_step, ind.mean);
}

this->predicted_latent_state_sequences[samp][0] = this->current_latent_state;
}

// Clear out perpetual constraints residual from previous sample
@@ -122,8 +127,9 @@ void AnalysisGraph::generate_latent_state_sequences(
// The actual line of code represents,
// s_t = e^{Ac * Δt } * s_{t-1}
// When discrete : s_t = Ad * s_{t-1}
this->predicted_latent_state_sequences[samp][ts] =
A * this->predicted_latent_state_sequences[samp][ts - 1];
this->current_latent_state = A * this->predicted_latent_state_sequences[samp][ts - 1];
this->update_latent_state_with_generated_derivatives(ts);
this->predicted_latent_state_sequences[samp][ts] = this->current_latent_state;

// Set derivatives for frozen nodes
for (const auto & [ v, deriv_func ] : this->external_concepts) {
72 changes: 56 additions & 16 deletions lib/sampling.cpp
Original file line number Diff line number Diff line change
@@ -134,13 +134,21 @@ void AnalysisGraph::set_log_likelihood() {
}
}
this->current_latent_state = this->s0;
set_log_likelihood_helper(0);

// this->update_independent_node_latent_state_with_generated_derivatives(
// 0, this->generated_concept, this->generated_latent_sequence);
this->update_latent_state_with_generated_derivatives(0);

this->set_log_likelihood_helper(0);

for (int ts = 1; ts < this->n_timesteps; ts++) {
this->current_latent_state =
this->e_A_ts[this->observation_timestep_gaps[ts]]
* this->current_latent_state;
set_log_likelihood_helper(ts);
// this->update_independent_node_latent_state_with_generated_derivatives(
// ts, this->generated_concept, this->generated_latent_sequence);
this->update_latent_state_with_generated_derivatives(ts);
this->set_log_likelihood_helper(ts);
}
} else {
// Discretized version
@@ -154,6 +162,9 @@ void AnalysisGraph::set_log_likelihood() {
this->current_latent_state[2 * v + 1] = deriv_func(ts, ind.mean);
}

// this->update_independent_node_latent_state_with_generated_derivatives(
// ts, this->generated_concept, this->generated_latent_sequence);
this->update_latent_state_with_generated_derivatives(ts);
set_log_likelihood_helper(ts);
this->current_latent_state = this->A_original * this->current_latent_state;
}
@@ -176,13 +187,21 @@ void AnalysisGraph::sample_from_posterior() {

if (acceptance_probability < this->uni_dist(this->rand_num_generator)) {
// Reject the sample
this->revert_back_to_previous_state();
if (this->generated_concept == -1) {
this->revert_back_to_previous_state();
}
else {
Node &n = (*this)[this->generated_concept];
n.mean = delphi::utils::mean(this->generated_latent_sequence);
n.std = delphi::utils::standard_deviation(n.mean, this->generated_latent_sequence);
}
}
}

void AnalysisGraph::sample_from_proposal() {
// Flip a coin and decide whether to perturb a θ or a derivative
this->coin_flip = this->uni_dist(this->rand_num_generator);
this->generated_concept = -1;

if (this->coin_flip < this->coin_flip_thresh) {
// Randomly pick an edge ≡ θ
@@ -202,11 +221,21 @@ void AnalysisGraph::sample_from_proposal() {
this->update_transition_matrix_cells(e[0]);
}
else {
// Randomly select a concept to change the derivative
this->changed_derivative =
2 * this->concept_sample_pool[this->uni_disc_dist(this->rand_num_generator)] + 1;
this->previous_derivative = this->s0[this->changed_derivative];
this->s0[this->changed_derivative] += this->norm_dist(this->rand_num_generator);
// Randomly select a concept
int concept = this->concept_sample_pool[this->uni_disc_dist(this->rand_num_generator)];
this->changed_derivative = 2 * concept + 1;

if (this->independent_nodes.find(concept) != this->independent_nodes.end()) {
this->generated_concept = concept;
Node &n = (*this)[this->generated_concept];
this->generate_from_data_mean_and_std_gussian(n.mean, n.std, this->n_timesteps);
}
else {
// to change the derivative
this->previous_derivative = this->s0[this->changed_derivative];
this->s0[this->changed_derivative] +=
this->norm_dist(this->rand_num_generator);
}
}
}

@@ -247,14 +276,25 @@ double AnalysisGraph::calculate_delta_log_prior() {
kde.logpdf(this->previous_theta.second);
}
else {
// A derivative has been sampled
// We assume the prior for derivative is N(0, 0.1)
// We have to return: log( p(ẋ_new )) - log( p( ẋ_old ))
// After some mathematical simplifications we can derive
// (ẋ_old - ẋ_new)(ẋ_old + ẋ_new) / 2σ²
return (this->previous_derivative - this->s0[this->changed_derivative])
* (this->previous_derivative + this->s0[this->changed_derivative])
/ (2 * this->derivative_prior_variance);
if (this->generated_concept == -1) {
// A derivative has been sampled
// We assume the prior for derivative is N(0, 0.1)
// We have to return: log( p(ẋ_new )) - log( p( ẋ_old ))
// After some mathematical simplifications we can derive
// (ẋ_old - ẋ_new)(ẋ_old + ẋ_new) / 2σ²
return (this->previous_derivative - this->s0[this->changed_derivative]) *
(this->previous_derivative + this->s0[this->changed_derivative]) /
(2 * this->derivative_prior_variance);
}
else {
// A derivative sequence for an independent node has been generated
// When latent state at ts = 0 is 1, it makes the observation 0 the
// highest probable value.
// The standard deviation of ts = 0 latent state is set to 0.01
return (1 - this->generated_latent_sequence[0]) *
(1 + this->generated_latent_sequence[0]) /
(2 * 0.01);
}
}
}

11 changes: 11 additions & 0 deletions lib/train_model.cpp
Original file line number Diff line number Diff line change
@@ -86,6 +86,8 @@ void AnalysisGraph::run_train_model(int res,
this->sample_from_posterior();
}

int num_verts = this->num_vertices();

cout << "\nSampling " << this->res << " samples from posterior..." << endl;
for (int i : trange(this->res)) {
this->sample_from_posterior();
@@ -95,6 +97,15 @@ void AnalysisGraph::run_train_model(int res,
for (auto e : this->edges()) {
this->graph[e].sampled_thetas.push_back(this->graph[e].theta);
}

this->latent_mean_collection[i] = vector<double>(num_verts);
this->latent_std_collection[i] = vector<double>(num_verts);

for (int v : this->node_indices()) {
Node &n = (*this)[v];
this->latent_mean_collection[i][v] = n.mean;
this->latent_std_collection[i][v] = n.std;
}
}

this->trained = true;
7 changes: 4 additions & 3 deletions scripts/modeling_efforts.py
Original file line number Diff line number Diff line change
@@ -86,8 +86,9 @@ def draw_CAG(G, file_name):
use_continuous=False,
train_start_timestep=0,
train_timesteps=48,
ext_concepts={'rain': get_rain_derivative})
#ext_concepts={'test': lambda x, s : x*s })
#ext_concepts={'rain': get_rain_derivative}
#ext_concepts={'test': lambda x, s : x*s }
)

# try:
G.generate_prediction(49, 24)
@@ -104,4 +105,4 @@ def draw_CAG(G, file_name):
print(pred_range[1:])

dp.delphi_plotter(model_state, num_bins=400, rotation=45,
out_dir='plots', file_name_prefix='')
out_dir='plots', file_name_prefix='', save_csv=True)