Deb Roclinn commited on
Commit
9c774f1
1 Parent(s): e81396d

Added this webserver except it works

Browse files
Files changed (3) hide show
  1. main.py +2 -2
  2. server.cpp +166 -0
  3. threadpool.h +145 -0
main.py CHANGED
@@ -117,7 +117,7 @@ if __name__ == '__main__':
117
  trainer.test(test_loader)
118
 
119
  if opt.save_mesh:
120
- trainer.save_mesh(resolution=256)
121
 
122
  else:
123
 
@@ -157,4 +157,4 @@ if __name__ == '__main__':
157
  trainer.test(test_loader)
158
 
159
  if opt.save_mesh:
160
- trainer.save_mesh(resolution=256)
 
117
  trainer.test(test_loader)
118
 
119
  if opt.save_mesh:
120
+ trainer.save_mesh(resolution=32)
121
 
122
  else:
123
 
 
157
  trainer.test(test_loader)
158
 
159
  if opt.save_mesh:
160
+ trainer.save_mesh(resolution=32)
server.cpp ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <cstdio>
2
+ #include <iostream>
3
+ #include <algorithm>
4
+ #include <memory>
5
+ #include <string>
6
+ #include <thread>
7
+ #include <array>
8
+ #include <queue>
9
+ #include <mutex>
10
+ #include <vector>
11
+ #include <filesystem>
12
+ #include <sstream>
13
+ #define CROW_MAIN
14
+ #include <crow.h>
15
+ #include <ranges>
16
+ #include "threadpool.h"
17
+ using std::string;
18
+ using std::mutex;
19
+ using std::lock_guard;
20
+ using std::make_shared;
21
+ using std::queue;
22
+ using std::vector;
23
+ namespace fs = std::filesystem;
24
+ namespace rv = std::ranges::views;
25
+ static inline string exec(const char* cmd) {
26
+ std::array<char, 128> buffer;
27
+ std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
28
+ string result;
29
+ if (!pipe)
30
+ return "Command failed";
31
+ else {
32
+ while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
33
+ result += buffer.data();
34
+ }
35
+ return result;
36
+ }
37
+
38
+ constexpr auto reify(const std::ranges::range auto& r){ return vector(r.begin(), r.end()); }
39
+
40
+ constexpr string strip(const string& s){ return s; }
41
+
42
+ constexpr string strip(string s, char ch){
43
+ s.erase(std::remove_if(s.begin(), s.end(), [=](char c){ return c == ch; }), s.end());
44
+ return s;
45
+ }
46
+
47
+ constexpr string strip(string s, char ch, auto... chs){
48
+ return strip(strip(s, ch), chs...);
49
+ }
50
+
51
+ constexpr vector<string> splitOn(const string& s, const string& delim){
52
+ vector<string> ret;
53
+ long long int start = 0;
54
+ for(size_t dp = s.find_first_of(delim, 0); start >= 0
55
+ ; start = (dp == std::string::npos) ? -1 : dp + 1, dp = s.find_first_of(delim, start))
56
+ if(auto n = s.substr(start, dp - start); !n.empty())
57
+ ret.emplace_back(n);
58
+ return ret;
59
+ }
60
+
61
+ static inline string reset = "rm -rf trial/checkpoints/*";
62
+
63
+ static inline string train(const string& prompt){
64
+ return string("python main.py --cuda_ray --save_mesh --text \"") + strip(prompt, '\'', '\"') + "\" --workspace trial -O";
65
+ }
66
+
67
+ static inline string save(const string& name){ return string("zip ") + name + ".zip trial/mesh/*"; }
68
+
69
+ template <typename T>
70
+ constexpr auto q_to_v(queue<T> qcopy){
71
+ vector<T> v;
72
+ v.reserve(qcopy.size());
73
+ while(!qcopy.empty())
74
+ v.push_back(qcopy.front()), qcopy.pop();
75
+ return v;
76
+ }
77
+
78
+ int main(){
79
+ crow::SimpleApp app;
80
+ typedef std::array<string, 2> guy;
81
+ auto commissions = make_shared<queue<guy>>();
82
+ auto queue_mutex = make_shared<mutex>()
83
+ , train_mutex = make_shared<mutex>();
84
+ auto pool = make_shared<threadpool<>>(2);
85
+ auto run = [=](const string& cmd){
86
+ CROW_LOG_INFO << "running \'" << cmd;
87
+ return exec(cmd.c_str());
88
+ };
89
+
90
+ auto check_queue = [=](const string& name) -> int {
91
+ if(!commissions->empty()){
92
+ const auto v = q_to_v(*commissions);
93
+ if(auto pos = std::find_if( v.begin(), v.end()
94
+ , [=](const guy& g){ auto& [n,d] = g; return n == name; });
95
+ pos != v.end())
96
+ return int(std::distance(v.begin(), pos));
97
+ }
98
+ return -1;
99
+ };
100
+
101
+ auto poppe = [=](){
102
+ lock_guard<mutex> qlock(*queue_mutex);
103
+ commissions->pop();
104
+ CROW_LOG_INFO << commissions->size() << " left in queue";
105
+ };
106
+
107
+ auto training_loop = [=](){
108
+ lock_guard<mutex> lock(*train_mutex);
109
+ while(!commissions->empty()){
110
+ auto& [name, prompt] = commissions->front();
111
+ CROW_LOG_INFO << "Launched training for " + name;
112
+ run(reset), run(train(prompt)), run(save(name));
113
+ CROW_LOG_INFO << "Finished training for " + name;
114
+ poppe();
115
+ }
116
+ };
117
+
118
+ auto enqueue = [=](const guy& thing){
119
+ lock_guard<mutex> lock(*queue_mutex);
120
+ commissions->push(thing);
121
+ auto& [name, prompt] = thing;
122
+ CROW_LOG_INFO << name << " queued with prompt: " << prompt;
123
+ };
124
+
125
+ CROW_ROUTE(app, "/create/<string>")
126
+ .methods("GET"_method, "POST"_method)([=](const crow::request& req, const string& name){
127
+ CROW_LOG_INFO << name << " commissioned";
128
+ if(auto prompt = req.url_params.get("prompt"); prompt == nullptr){
129
+ CROW_LOG_INFO << "No prompt specified";
130
+ return "Error: Can't train a NeRF for " + name + " without a prompt!";
131
+ } else {
132
+ if(auto r = check_queue(name); r < 0){
133
+ enqueue({name, prompt});
134
+ pool->enqueue(training_loop);
135
+ CROW_LOG_INFO << "Launched training loop";
136
+ return "Scheduled training for " + name;
137
+ } else
138
+ return name + " is currently "
139
+ + (r ? string("in line") : string("training"));
140
+ }
141
+ });
142
+
143
+ CROW_ROUTE(app, "/check/<string>")([=](crow::response& res, const string& name){
144
+ CROW_LOG_INFO << name << " check'd";
145
+ if(fs::exists(fs::path(name + ".zip"))){
146
+ res.write("O I know that guy");
147
+ res.set_static_file_info(name + ".zip");
148
+ } else if(auto r = check_queue(name); r < 0)
149
+ res.write("Doesn't look like much of anything to me");
150
+ else
151
+ res.write(name + " is currently "
152
+ + (r ? string("in line") : string("training")));
153
+ res.end();
154
+ });
155
+
156
+ CROW_ROUTE(app, "/list")([&](){
157
+ std::vector<string> fin = splitOn(exec("ls *zip"), "\n")
158
+ , q = reify(q_to_v(*commissions) | rv::transform([](const guy& i){ return i[0]; }));
159
+ crow::json::wvalue ret;
160
+ ret["finished"] = fin;
161
+ ret["pending"] = q;
162
+ return ret;
163
+ });
164
+
165
+ app.port(80).run();
166
+ }
threadpool.h ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #pragma once
2
+ #include <atomic>
3
+ #include <condition_variable>
4
+ #include <functional>
5
+ #include <future>
6
+ #include <mutex>
7
+ #include <queue>
8
+ #include <utility>
9
+ #include <vector>
10
+ #include <concepts>
11
+ #include <thread>
12
+ static inline size_t avail_threads(){
13
+ return std::thread::hardware_concurrency();
14
+ }
15
+
16
+ template <typename F, typename... Args>
17
+ using irt = std::invoke_result_t<F, Args...>;
18
+
19
+ template <typename F, typename... Args>
20
+ static inline auto taskify(const F& funk, Args... args){
21
+ return std::bind(funk, std::forward<Args...>(args)...);
22
+ }
23
+
24
+ static inline auto promitask(const std::invocable<> auto& funk){
25
+ typedef irt<decltype(funk)> ret;
26
+ auto pr = std::make_shared<std::promise<ret>>();
27
+ if constexpr (std::same_as<irt<decltype(funk)>, void>)
28
+ return make_pair([=](){ funk(), pr->set_value(); }, pr);
29
+ else
30
+ return make_pair([=](){ pr->set_value(funk()); }, pr);
31
+ }
32
+
33
+ static inline auto await_many(const std::ranges::range auto& fu){
34
+ std::for_each(fu.begin(), fu.end(), [](auto&& f){ f.wait(); });
35
+ }
36
+
37
+ typedef std::function<void()> tasque;
38
+
39
+ template <typename Thrd = std::jthread>
40
+ class threadpool {
41
+ /// If true the queue thread should exit
42
+ std::atomic<bool> done;
43
+
44
+ /// The thread object associated with this queue
45
+ std::vector<Thrd> queue_threads;
46
+ /// A queue of functions that will be executed on the queue thread
47
+ std::queue<tasque> work_queue;
48
+
49
+ /// The mutex used in the condition variable
50
+ std::mutex queue_mutex;
51
+
52
+ /// The condition variable that waits for a new function to be inserted in the
53
+ /// queue
54
+ std::condition_variable cond;
55
+
56
+ /// This funciton executes on the queue_thread
57
+ void queue_runner() {
58
+ while (!done) {
59
+ tasque func;
60
+ {
61
+ std::unique_lock<std::mutex> lock(queue_mutex);
62
+ cond.wait( lock
63
+ , [this]() { return work_queue.empty() == false || done; });
64
+
65
+ if (!done){
66
+ swap(func, work_queue.front());
67
+ work_queue.pop();
68
+ }
69
+ }
70
+ if (func) func();
71
+ }
72
+ }
73
+
74
+ void qup(const std::invocable<> auto& f){
75
+ std::lock_guard<std::mutex> lock(queue_mutex);
76
+ work_queue.push(f);
77
+ cond.notify_one();
78
+ }
79
+
80
+ public:
81
+ template <typename F, typename... Args>
82
+ void enqueue(const F& func, Args... args) requires std::invocable<F, Args...> {
83
+ qup(taskify(func, args...));
84
+ }
85
+
86
+ template <typename F, typename... Args>
87
+ auto inquire(const F& func, Args... args) requires std::invocable<F, Args...> {
88
+ auto [t, pr] = promitask(taskify(func, args...));
89
+ auto fut = pr->get_future();
90
+ enqueue(t);
91
+ return fut;
92
+ }
93
+
94
+ void clear() {
95
+ {
96
+ std::lock_guard<std::mutex> lock(queue_mutex);
97
+ while(!work_queue.empty())
98
+ work_queue.pop();
99
+ }
100
+ sync();
101
+ }
102
+
103
+ void sync(){
104
+ std::atomic<size_t> n(0);
105
+ const size_t m = queue_threads.size();
106
+ auto present = [&](){ ++n; size_t l = n.load(); while(l < m) l = n.load(); };
107
+ std::vector<std::future<void>> fu;
108
+ std::ranges::generate_n(std::back_inserter(fu), m, [=, this](){ return inquire(present); });
109
+ await_many(fu);
110
+ }
111
+
112
+ threadpool(size_t n, size_t res) : done(false)
113
+ , queue_threads(n ? std::clamp(n, size_t(1), avail_threads() - res)
114
+ : std::max(size_t(1), avail_threads() - res)) {
115
+ for(auto& i:queue_threads){
116
+ Thrd tmp(&threadpool::queue_runner, this);
117
+ std::swap(i, tmp);
118
+ }
119
+ }
120
+ threadpool(size_t n) : threadpool(n, 0) {}
121
+ threadpool() : threadpool(0, 1) {}
122
+
123
+ ~threadpool() {
124
+ sync();
125
+ done.store(true);
126
+ cond.notify_all();
127
+ }
128
+
129
+ threadpool(const threadpool& other) : work_queue(other.work_queue), done(false) {
130
+ for(auto& i:queue_threads){
131
+ Thrd tmp(&threadpool::queue_runner, this);
132
+ std::swap(i, tmp);
133
+ }
134
+ }
135
+
136
+ threadpool& operator=(const threadpool& other){
137
+ clear();
138
+ work_queue = other.work_queue;
139
+ return *this;
140
+ }
141
+ size_t size() const { return queue_threads.size(); }
142
+ threadpool& operator=(threadpool&& other) = default;
143
+ threadpool(threadpool&& other) = default;
144
+ };
145
+