Skip to content
This repository was archived by the owner on Aug 15, 2019. It is now read-only.

Commit 8c5c730

Browse files
author
Nikhil Thorat
authored
Runnable code snippets in API reference. (#719)
Let there be runnable snippets!
1 parent 56a3325 commit 8c5c730

File tree

5 files changed

+154
-19
lines changed

5 files changed

+154
-19
lines changed

src/ops/array_ops.ts

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ export class Ops {
228228
/**
229229
* Creates a `Tensor` with all elements set to 1.
230230
*
231+
* ```js
232+
* dl.ones([2, 2]).print();
233+
* ```
234+
*
231235
* @param shape An array of integers defining the output tensor shape.
232236
* @param dtype The type of an element in the resulting tensor. Defaults to
233237
* 'float'.
@@ -242,6 +246,11 @@ export class Ops {
242246

243247
/**
244248
* Creates a `Tensor` with all elements set to 0.
249+
*
250+
* ```js
251+
* dl.zeros([2, 2]).print();
252+
* ```
253+
*
245254
* @param shape An array of integers defining the output tensor shape.
246255
* @param dtype The type of an element in the resulting tensor. Can
247256
* be 'float32', 'int32' or 'bool'. Defaults to 'float'.
@@ -257,6 +266,10 @@ export class Ops {
257266
/**
258267
* Creates a `Tensor` filled with a scalar value.
259268
*
269+
* ```js
270+
* dl.fill([2, 2], 4).print();
271+
* ```
272+
*
260273
* @param shape An array of integers defining the output tensor shape.
261274
* @param value The scalar value to fill the tensor with.
262275
* @param dtype The type of an element in the resulting tensor. Defaults to
@@ -276,6 +289,11 @@ export class Ops {
276289
/**
277290
* Creates a `Tensor` with all elements set to 1 with the same shape as the
278291
* given tensor.
292+
*
293+
* ```js
294+
* const x = dl.tensor([1, 2]);
295+
* dl.onesLike(x).print();
296+
* ```
279297
* @param x A tensor.
280298
*/
281299
@doc({heading: 'Tensors', subheading: 'Creation'})
@@ -288,6 +306,11 @@ export class Ops {
288306
* Creates a `Tensor` with all elements set to 0 with the same shape as the
289307
* given tensor.
290308
*
309+
* ```js
310+
* const x = dl.tensor([1, 2]);
311+
* dl.zerosLike(x).print();
312+
* ```
313+
*
291314
* @param x A tensor.
292315
*/
293316
@doc({heading: 'Tensors', subheading: 'Creation'})
@@ -299,6 +322,12 @@ export class Ops {
299322
/**
300323
* Creates a new tensor with the same values and shape as the specified
301324
* tensor.
325+
*
326+
* ```js
327+
* const x = dl.tensor([1, 2]);
328+
* x.clone().print();
329+
* ```
330+
*
302331
* @param x The tensor to clone.
303332
*/
304333
@doc({heading: 'Tensors', subheading: 'Creation'})
@@ -413,6 +442,11 @@ export class Ops {
413442
/**
414443
* Creates a `Tensor` with values drawn from a multinomial distribution.
415444
*
445+
* ```js
446+
* const probs = dl.tensor([.75, .25]);
447+
* dl.multinomial(probs, 3).print();
448+
* ```
449+
*
416450
* @param probabilities 1D array with normalized outcome probabilities, or
417451
* 2D array of shape `[batchSize, numOutcomes]`.
418452
* @param numSamples Number of samples to draw for each row slice.
@@ -719,6 +753,9 @@ export class Ops {
719753
/**
720754
* Return an evenly spaced sequence of numbers over the given interval.
721755
*
756+
* ```js
757+
* dl.linspace(0, 9, 10).print();
758+
* ```
722759
* @param start The start value of the sequence
723760
* @param stop The end value of the sequence
724761
* @param num The number of values to generate
@@ -797,6 +834,19 @@ export class Ops {
797834
* `buffer.set()`, or by modifying directly `buffer.values`. When done,
798835
* call `buffer.toTensor()` to get an immutable `Tensor` with those values.
799836
*
837+
* When done, call `buffer.toTensor()` to get an immutable `Tensor` with those
838+
* values.
839+
*
840+
* ```js
841+
* // Create a buffer and set values at particular indices.
842+
* const buffer = dl.buffer([2, 2]);
843+
* buffer.set(3, 0, 0);
844+
* buffer.set(5, 1, 0);
845+
*
846+
* // Convert the buffer back to a tensor.
847+
* buffer.toTensor().print();
848+
* ```
849+
*
800850
* @param shape An array of integers defining the output tensor shape.
801851
* @param dtype The dtype of the buffer. Defaults to 'float32'.
802852
* @param values The values of the buffer as `TypedArray`. Defaults to zeros.
@@ -816,20 +866,22 @@ export class Ops {
816866
*/
817867
@doc({heading: 'Tensors', subheading: 'Creation'})
818868
static print<T extends Tensor>(x: T, verbose = false): void {
819-
let displayName = Tensor.name;
820-
if (x.rank <= 4) {
821-
displayName =
822-
['Scalar', 'Tensor1D', 'Tensor2D', 'Tensor3D', 'Tensor4D'][x.rank];
823-
}
824-
825-
// Construct a new class so that we can display a rich object in the console
826-
// that only has the properties that we want to show about the tensor but
827-
// still shows it as if it's the proper class.
828-
const C = new Function(`return class ${displayName} {}`)();
869+
const C = class Tensor {
870+
shape: number[];
871+
data: number[];
872+
dtype: string;
873+
size: number;
874+
};
829875

830876
const displayTensor = new C();
831877
displayTensor.shape = x.shape;
832878
displayTensor.data = Array.from(x.dataSync());
879+
displayTensor.toString = function() {
880+
return `Tensor {\n` +
881+
` data: [${this.data.join(', ')}],\n` +
882+
` shape: [${x.shape.join(', ')}]\n` +
883+
`}`;
884+
};
833885

834886
if (verbose) {
835887
displayTensor.dtype = x.dtype;

src/ops/binary_ops.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export class Ops {
137137
*
138138
* ```js
139139
* const a = dl.tensor([[2, 2], [3, 3]])
140-
* const b = dl.tensor([[8, 16], [2, 3]])
140+
* const b = dl.tensor([[8, 16], [2, 3]]).toInt()
141141
* dl.pow(a, b).print(); // [256, 65536, 9, 27]
142142
* ```
143143
*

website/api/index.html

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<head>
2-
<script src="https://cdn.jsdelivr.net/npm/deeplearn@latest"></script>
2+
<script src="{{bundleJsPath}}"></script>
33
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.cyan-teal.min.css" />
44
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/railscasts.min.css">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -195,7 +195,7 @@
195195
margin-right: 0.33em;
196196
}
197197

198-
.documentation pre, .param-docs pre {
198+
.param-docs pre {
199199
background: #f4f4f4;
200200
}
201201

@@ -205,9 +205,11 @@
205205
}
206206

207207
pre.hljs {
208-
margin: 24px;
208+
padding: 24px;
209+
padding-bottom: 32px;
209210
/* margin-left: 24px; */
210-
padding: 0;
211+
margin: 0;
212+
background: white;
211213
}
212214

213215
code, .param-name, .return-type {
@@ -228,8 +230,6 @@
228230
font-family: Roboto Mono, monospace;
229231
}
230232

231-
232-
233233
.reference .symbol {
234234
margin-left: 32px;
235235
margin-bottom: 96px;
@@ -287,6 +287,26 @@
287287
font-size: 82%;
288288
}
289289

290+
.snippet-console {
291+
margin: -32px 24px 0 24px;
292+
min-height: 24px;
293+
position: relative;
294+
}
295+
296+
.snippet-console-log {
297+
border-radius: 8px;
298+
background: #f4f4f4;
299+
padding: 8px 16px;
300+
min-height: 16px;
301+
white-space: pre;
302+
font-family: "Roboto Mono", monospace;
303+
}
304+
305+
.snippet-run-button {
306+
position: absolute;
307+
right: 4px;
308+
top: 4px;
309+
}
290310
</style>
291311

292312
<script>
@@ -389,7 +409,6 @@
389409
{{/headings}}
390410
</div>
391411

392-
393412
<div class="reference">
394413
{{#headings}}
395414
<div class="section">
@@ -449,4 +468,49 @@ <h6>Methods:</h6>
449468
</div>
450469
</div>
451470
</div>
471+
<script>
472+
function executeCodeSnippet(consoleLogElement, codeSnippet) {
473+
consoleLogElement.innerText = '';
474+
475+
var oldLog = console.log;
476+
console.log = function(logStr) {
477+
consoleLogElement.innerText += logStr + '\n';
478+
};
479+
480+
var snippet = 'dl.tidy(function() {' + codeSnippet + '});';
481+
482+
eval(snippet);
483+
484+
console.log = oldLog;
485+
};
486+
487+
(function() {
488+
// Find all the code blocks.
489+
var jsBlocks = document.querySelectorAll('.language-js');
490+
for (var i = 0; i < jsBlocks.length; i++) {
491+
var block = jsBlocks[i];
492+
493+
var consoleElement = document.createElement('div');
494+
consoleElement.className = 'snippet-console';
495+
496+
var consoleRunElement = document.createElement('button');
497+
consoleRunElement.innerText = 'Run';
498+
consoleRunElement.className = 'snippet-run-button';
499+
500+
var consoleLogElement = document.createElement('div');
501+
consoleLogElement.className = 'snippet-console-log';
502+
503+
consoleElement.appendChild(consoleLogElement);
504+
consoleElement.appendChild(consoleRunElement);
505+
block.parentElement.insertAdjacentElement('afterend', consoleElement);
506+
507+
consoleRunElement.addEventListener('click', function() {
508+
var consoleLogElement =
509+
this.parentElement.querySelector('.snippet-console-log');
510+
var snippetText = this.parentElement.previousElementSibling.innerText;
511+
executeCodeSnippet(consoleLogElement, snippetText);
512+
});
513+
}
514+
})();
515+
</script>
452516
</body>

website/api/view.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
* =============================================================================
1616
*/
17-
export interface Docs { headings: DocHeading[]; }
17+
export interface Docs { headings: DocHeading[]; bundleJsPath: string;}
1818

1919
export interface DocHeading {
2020
name: string;

website/scripts/make-api.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,28 @@ const TOPLEVEL_NAMESPACE = 'dl';
3636
const API_TEMPLATE_PATH = './website/api/index.html';
3737
const HTML_OUT_DIR = '/tmp/deeplearn-new-website/api/';
3838

39+
const argv = minimist(process.argv.slice(2));
40+
3941
shell.mkdir('-p', HTML_OUT_DIR);
4042

43+
let bundleJsPath;
44+
if (argv['master']) {
45+
// When using --master, build a deeplearn.js bundle if it doesn't exist. This
46+
// is mainly for development.
47+
if (!fs.existsSync(HTML_OUT_DIR + 'deeplearn.js')) {
48+
shell.exec('./scripts/build-standalone.sh');
49+
shell.cp('./dist/deeplearn.js', HTML_OUT_DIR);
50+
}
51+
bundleJsPath = 'deeplearn.js';
52+
} else {
53+
// Read version and point to it.
54+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
55+
bundleJsPath = `https://cdn.jsdelivr.net/npm/deeplearn@${pkg.version}`;
56+
}
57+
console.log(`Using bundle path ${bundleJsPath}.`);
58+
4159
const {docs, docLinkAliases} = parser.parse();
60+
docs.bundleJsPath = bundleJsPath;
4261

4362
// Predefine some custom type links.
4463
const symbols: util.SymbolAndUrl[] = [

0 commit comments

Comments
 (0)