@@ -3,7 +3,10 @@ function demo() {
33 input : {
44 expression : "" ,
55 tensorOrders : { } ,
6- error : "" ,
6+ error : {
7+ message : "" ,
8+ delay : 0
9+ } ,
710 indices : [ ] ,
811 prefix : ""
912 } ,
@@ -25,69 +28,70 @@ function demo() {
2528
2629 addInputView : function ( newView ) {
2730 model . inputViews . push ( newView ) ;
28- newView ( 400 ) ;
31+ newView ( ) ;
2932 } ,
3033 updateInputViews : function ( ) {
3134 for ( v in model . inputViews ) {
32- model . inputViews [ v ] ( 400 ) ;
35+ model . inputViews [ v ] ( ) ;
3336 }
3437 } ,
3538 updateScheduleView : function ( ) {
3639 model . removeInvalidIndices ( ) ;
3740 model . removeInvalidAccesses ( ) ;
38- model . scheduleView ( 0 ) ;
41+ model . scheduleView ( ) ;
3942 } ,
4043 addExampleScheduleView : function ( newView ) {
4144 model . exampleScheduleViews . push ( newView ) ;
42- newView ( 0 ) ;
45+ newView ( ) ;
4346 } ,
4447 updateExampleScheduleViews : function ( ) {
4548 for ( v in model . exampleScheduleViews ) {
46- model . exampleScheduleViews [ v ] ( 0 ) ;
49+ model . exampleScheduleViews [ v ] ( ) ;
4750 }
4851 } ,
4952 addOutputView : function ( newView ) {
5053 model . outputViews . push ( newView ) ;
51- newView ( 0 ) ;
54+ newView ( ) ;
5255 } ,
5356 updateOutputViews : function ( ) {
5457 for ( v in model . outputViews ) {
55- model . outputViews [ v ] ( 0 ) ;
58+ model . outputViews [ v ] ( ) ;
5659 }
5760 } ,
5861 addReqView : function ( newView ) {
5962 model . reqViews . push ( newView ) ;
60- newView ( 0 ) ;
63+ newView ( ) ;
6164 } ,
6265 updateReqViews : function ( ) {
6366 for ( v in model . reqViews ) {
64- model . reqViews [ v ] ( 0 ) ;
67+ model . reqViews [ v ] ( ) ;
6568 }
6669 } ,
6770
68- setInput : function ( expression ) {
71+ setInput : function ( expression , errorDelay = 400 ) {
6972 model . cancelReq ( ) ;
7073 model . setOutput ( "" , "" , "" , "" ) ;
7174
7275 model . input . expression = expression ;
76+ model . input . error . delay = errorDelay ;
7377 if ( model . input . expression . length > 256 ) {
7478 model . input . tensorOrders = { } ;
75- model . input . error = "Input expression is too long" ;
79+ model . input . error . message = "Input expression is too long" ;
7680 } else {
7781 try {
7882 model . input . tensorOrders = parser . parse ( expression ) ;
7983 model . input . indices = [ ...new Set ( parser_indices . parse ( expression ) ) ] ;
80- model . input . error = "" ;
84+ model . input . error . message = "" ;
8185 for ( t in model . input . tensorOrders ) {
8286 if ( model . input . tensorOrders [ t ] < 0 ) {
8387 model . input . tensorOrders = { } ;
84- model . input . error = "Tensor " + t + " has inconsistent order" ;
88+ model . input . error . message = "Tensor " + t + " has inconsistent order" ;
8589 break ;
8690 }
8791 }
8892 } catch ( e ) {
8993 model . input . tensorOrders = { } ;
90- model . input . error = "Input expression is invalid" ;
94+ model . input . error . message = "Input expression is invalid" ;
9195 }
9296 }
9397 model . updateInputViews ( ) ;
@@ -116,9 +120,6 @@ function demo() {
116120 model . setReq ( null ) ;
117121 }
118122 } ,
119- getError : function ( ) {
120- return ( model . output . error !== "" ) ? model . output . error : model . input . error ;
121- } ,
122123
123124 setExampleSchedule : function ( e ) {
124125 model . exampleSchedule = e ;
@@ -267,15 +268,23 @@ function demo() {
267268 var txtExprView = {
268269 timerEvent : null ,
269270
270- updateView : function ( timeout ) {
271- clearTimeout ( txtExprView . timerEvent ) ;
272- if ( model . getError ( ) !== "" ) {
273- var markError = function ( ) {
274- $ ( "#lblError" ) . html ( model . getError ( ) ) ;
275- $ ( "#txtExpr" ) . parent ( ) . addClass ( 'is-invalid' ) ;
276- } ;
277- txtExprView . timerEvent = setTimeout ( markError , timeout ) ;
271+ updateView : function ( ) {
272+ if ( model . output . error !== "" ) {
273+ clearTimeout ( txtExprView . timerEvent ) ;
274+ txtExprView . timerEvent = null ;
275+ $ ( "#lblError" ) . html ( model . output . error ) ;
276+ $ ( "#txtExpr" ) . parent ( ) . addClass ( 'is-invalid' ) ;
277+ } else if ( model . input . error . message !== "" ) {
278+ if ( ! txtExprView . timerEvent ) {
279+ var markError = function ( ) {
280+ $ ( "#lblError" ) . html ( model . input . error . message ) ;
281+ $ ( "#txtExpr" ) . parent ( ) . addClass ( 'is-invalid' ) ;
282+ } ;
283+ txtExprView . timerEvent = setTimeout ( markError , model . input . error . delay ) ;
284+ }
278285 } else {
286+ clearTimeout ( txtExprView . timerEvent ) ;
287+ txtExprView . timerEvent = null ;
279288 $ ( "#txtExpr" ) . parent ( ) . removeClass ( 'is-invalid' ) ;
280289 }
281290 }
@@ -388,15 +397,15 @@ function demo() {
388397 return "" ;
389398 }
390399 } ,
391- updateView : function ( timeout ) {
400+ updateView : function ( ) {
392401 clearTimeout ( tblFormatsView . timerEvent ) ;
393- if ( model . getError ( ) !== "" ) {
402+ if ( model . input . error . message !== "" ) {
394403 var hideTables = function ( ) {
395404 $ ( "#tblFormats" ) . hide ( ) ;
396405 $ ( "#tblSchedule" ) . hide ( ) ;
397406 model . resetSchedule ( ) ;
398407 } ;
399- tblFormatsView . timerEvent = setTimeout ( hideTables , timeout ) ;
408+ tblFormatsView . timerEvent = setTimeout ( hideTables , model . input . error . delay ) ;
400409 } else {
401410 var listTensorsBody = "" ;
402411 for ( t in model . input . tensorOrders ) {
@@ -841,7 +850,7 @@ function demo() {
841850 return parameters ;
842851 } ,
843852
844- updateView : function ( timeout ) {
853+ updateView : function ( ) {
845854 var scheduleBody = "" ;
846855 for ( var r = 0 ; r < model . schedule . length ; ++ r ) {
847856 var rowId = "schedule" + r ;
@@ -983,7 +992,7 @@ function demo() {
983992 model . scheduleView = tblScheduleView . updateView ;
984993
985994 var btnExampleScheduleView = {
986- updateView : function ( timeout ) {
995+ updateView : function ( ) {
987996 if ( model . exampleSchedule . length === 0 ) {
988997 $ ( "#btnCPU" ) . hide ( ) ;
989998 $ ( "#btnGPU" ) . hide ( ) ;
@@ -1000,8 +1009,8 @@ function demo() {
10001009 model . addExampleScheduleView ( btnExampleScheduleView . updateView ) ;
10011010
10021011 var btnGetKernelView = {
1003- updateView : function ( timeout ) {
1004- $ ( "#btnGetKernel" ) . prop ( 'disabled' , model . input . error !== "" || model . req ) ;
1012+ updateView : function ( ) {
1013+ $ ( "#btnGetKernel" ) . prop ( 'disabled' , model . input . error . message !== "" || model . req ) ;
10051014 if ( model . req ) {
10061015 $ ( "#btnGetKernel" ) . addClass ( "is-loading" ) ;
10071016 } else {
@@ -1014,14 +1023,14 @@ function demo() {
10141023 model . addInputView ( tblFormatsView . updateView ) ;
10151024 model . addInputView ( btnGetKernelView . updateView ) ;
10161025
1017- $ ( "#txtExpr" ) . keyup ( function ( ) {
1026+ $ ( "#txtExpr" ) . on ( "input" , function ( ) {
10181027 model . setInput ( $ ( "#txtExpr" ) . val ( ) ) ;
10191028 model . resetSchedule ( ) ;
10201029 model . setExampleSchedule ( "" ) ;
10211030 } ) ;
10221031
10231032 var panelKernelsView = {
1024- updateView : function ( timeout ) {
1033+ updateView : function ( ) {
10251034 var computeLoops = ( model . output . computeLoops === "" ) ?
10261035 "/* The generated compute code will appear here */" :
10271036 model . output . computeLoops . replace ( / < / g, "<" ) ;
@@ -1044,7 +1053,7 @@ function demo() {
10441053 } ;
10451054
10461055 var btnDownloadView = {
1047- updateView : function ( timeout ) {
1056+ updateView : function ( ) {
10481057 if ( model . output . fullCode === "" ) {
10491058 $ ( "#btnDownload" ) . hide ( ) ;
10501059 $ ( "#btnDownload" ) . parent ( ) . css ( "width" , "0px" ) ;
@@ -1241,8 +1250,11 @@ function demo() {
12411250 } ;
12421251
12431252 var inited = false ;
1253+ var validInit = true ;
12441254 var expr = getURLParam ( "expr" ) ;
12451255 if ( expr !== "" ) {
1256+ inited = true ;
1257+
12461258 var formats = getURLParam ( "format" ) . split ( ";" ) ;
12471259 for ( var f in formats ) {
12481260 var [ tensor , levelFormats , ordering ] = formats [ f ] . split ( ":" ) ;
@@ -1255,23 +1267,32 @@ function demo() {
12551267 }
12561268
12571269 expr = expr . replaceAll ( "%20" , " " ) ;
1258- model . setInput ( expr ) ;
1270+ model . setInput ( expr , 0 ) ;
12591271 $ ( "#txtExpr" ) . val ( expr ) ;
1260- inited = ( model . error == null ) ;
1261-
1262- var schedule = [ ] ;
1263- var scheduleString = getURLParam ( "sched" ) ;
1264- if ( scheduleString !== "" ) {
1265- var commands = scheduleString . split ( ";" ) ;
1266- for ( var c in commands ) {
1267- var [ transform , ...args ] = commands [ c ] . split ( ":" ) . map ( function ( x ) {
1268- return x . replaceAll ( "%20" , " " ) ;
1269- } ) ;
1270- command = { command : transform , parameters : args } ;
1271- schedule . push ( command ) ;
1272+ validInit = ( model . input . error . message === "" ) ;
1273+
1274+ if ( validInit ) {
1275+ var schedule = [ ] ;
1276+ var scheduleString = getURLParam ( "sched" ) ;
1277+ if ( scheduleString !== "" ) {
1278+ var commands = scheduleString . split ( ";" ) ;
1279+ for ( var c in commands ) {
1280+ var [ transform , ...args ] = commands [ c ] . split ( ":" ) . map ( function ( x ) {
1281+ return x . replaceAll ( "%20" , " " ) ;
1282+ } ) ;
1283+ command = { command : transform , parameters : args } ;
1284+ if ( ! scheduleCommands . hasOwnProperty ( transform ) ) {
1285+ model . setOutput ( "" , "" , "" , "Invalid scheduling command: " + transform ) ;
1286+ validInit = false ;
1287+ break ;
1288+ }
1289+ schedule . push ( command ) ;
1290+ }
1291+ }
1292+ if ( validInit ) {
1293+ model . setSchedule ( schedule ) ;
12721294 }
12731295 }
1274- model . setSchedule ( schedule ) ;
12751296 }
12761297
12771298 var demo = getURLParam ( "demo" ) ;
@@ -1304,7 +1325,9 @@ function demo() {
13041325 }
13051326
13061327 if ( inited ) {
1307- getKernel ( ) ;
1328+ if ( validInit ) {
1329+ getKernel ( ) ;
1330+ }
13081331 } else {
13091332 var urlPrefix = "http://tensor-compiler.org/examples/" + demo ;
13101333 var computeGet = $ . get ( urlPrefix + "_compute.c" ) ;
0 commit comments