1+ < html >
2+ <!--
3+ Usage:
4+ http://localhost:8000/split-slice.html?op=split&splitNum=100&numRuns=100
5+ http://localhost:8000/split-slice.html?op=slice&splitNum=100&numRuns=100
6+ op = slice | split
7+ -->
8+ < style >
9+ body {
10+ font-family : sans-serif;
11+ }
12+ </ style >
13+
14+ < head >
15+ </ head >
16+
17+
18+ < body >
19+ < h1 > Split vs. Slice Benchmarking</ h1 >
20+ < p class ="text-lg-start ">
21+ < div id ="status " style ="font: 1em consolas; "> </ div >
22+ </ p >
23+ </ body >
24+
25+ < script >
26+ const opName = getQueryVariable ( "op" , "split" ) ;
27+ const numRuns = parseInt ( getQueryVariable ( "numRuns" , "100" ) ) ;
28+ const splitNum = parseInt ( getQueryVariable ( "splitNum" , "100" ) ) ;
29+ function log ( i ) {
30+ console . log ( i ) ; document . getElementById ( 'status' ) . innerText += `\n[${ performance . now ( ) . toFixed ( 3 ) } ] ` + i ;
31+ }
32+
33+ function getQueryVariable ( name , defaults ) {
34+ const query = window . location . search . substring ( 1 ) ;
35+ let vars = query . split ( "&" ) ;
36+ for ( var i = 0 ; i < vars . length ; i ++ ) {
37+ let pair = vars [ i ] . split ( "=" ) ;
38+ if ( pair [ 0 ] == name ) {
39+ return pair [ 1 ] ;
40+ }
41+ }
42+ return defaults ;
43+ }
44+
45+ async function run ( ) {
46+ const context = await navigator . ml . createContext ( { deviceType : 'gpu' } ) ;
47+ const builder = new MLGraphBuilder ( context ) ;
48+
49+ log ( "entering run ..." ) ;
50+
51+ try {
52+
53+ log ( `Build ${ opName } graph...` ) ;
54+ let graph ;
55+ if ( opName == 'split' ) {
56+ graph = await buildSplit ( builder ) ;
57+ } else {
58+ graph = await buildSlice ( builder ) ;
59+ }
60+
61+ log ( "Build done ..." ) ;
62+ const inputSize = 4 * splitNum * 56 * 56 ;
63+ const inputBuffer = new Float32Array ( inputSize ) ;
64+ for ( let i = 0 ; i < inputSize ; i ++ ) {
65+ inputBuffer [ i ] = i * 0.1 ;
66+ }
67+
68+ const inputs = { 'input' : inputBuffer . slice ( 0 ) } ;
69+ const outputs = { } ;
70+ for ( let i = 0 ; i < splitNum ; i ++ ) {
71+ outputs [ `output${ i } ` ] = new Float32Array ( 4 * 1 * 56 * 56 ) ;
72+ }
73+
74+ log ( "warmup by running once ..." ) ;
75+ let result = await context . compute ( graph , inputs , outputs ) ;
76+
77+ log ( `running ${ numRuns } times ...` ) ;
78+
79+ let inferTimes = [ ] ;
80+ for ( let i = 0 ; i < numRuns ; i ++ ) {
81+ const start = performance . now ( ) ;
82+ result = await context . compute ( graph , result . inputs , result . outputs ) ;
83+ inferTimes . push ( performance . now ( ) - start ) ;
84+ }
85+
86+ let intermediateTimings = "" ;
87+ for ( let i = 1 ; i < numRuns ; i ++ ) {
88+ intermediateTimings += `${ inferTimes [ i ] . toFixed ( 2 ) } , ` ;
89+ }
90+
91+ log ( intermediateTimings ) ;
92+
93+ const totalTime = inferTimes . reduce ( ( partialSum , a ) => partialSum + a , 0 ) ;
94+ const averageInferTime = `${ opName } [4, ${ splitNum } , 56, 56] / split into ${ splitNum } outputs along axis 1, ${ ( totalTime / numRuns ) . toFixed ( 2 ) } ms / iter` ;
95+ log ( averageInferTime ) ;
96+ } catch ( e ) {
97+ log ( e ) ;
98+ }
99+ }
100+
101+ async function buildSplit ( builder ) {
102+ const input = builder . input ( 'input' , {
103+ dataType : 'float32' ,
104+ type : 'float32' ,
105+ dimensions : [ 4 , splitNum , 56 , 56 ] ,
106+ } ) ;
107+ const splits = builder . split ( input , splitNum , { axis : 1 } ) ;
108+ const outputs = { } ;
109+ for ( let i = 0 ; i < splits . length ; i ++ ) {
110+ outputs [ `output${ i } ` ] = splits [ i ] ;
111+ }
112+ const startTime = performance . now ( ) ;
113+ const splitGraph = await builder . build ( outputs ) ;
114+ log ( `Build time: ${ ( performance . now ( ) - startTime ) . toFixed ( 2 ) } ms` ) ;
115+ return splitGraph ;
116+ }
117+
118+ async function buildSlice ( builder ) {
119+ const input = builder . input ( 'input' , {
120+ dataType : 'float32' ,
121+ type : 'float32' ,
122+ dimensions : [ 4 , splitNum , 56 , 56 ] ,
123+ } ) ;
124+ const outputs = { } ;
125+ let starts = [ 0 , 0 , 0 , 0 ] ;
126+ let sizes = [ 4 , 1 , 56 , 56 ] ;
127+ let start = 0 ;
128+ for ( let i = 0 ; i < splitNum ; i ++ ) {
129+ starts [ 1 ] = start ;
130+ outputs [ `output${ i } ` ] = builder . slice ( input , starts , sizes ) ;
131+ start ++ ;
132+ }
133+ const startTime = performance . now ( ) ;
134+ const sliceGraph = await builder . build ( outputs ) ;
135+ log ( `Build time: ${ ( performance . now ( ) - startTime ) . toFixed ( 2 ) } ms` ) ;
136+ return sliceGraph ;
137+ }
138+
139+ run ( ) ;
140+ </ script >
141+
142+ </ html >
0 commit comments