Skip to content

Commit d1999d7

Browse files
committed
Converted all websocket/socket communication to JSON.
1 parent d1f231b commit d1999d7

16 files changed

+357
-334
lines changed

Diff for: .gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "framework/host/json"]
2+
path = framework/host/json
3+
url = https://github.com/nlohmann/json.git

Diff for: apps/mandelbrot/build/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ ADDITIONAL_HDRS=
4747
#Software (no FPGA) flags
4848
SW_SRC=$(ADDITIONAL_SRC) $(FRAMEWORK_DIR)/server_main.c $(HOST_DIR)/lodepng.c $(HOST_DIR)/mandelbrot.c
4949
SW_HDRS=$(ADDITIONAL_HDRS) $(HOST_DIR)/mandelbrot.h
50-
SW_CFLAGS=-g -Wall -O3 -std=c++11 -I$(HOST_DIR) -I$(FRAMEWORK_DIR)
50+
SW_CFLAGS=-g -Wall -O3 -std=c++11 -I$(HOST_DIR) -I$(FRAMEWORK_DIR) -I../../../framework/host/json/include
5151
SW_LFLAGS=-L${XILINX_SDX}/runtime/lib/x86_64
5252

5353
#Host code

Diff for: apps/mandelbrot/host/mandelbrot.c

+91-55
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,27 @@ inline double fastPow(double a, double b) {
4545
return u.d;
4646
}
4747

48+
4849
// ===========================================================================================
4950
// A Mandelbrot image.
5051
//
5152

