Skip to content

Commit 6cc9a7d

Browse files
committed
Added parameter with pseudo random manipulation support (crashes kernel - to fix next)
1 parent bc35589 commit 6cc9a7d

2 files changed

Lines changed: 224 additions & 43 deletions

File tree

demo/playground.html

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.13.4/codemirror.js"></script>
1515
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.13.4/mode/javascript/javascript.js"></script>
1616

17+
<!-- seed random : https://github.com/davidbau/seedrandom -->
18+
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.0/lib/xor4096.min.js"></script>
19+
1720
<!-- chartist -->
1821
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/chartist/0.9.7/chartist.min.css">
1922
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartist/0.9.7/chartist.js"></script>
@@ -47,13 +50,18 @@ <h1>GPU.js - playground : <small style="display:inline-block">GPU Accelerated Ja
4750
<div class="container">
4851
<h3>Step 1) Setup your input parameters generator</h3>
4952
<blockquote>
50-
(to-be-implmented : currently do an array of [0-samplesize], for 2 arguments)<br/>
51-
- Setup your various argument generator settings here.
52-
<br/>
53+
Setup your various argument generator settings here.<br/>
5354
<br/>
5455
- Number of parameters : To pass to the final GPU.js function<br/>
5556
- Sample size : Size for the sample display<br/>
56-
- Random seed : Seed value, used by the random function
57+
- Random seed : Seed value, used by the random function<br/>
58+
<br/>
59+
Each parameter function are passed in 2 attributes<br/>
60+
<br/>
61+
- size : The sample size used for this iteration<br/>
62+
- rand : The 0-1 floating value, pesudo random generator used for this sample size, and parameter count.<br/>
63+
<br/>
64+
(Pesudo random is choosen to make testing and debugging the parameter function generator easier and consistent)
5765
</blockquote>
5866
</div>
5967
<div class="container">
@@ -97,38 +105,17 @@ <h3>Step 1) Setup your input parameters generator</h3>
97105
</div>
98106
</div>
99107
<div class="container paramContainer">
100-
<div class="col-sm-6 paramGroup" id="paramGroupSample">
101-
<div class="paramGroupInner form-group">
102-
<label class="control-label" for="param_name">Parameter Name</label>
103-
<input type="text" name="param_name" class="form-control" value="A">
104-
<label class="control-label" for="param_function">Parameter Function</label>
105-
<textarea name="param_function">function(size,rand) {
106-
var ret = [];
107-
for(var i=0; i<size; ++i){
108-
ret[i] = i;
109-
}
110-
return ret;
111-
}
112-
</textarea>
113-
<label class="control-label" for="param_sample">Sample Output</label>
114-
<pre class="param_sample"></pre>
115-
</div>
116-
</div>
117-
<div class="col-sm-6 paramGroup" id="paramGroupSample">
118-
<div class="paramGroupInner form-group">
119-
<label class="control-label" for="param_name">Parameter Name</label>
120-
<input type="text" name="param_name" class="form-control" value="B">
121-
<label class="control-label" for="param_function">Parameter Function</label>
122-
<textarea name="param_function">function(size,rand) {
123-
var ret = [];
124-
for(var i=0; i<size; ++i){
125-
ret[i] = i;
126-
}
127-
return ret;
128-
}
129-
</textarea>
130-
<label class="control-label" for="param_sample">Sample Output</label>
131-
<pre class="param_sample"></pre>
108+
<div class="paramGroupContainer" id="paramGroupContainer">
109+
<div class="col-sm-6 paramGroup" id="paramGroupTemplate" style="display:none;">
110+
<div class="paramGroupInner form-group">
111+
<label class="control-label" for="param_name">Parameter Name</label>
112+
<input type="text" name="param_name" class="param_name form-control" value="A">
113+
<label class="control-label" for="param_function">Parameter Function</label>
114+
<textarea name="param_function" class="param_function">
115+
</textarea>
116+
<label class="control-label" for="param_sample">Sample Output</label>
117+
<pre class="param_sample"></pre>
118+
</div>
132119
</div>
133120
</div>
134121
<button id="paramset_btn" type="button" class="btn btn-primary btn-lg btn-block paramset_btn">Generate parameter samples</button>