52-
53-
MandelbrotImage::MandelbrotImage(double *params, bool fpga_param) {
53+
MandelbrotImage::MandelbrotImage(json &j) {
54+
params_json = j;
5455

5556
// // Print sizeof(stuff)
5657
//cout << "int: " << sizeof(int) << ", long: " << sizeof(long) << ", long long: " << sizeof(long long) << ", float: " << sizeof(float) << ", double: " << sizeof(double) << ", long double: " << sizeof(long double) << endl;
5758

58-
fpga = fpga_param; // Currently we restrict image settings based on whether the FPGA was _requested_ (whether available/used or not).
59-
test_flags = (int)(params[23]);
59+
fpga = param<string>("renderer", "fpga") == "fpga"; // Currently we restrict image settings based on whether the FPGA was _requested_ (whether available/used or not).
60+
param("test_flags", test_flags, 0);
6061
for (int i = 0; i < 16; i++) {
61-
test_vars[i] = (int)(params[24+i]);
62+
try {
63+
j["test_vars"][i].get_to(test_vars[i]);
64+
} catch (nlohmann::detail::exception) {
65+
test_vars[i] = 0.0L;
66+
}
6267
}
63-
68+
6469
verbosity = (int)getTestVar(15, -10.0, 10.0);
6570
if (verbosity < 0) {verbosity = 0;}
6671

@@ -81,7 +86,6 @@ MandelbrotImage::MandelbrotImage(double *params, bool fpga_param) {
8186
}
8287

8388
enableTimer(0);
84-
8589

8690
depth_array = right_depth_array = NULL;
8791
fractional_depth_array = right_fractional_depth_array = NULL;
@@ -91,9 +95,12 @@ MandelbrotImage::MandelbrotImage(double *params, bool fpga_param) {
9195
req_width = req_height = 0;
9296
calc_width = calc_height = 0;
9397
x = y = req_pix_size = calc_pix_size = (coord_t)0.0L;
94-
is_3d = (params[9] > 0.0L);
95-
int modes = (int)(params[16]); // Bits, lsb first: 0: python(irrelevant here), 1: C++, 2: reserved, 3: optimize1, 4-5: reserved, 6: full-image, ...
96-
int colors = (int)(params[17]);
98+
param("three_d", is_3d, false);
99+
int modes;
100+
param("modes", modes, 0); // Bits, lsb first: 0: python(irrelevant here), 1: C++, 2: reserved, 3: optimize1, 4-5: reserved, 6: full-image, ...
101+
int colors;
102+
param("colors", colors, 0);
103+
97104

98105
// Active color scheme
99106
active_color_scheme_index = colors & 65535;
@@ -105,18 +112,17 @@ MandelbrotImage::MandelbrotImage(double *params, bool fpga_param) {
105112
color_shift = ((colors >> 16) & 255) * color_scheme_size[active_color_scheme_index] / 100; // amount to shift color scheme given as 0-99 (percent) and adjusted for color scheme size.
106113
full_image = (bool)((modes >> 6) & 1);
107114
//+int color_scheme = (int)(params[17]);
108-
spot_depth = (int)(params[18]);
115+
param("spot_depth", spot_depth, -1);
109116
show_spot = spot_depth >= 0;
110-
brighten = (int)(params[13]);
111-
eye_adjust = params[14];
117+
param("brighten", brighten, 0);
118+
param<coord_t>("eye_adjust", eye_adjust, 0.0L);
112119
int eye_sep_adjust = (int)(getTestVar(14, -500.0f, 500.0f));
113-
req_eye_separation = params[15] + eye_sep_adjust;
114-
adjustment = params[7] / 100.0L;
115-
adjustment2 = params[8] / 100.0L;
120+
req_eye_separation = param("eye_sep", 0.0L) + eye_sep_adjust;
121+
adjustment = param<coord_t>("var1", 0.0L) / 100.0L;
122+
adjustment2 = param<coord_t>("var2", 0.0L) / 100.0L;
116123
adjust = (adjustment != 0.0L || adjustment2 != 0.0L) && !fpga;
117124

118-
119-
int texture = fpga ? 0 : (int)(params[19]);
125+
int texture = fpga ? 0 : param<int>("texture", 0);
120126
string_lights = (bool)((texture >> 0) & 1);
121127
fanciful_pattern = (bool)((texture >> 1) & 1);
122128
shadow_interior = (bool)((texture >> 2) & 1);
@@ -126,16 +132,15 @@ MandelbrotImage::MandelbrotImage(double *params, bool fpga_param) {
126132
light_brightness = getTestVar(13, 1.0f, 5.2f);
127133

128134
power_divergence = getTestFlag(6);
129-
int edge_style = (fpga || power_divergence) ? 0 : (int)(params[20]);
135+
int edge_style = (fpga || power_divergence) ? 0 : param<int>("edge", 0);
130136
square_divergence = edge_style == 1;
131137
y_squared_divergence = edge_style == 2;
132138
normal_divergence = !(power_divergence || square_divergence || y_squared_divergence || ornaments);
133-
int theme = fpga ? 0 : (int)(params[21]);
139+
int theme = fpga ? 0 : param<int>("theme", 0);
134140
no_theme = theme == 0;
135141
xmas_theme = theme == 1;
136-
137-
cycle = (int)(params[22]);
138-
142+
143+
param("cycle", cycle, 0);
139144
test_texture = getTestFlag(0);
140145
lighting = string_lights || fanciful_pattern || shadow_interior || round_edges;
141146
textured = (test_texture || lighting) && !fpga;
@@ -157,7 +162,7 @@ MandelbrotImage::MandelbrotImage(double *params, bool fpga_param) {
157162
use_derivatives = getTestFlag(15);
158163

159164
// For darkening distant 3D depths.
160-
darken = (params[12] > 0.0L);
165+
param("darken", darken, false);
161166
texture_max = !darken && getTestFlag(27); // Apply texture to max depth. Note that use_next has no effect on max-depth texture, as next_* have not been updated for max_depth.
162167
// Do not darken if debugging max depth, as it could change dynamically.
163168
half_faded_depth = 30;
@@ -193,18 +198,17 @@ MandelbrotImage::MandelbrotImage(double *params, bool fpga_param) {
193198

194199
assert(! IS_BIG_ENDIAN);
195200

196-
x = (coord_t)params[0];
197-
y = (coord_t)params[1];
198-
req_pix_size = (coord_t)params[2]; // (assuming same size x and y, even though both are sent)
199-
//pix_y = (coord_t)params[3];
200-
req_width = (int)params[4];
201-
req_height = (int)params[5];
201+
x = param<coord_t>("x", 0.0L);
202+
y = param<coord_t>("y", 0.0L);
203+
param<coord_t>("pix_x", req_pix_size, 0.0L); // (assuming same size x and y, even though both are sent)
204+
param("width", req_width, 0);
205+
param("height", req_height, 0);
202206
calc_width = req_width; // assuming not 3d and not limited by FPGA restrictions
203207
calc_height = req_height; // "
204-
spec_max_depth = (int)params[6];
208+
param("max_depth", spec_max_depth, 250);
205209
max_depth = -1000; // garbage value
206-
if (getTestFlag(2)) {spec_max_depth = (int)(sqrt(params[6])) - 4;}
207-
req_eye_offset = (int)(params[10]) - (eye_sep_adjust >> 1);
210+
if (getTestFlag(2)) {spec_max_depth = sqrt(spec_max_depth) - 4;}
211+
req_eye_offset = param<int>("offset_w", 0) - (eye_sep_adjust >> 1);
208212
is_stereo = is_3d && req_eye_separation > 0;
209213
req_center_w = req_width >> 1; // (adjusted by req_eye_offset for stereo 3D)
210214
req_center_h = req_height >> 1;
@@ -288,8 +292,7 @@ MandelbrotImage::MandelbrotImage(double *params, bool fpga_param) {
288292
if (verbosity > 0)
289293
cout << "Settings: smooth: " << smooth << ", smooth_texture: " << smooth_texture << ", divergence_fn: " << power_divergence << y_squared_divergence << square_divergence << normal_divergence
290294
<< ", string_lights: " << string_lights << "expansion_factor_3d: " << expansion_factor_3d << "req: (" << req_width << ", " << req_height << "), calc: (" << calc_width << ", " << calc_height << ")" << endl;
291-
};
292-
295+
}
293296

294297

295298
MandelbrotImage::~MandelbrotImage() {
@@ -873,12 +876,43 @@ inline int MandelbrotImage::pixelDepth(int w, int h, bool trying) {
873876
if (round_edges) {
874877
float beyond = divergent_radius + (outward - ornament_shrink) / 1.5f * divergent_radius; // Divisor increases rounding.
875878
next_effective_radius_sq = beyond * beyond;
876-
}
879+
}
877880
}
878881
}
879882
}
880883
}
881-
next_diverges = next_effective_radius_sq > divergent_radius_sq || force_diverge;
884+
885+
// Experimental approximations for determining convergence and stopping the search on convergence as well as divergence:
886+
// These are interesting and worth enabling.
887+
bool conv = false;
888+
/*
889+
// Look at fixed windows of radius history and compare.
890+
x_hist[depth % 16] = xx * xx + yy * yy;
891+
// Is there a convergent trend.
892+
if (depth > 16) {
893+
coord_t diff = 0.0L;
894+
for (int i = 0; i < 8; i++) {
895+
diff += x_hist[(depth - i - 8) % 16] - x_hist[(depth - i ) % 16];
896+
}
897+
conv = diff > sqrt(x0 * x0 + y0 * y0);
898+
}
899+
*/
900+
/*
901+
// Keep two weighted radius histories with different decay. If that slower decay has a larger value, there's convergence.
902+
if (depth == 0) {
903+
exp = 0.0L;
904+
exp2 = 0.0L;
905+
} else {
906+
exp = 0.95L * exp + 0.05L * (xx * xx + yy * yy);
907+
exp2 = 0.98L * exp2 + 0.02L * (xx * xx + yy * yy);
908+
}
909+
conv = exp < 0.99L * exp2;
910+
*/
911+
next_diverges = next_effective_radius_sq > divergent_radius_sq ||
912+
//next_effective_radius_sq < 0.01 || // Creates dots inside (mostly) convergent region.
913+
//(dxx_dx0 * dxx_dx0 + dyy_dx0 * dyy_dx0 < 0.01 && depth > 0) || // Creates dots inside (mostly) convergent region. (need_derivatives must be true)
914+
conv ||
915+
force_diverge;
882916

883917

884918
// DONE?
@@ -1051,8 +1085,6 @@ inline int MandelbrotImage::pixelDepth(int w, int h, bool trying) {
10511085
bool radial = getTestFlag(1) || smooth_texture;
10521086
float a_granularity = ((float)(1 << (int)getTestVar(5, 0.0, 12.0))) / 64.0f; //fastPow(2.0L, (double)(int)getTestVar(5, -6.0, 6.0));
10531087
float b_granularity = ((float)(1 << (int)getTestVar(6, 0.0, 12.0))) / 64.0f; //fastPow(2.0L, (double)(int)getTestVar(6, -6.0, 6.0));
1054-
//-bool fine_grained = getTestFlag(8);
1055-
//-bool coarse_grained = getTestFlag(9);
10561088
bool two_tone = getTestFlag(10);
10571089
bool use_next = getTestFlag(11);
10581090
float a_adj = getTestVar(3, 0.0f, 2.0f);
@@ -1444,7 +1476,7 @@ MandelbrotImage *MandelbrotImage::generateMandelbrot() {
14441476
// initial approximation.
14451477
if (adjust) {
14461478
// Matched to eye depth.
1447-
adjust_depth = start_darkening_depth; // Begin adjustment where we begin darkening (both should be around first visible level) //- getZoomDepth() - eye_depth_fit - eye_adjust;
1479+
adjust_depth = start_darkening_depth; // Begin adjustment where we begin darkening (both should be around first visible level)
14481480
}
14491481
if (verbosity > 3)
14501482
cout << "adjust: " << adjust << ", adjust_depth: " << adjust_depth << ", auto_depth" << auto_depth << ", adjustment: " << adjustment << ", smooth: " << smooth << flush;
@@ -1711,9 +1743,6 @@ MandelbrotImage::color_t * MandelbrotImage::allocGradientEdgePairColorScheme(int
17111743

17121744
// Mimic these two edges to form the other four.
17131745
completeRGBShiftedColorScheme(color_scheme, colors_per_part);
1714-
//-for (int j = 0; j < size; j++) {
1715-
//- color_scheme[j].component[2] = (j % 4) * 64 + 32;
1716-
//-}
17171746

17181747
return color_scheme;
17191748
}
@@ -1857,17 +1886,22 @@ void HostMandelbrotApp::get_image(int sock) {
18571886
#endif
18581887
dynamic_array array_struct;
18591888

1860-
array_struct = handle_write_data(sock);
1861-
bool fpga_req = true;
1862-
if (array_struct.data[6] < 0) {
1863-
// Depth argument is negative. This is our indication that we must render in C++. TODO: Ick!
1864-
array_struct.data[6] = - array_struct.data[6];
1865-
fpga_req = false;
1866-
}
1867-
// Or, newer, only slightly less icky flag
1868-
if ((array_struct.data_size >= 16) && (((int)(array_struct.data[16])) & (1 << 1))) {
1869-
fpga_req = false;
1870-
}
1889+
json json_obj = read_json(sock);
1890+
//cout << "C++ read JSON: " << json_obj << endl;
1891+
1892+
// TODO: Eliminate array_struct.
1893+
1894+
array_struct.data_size = 7; // TODO
1895+
array_struct.data = (double *) malloc(CHUNK_SIZE * 100 /* TODO */);
1896+
array_struct.data[0] = json_obj["x"];
1897+
array_struct.data[1] = json_obj["y"];
1898+
array_struct.data[2] = json_obj["pix_x"];
1899+
array_struct.data[3] = json_obj["pix_y"];
1900+
array_struct.data[4] = json_obj["width"];
1901+
array_struct.data[5] = json_obj["height"];
1902+
array_struct.data[6] = json_obj["max_depth"];
1903+
1904+
18711905
#ifdef OPENCL
18721906
if (fpga_req) {
18731907
// Don't go bigger than allocated sizes.
@@ -1879,7 +1913,7 @@ void HostMandelbrotApp::get_image(int sock) {
18791913
}
18801914
}
18811915
#endif
1882-
MandelbrotImage * mb_img_p = newMandelbrotImage(array_struct.data, fpga_req);
1916+
MandelbrotImage * mb_img_p = newMandelbrotImage(json_obj);
18831917

18841918
// Free memory for array_struct.
18851919
free(array_struct.data);
@@ -1934,6 +1968,8 @@ void HostMandelbrotApp::get_image(int sock) {
19341968
unsigned char *png;
19351969
png = mb_img_p->generatePNG(&png_size);
19361970

1971+
//cout << "C++ Image Generated" << endl;
1972+
19371973
// Call the utility function to send data over the socket
19381974
handle_read_data(sock, png, (int)png_size);
19391975
delete mb_img_p;

Diff for: apps/mandelbrot/host/mandelbrot.h

+32-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class MandelbrotImage {
103103
// Constructors (with optional arguments for some settings)
104104
//
105105

106-
MandelbrotImage(double *params, bool fpga_param);
106+
MandelbrotImage(json &params);
107107
virtual ~MandelbrotImage();
108108

109109

@@ -135,6 +135,28 @@ class MandelbrotImage {
135135
// 3: (1 & 2) (not currently supported)
136136
MandelbrotImage * enableTimer(int level = 2);
137137

138+
template <class T>
139+
void param(const string name, T &var, const T def) {
140+
try {
141+
params_json.at(name).get_to(var);
142+
} catch (nlohmann::detail::type_error) {
143+
cerr << "Param " << name << " has wrong type." << endl;
144+
var = def;
145+
} catch (nlohmann::detail::out_of_range) {
146+
if (verbosity > 1) {
147+
cout << "Defaulting param " << name << " = " << def << endl;
148+
}
149+
var = def;
150+
}
151+
}
152+
153+
template <class T>
154+
T param(const string name, const T def) {
155+
T var;
156+
param(name, var, def);
157+
return var;
158+
}
159+
138160
//
139161
// Compute Methods
140162
//
@@ -207,6 +229,9 @@ class MandelbrotImage {
207229
color_t * active_color_scheme; // The active one.
208230
int active_color_scheme_size; // "
209231

232+
233+
json params_json; // JSON parameters.
234+
210235
bool electrify;
211236
int color_shift;
212237

@@ -293,6 +318,11 @@ class MandelbrotImage {
293318
bool texture_max; // Color at max_depth (not possible if darken, as this sets max_depth dynamically). Mainly for debug.
294319
int half_faded_depth;
295320
float start_darkening_depth;
321+
322+
// Experimental:
323+
coord_t x_hist[16], y_hist[16];
324+
coord_t exp; // Experimental
325+
coord_t exp2; // Experimental too
296326

297327
// Storage structures. These are freed upon destruction.
298328
int *depth_array; // Image array of depth integers.
@@ -394,7 +424,7 @@ class HostMandelbrotApp : public HostApp {
394424
#else
395425
void get_image(int sock);
396426
#endif
397-
virtual MandelbrotImage * newMandelbrotImage(double *params, bool fpga_req) {return new MandelbrotImage(params, fpga_req);} // Can be extented to utilize a derived type.
427+
virtual MandelbrotImage * newMandelbrotImage(json &params) {return new MandelbrotImage(params);} // Can be extented to utilize a derived type.
398428
};
399429

400430

Diff for: apps/mandelbrot/webserver/css/about.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#content {
2-
background-image: url("/img?data=[-1.0221004461908865,0.37353728027791605,0.000002985021213376194,0.000002985021213376194,1670,1490,2500]&var1=0&var2=0&three_d=0&offset_w=0&offset_h=0&eye_sep=0&darken=1&brighten=0&eye_adjust=0&renderer=cpp&modes=194&colors=3604480");
2+
background-image: url("/img?json={%22x%22:-1.0221004461908865,%22y%22:0.37353728027791605,%22pix_x%22:0.000002985021213376194,%22pix_y%22:0.000002985021213376194,%22width%22:1670,%22height%22:1490,%22max_depth%22:2500,%22darken%22:true,%22renderer%22:%22fpga%22,%22colors%22:3604480,%22modes%22:194}");
33
background-attachment: fixed;
44
}
55
#mask {

0 commit comments

Comments
 (0)