demo/playground.js

Lines changed: 201 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,210 @@ $(function() {
8585

8686
//-------------------------------------------
8787
//
88-
// Parameter setup
88+
// Utility functions
8989
//
9090
//-------------------------------------------
9191

92-
/// @TODO setup and normalize the parameter list
92+
// Used to indicate to the CM_blockFirstAndLastLine to ignore cancel step
93+
var CM_doNotCancelOrigin = "do-not-cancel";
94+
95+
// Blocks the first and last line inside the code mirror from being editted
96+
function CM_blockFirstAndLastLine(cm,change) {
97+
98+
// If origin is set to "not-cancel" ignore
99+
if( change.origin == CM_doNotCancelOrigin ) {
100+
return;
101+
}
102+
103+
if( change.from.line <= 0 || cm.lineCount() - 1 <= change.to.line) {
104+
change.cancel();
105+
}
106+
}
107+
108+
//-------------------------------------------
109+
//
110+
// Code mirror parameters generator setup
111+
//
112+
//-------------------------------------------
113+
114+
/// Default parameter names : alphabectical
115+
var paramDefaultNames = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split('');
116+
117+
/// Default parameter function
118+
var paramDefaultFunction = ""+
119+
"function(size,rand) {\n"+
120+
" var ret = [];\n"+
121+
" for(var i=0; i<size; ++i){\n"+
122+
" ret[i] = parseInt(rand()*100);\n"+
123+
" }\n"+
124+
" return ret;\n"+
125+
"}";
126+
127+
/// Parameter code mirror objects
128+
var CM_parameters = [];
129+
var paramNameInputs = [];
130+
var paramSampleOutputs = [];
131+
132+
/// Get the parameter count
133+
function getParamCount() {
134+
return parseInt( $("#arg_count").val() );
135+
}
136+
137+
/// Update the parameter display list, to match the number of parameters
93138
function updateParamsList() {
94139

140+
// Get the main parameter container to update
141+
var pContainer = $("#paramGroupContainer");
142+
var template = pContainer.find("#paramGroupTemplate")
143+
144+
// Hide everything : handle the case for reduced parameters
145+
pContainer.find(".paramGroup").hide();
146+
147+
// Get desired parameter count
148+
var pCount = getParamCount();
149+
150+
// Time to iterate, and create/reveal those paramGroups
151+
for(var p=0; p<pCount; ++p) {
152+
var pNode = $("#paramGroup_"+p);
153+
154+
if( pNode == null || pNode.length == 0 ) {
155+
pNode = template.clone();
156+
157+
pNode.attr("id", "#paramGroup_"+p);
158+
pNode.find(".param_name").val( paramDefaultNames[p] );
159+
160+
// Setup code mirror
161+
CM_parameters[p] = CodeMirror.fromTextArea(pNode.find(".param_function")[0], {
162+
lineNumbers: true,
163+
mode: {name: "javascript", json: true},
164+
indentUnit: 3,
165+
tabSize: 3
166+
});
167+
168+
// Setup default value
169+
CM_parameters[p].setValue(paramDefaultFunction);
170+
171+
// Block edits for first and last line
172+
CM_parameters[p].on('beforeChange', CM_blockFirstAndLastLine);
173+
174+
// Add param name, and sample output nodes to array (for easy refence)
175+
paramNameInputs[p] = pNode.find(".param_name");
176+
paramSampleOutputs[p] = pNode.find(".param_sample");
177+
178+
pContainer.append(pNode);
179+
}
180+
181+
pNode.show();
182+
CM_parameters[p].refresh();
183+
}
184+
185+
// Update parameter names
186+
updateKernelParamNames();
187+
}
188+
189+
/// Get the configured parameter functions
190+
function getParameterFunctions() {
191+
var ret = [];
192+
var pCount = getParamCount();
193+
194+
for( var p=0; p<pCount; ++p ) {
195+
try {
196+
eval("ret[p] = "+CM_parameters[p].getValue());
197+
} catch(e) {
198+
paramSampleOutputs[p].html(e.toString());
199+
console.error("Failed to process parameter "+p, e);
200+
alert("Failed to process parameter "+p+" : "+e);
201+
return null;
202+
}
203+
}
204+
205+
return ret;
206+
}
207+
208+
/// The random seed dom
209+
var rand_seed_jqDom = $("#rand_seed");
210+
211+
/// Get the pesudo random number generator for the sample size / parameter count
212+
function getRandom(parameterCount, sampleSize, rand_seed) {
213+
if(rand_seed == null) {
214+
rand_seed = rand_seed_jqDom.val();
215+
}
216+
217+
return new xor4096(parameterCount+"-"+rand_seed+"-"+sampleSize);
218+
}
219+
220+
/// Update the parameter samples
221+
function updateParameterSamples() {
222+
// Get the param functions
223+
var paramFunctions = getParameterFunctions();
224+
225+
// Invalid parameter function
226+
if(paramFunctions == null) {
227+
$("#paramGroupContainer .param_sample").html("");
228+
return;
229+
}
230+
231+
// Get demo sample size
232+
var sample_size = $("#sample_size").val();
233+
234+
// Iterate, execute
235+
var pCount = paramFunctions.length;
236+
for(var p=0; p<pCount; ++p) {
237+
var rand = getRandom(p, sample_size);
238+
var sample = paramFunctions[p](sample_size, rand);
239+
240+
paramSampleOutputs[p].html( JSON.stringify(sample) );
241+
}
242+
243+
// Update parameter names
244+
updateKernelParamNames();
245+
}
246+
247+
/// Setup the parameter generators
248+
function setupParameterGenerator() {
249+
updateParamsList();
250+
$("#arg_count").change(updateParamsList);
251+
$("#paramset_btn").click(updateParameterSamples);
252+
}
253+
254+
/// Get the parameter names, after NORMALIZING them (just in case)
255+
function getParameterNames() {
256+
var ret = [];
257+
258+
// Get desired parameter count
259+
var pCount = getParamCount();
260+
261+
// Iterate through
262+
for( var p = 0; p < pCount; ++p ) {
263+
var name = paramNameInputs[p].val();
264+
name = name.replace(/\W/g, '');
265+
266+
if( name == null || name.length <= 0 ) {
267+
name = paramDefaultNames[p];
268+
}
269+
paramNameInputs[p].val(name);
270+
ret[p] = name;
271+
}
272+
273+
return ret;
274+
}
275+
276+
/// Updates the kernel first line, with the parameter names
277+
function updateKernelParamNames() {
278+
// Out of order initialzing =(
279+
if(CM_kernel == null) {
280+
return;
281+
}
282+
283+
var paramNames = getParameterNames();
284+
285+
var kernelHeader = "function kernel("+paramNames.toString()+") {";
286+
var originalHeader = CM_kernel.getLine(0);
287+
288+
if( kernelHeader != originalHeader ) {
289+
CM_kernel.replaceRange(kernelHeader, CodeMirror.Pos(0,0), CodeMirror.Pos(0, originalHeader.length), CM_doNotCancelOrigin);
290+
//CM_kernel.refresh();
291+
}
95292
}
96293

97294
//-------------------------------------------
@@ -132,11 +329,7 @@ function kernel(A,B) {
132329
}
133330

134331
// Block edits for first and last line
135-
CM_kernel.on('beforeChange', function(cm,change) {
136-
if( change.from.line <= 0 || cm.lineCount() - 1 <= change.to.line) {
137-
change.cancel();
138-
}
139-
});
332+
CM_kernel.on('beforeChange', CM_blockFirstAndLastLine);
140333

141334
// Setup the kernel sample click call
142335
$("#kernel_sample_btn").click(updateKernelSampleDisplay);
@@ -375,6 +568,7 @@ function kernel(A,B) {
375568

376569
// The various setup actual call
377570
setupInputNumbers();
571+
setupParameterGenerator();
378572
setupKernelEditor();
379573
setupBenchmarking();
380574

0 commit comments

Comments
 (0)