Ignore:
Timestamp:
07/03/18 01:05:04 (7 years ago)
Author:
dlcheng
Message:

CHG (JS): Updating js processing scripts.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/m/classes/clusters/generic.js

    r21911 r22894  
    1 //GENERIC class definition
    2 //
    3 //   Usage:
    4 //      generic=new generic();
     1// Execute script in strict mode
     2'use strict';
     3/**
     4 * generic - Class that allows for sending requests to server and handling response or errors
     5 *
     6 *      Usage:
     7 *              generic = new generic();
     8 *
     9 *      Todo:
     10 *              Convert to ES6 class
     11 */
     12function generic() {
     13        // Retrieve options and apply to properties
     14        // {{{
     15        let args        = Array.prototype.slice.call(arguments);
     16        let options = new pairoptions(args.slice(0, args.length));
     17       
     18        this.url                        = options.getfieldvalue('url', '');
     19        this.np                         = options.getfieldvalue('np', 3);
     20        this.codeversion        = options.getfieldvalue('codeversion', 20486);
     21        this.codepath           = options.getfieldvalue('codepath', 'issmdir/bin');
     22        this.executionpath      = options.getfieldvalue('executionpath', 'issmdir/execution');
     23        //}}}
     24       
     25       
     26        // Methods
     27        //{{{
     28        this.disp = function() { //{{{
     29                console.log(sprintf('   generic class echo:'));
     30                console.log(sprintf('    url: %s', this.url));
     31                console.log(sprintf('    np: %i', this.np));
     32                console.log(sprintf('    codepath: %s', this.codepath));
     33                console.log(sprintf('    executionpath: %s', this.executionpath));
     34        }; //}}}
     35       
     36        this.classname = function() { //{{{
     37                return 'generic';
     38        }; //}}}
     39       
     40        this.checkconsistency = function(md, solution, analyses) { //{{{
     41                if (cluster.np < 1) {
     42                        md.checkmessage('Number of processors should be at least 1!');
     43                }
     44                if (isNaN(cluster.np)) {
     45                        md.checkmessage('Number of processors NaN!');
     46                }
     47        }; //}}}
     48       
     49        this.BuildQueueScript = function(cluster, dirname, modelname, solution, io_gather, isvalgrind, isgprof, isdakota) { //{{{
     50                //write queuing script
     51                //what is the executable being called?
     52                executable      = 'issm.exe';
     53               
     54                fid             = fopen(modelname + '.queue','w');
     55                fprintf(fid, '#!%s\n', cluster.shell);
     56                fprintf(fid, 'mpiexec -np %i %s/%s %s %s %s 2> %s.errlog >%s.outlog ', cluster.np, cluster.codepath, executable, EnumToString(solution), cluster.executionpath + '/' + dirname, modelname, modelname, modelname);                                       
     57                fclose(fid);
     58        }; //}}}
     59       
     60        this.UploadAndRun = function(md, fid, toolkitsstring, solutionstring, name, runtimename, successCallback, errorCallback, solveButtonId, callout, withProgressBar) { //{{{
     61                /* Local constants */
     62                let PROGRESS_BAR_ID                             = 'solve-progress-bar';
     63                let PROGRESS_BAR_TEXT_PERCENTAGE_ID = 'progress-bar-text-percentage';           
     64               
     65                /* Local variables */
     66                let hasCallout                                  = false;
     67                let isProgressBarLoaded                 = false;
     68                let progressBar                                 = {};
     69                let progressBarTextPercentage   = {};
     70                let request                                     = {};
     71                let solveButton                                 = $(solveButtonId);
     72                let solveButtonText                     = !vesl.helpers.isEmptyOrUndefined(solveButton) ? solveButton.text() : ''; // Save initial solve button text
     73               
     74                /* Local functions */
     75                // NOTE: After conversion of generic to ES6 class, these should be class methods
     76                function loadProgressBar() {
     77                        callout.setContent('\
     78                                <div class="progress-bar-wrapper">\
     79                                        <progress id="' + PROGRESS_BAR_ID + '" value="0" max="100"></progress>\
     80                                        <div class="progress-bar-text">\
     81                                                <span id="' + PROGRESS_BAR_TEXT_PERCENTAGE_ID + '">0</span>\
     82                                                <span>%</span>\
     83                                        </div>\
     84                                </div>\
     85                        ');
     86                       
     87                        progressBar                             = $('#' + PROGRESS_BAR_ID);
     88                        progressBarTextPercentage       = $('#' + PROGRESS_BAR_TEXT_PERCENTAGE_ID);
     89                        isProgressBarLoaded             = true;
     90                }
     91               
     92                function setProgressBar(progress) {
     93                        progressBar.val(progress);
     94                        progressBarTextPercentage.text(progress);
     95                }
     96               
     97                // Check certain arguments
     98                hasCallout = !vesl.helpers.isEmptyOrUndefined(callout);         
     99               
     100                // Check that we have a connection
     101                if (!navigator.onLine) {
     102                        console.log('Error: no connection!');
     103                        if (hasCallout) {
     104                                callout.set('No connection!', '');
     105                        } else {
     106                                solveButton.text('No connection!').prop('disabled', false);
     107                        }
     108                        errorCallback();
     109                        return;
     110                }
     111               
     112                // Create request
     113                request = new XMLHttpRequest();
     114                request.open('POST', this.url, true);
     115               
     116                // Set request properties
     117                request.position        = 0; // Keep track of current parsing position in repsonseText
     118                request.timeout         = 1000 * 60 * 60 * 3; // 3 hrs (in milliseconds); NOTE: This should match FastCgiServer timeout in Apache conf
     119               
     120                request.ontimeout = function(event) { //{{{
     121                        console.log('Error: timeout!');
     122                       
     123                        if (hasCallout) {
     124                                callout.set(vesl.ERROR_HEADER_GENERAL, '<p>Request timeout! ' + vesl.ERROR_CONTENT_TRY_AGAIN + '</p>');
     125                        } else {
     126                                solveButton.text('Timeout!').prop('disabled', false);
     127                        }
     128                       
     129                        errorCallback();
     130                }; //}}}
     131               
     132                request.onerror = function(event) { //{{{
     133                        console.log('Error: could not run!');
     134                       
     135                        if (hasCallout) {
     136                                callout.set(vesl.ERROR_HEADER_GENERAL, '<p>Something went wrong. ' + vesl.ERROR_CONTENT_TRY_AGAIN + '</p>');
     137                        } else {
     138                                solveButton.text('Could not run!').prop('disabled', false);
     139                        }
     140                       
     141                        errorCallback();
     142                }; //}}}
     143               
     144                request.upload.onprogress = function(event) { //{{{
     145                        let progress = (event.loaded / event.total * 100).toFixed(0);
     146                       
     147                        if (hasCallout) {
     148                                callout.setHeader('Sending request...');
     149                                if (withProgressBar) {
     150                                        if (!isProgressBarLoaded) {
     151                                                loadProgressBar();
     152                                        }
     153                                        setProgressBar(progress);
     154                                } else {
     155                                        callout.setContent('<p>' + progress + '%</p>');
     156                                }
     157                        } else {
     158                                solveButton.text('Sending: ' + progress + '%');
     159                        }
     160        }; //}}}
     161       
     162                request.onprogress = function(event) { //{{{
     163                        /* Local variables */
     164                        let progress    = 0;
    5165
    6 function generic (){
    7         //properties
    8         // {{{
    9         var args = Array.prototype.slice.call(arguments);
    10         var options = new pairoptions(args.slice(0,args.length));
     166                        // Receive updates by parsing message length as a 32-bit hex string of form 0x*09ABCDEF))
     167                        let startIndex  = request.position;
     168                        let endIndex    = request.position + 10;
     169                       
     170                        if (request.responseText.length >= endIndex) { // Ensure entire hex string is loaded
     171                                let chunkSize = parseInt(request.responseText.slice(startIndex, endIndex));
     172                               
     173                                startIndex      = endIndex;
     174                                endIndex        = startIndex + chunkSize;
     175                               
     176                                if (chunkSize >= 1024) { // Arbitrary maximium size of message (Must be below minimium size of model results)
     177                                        progress = ((request.responseText.length - request.position) / chunkSize * 100).toFixed(0);
     178                                        if (hasCallout) {
     179                                                callout.setHeader('Downloading result...');
     180                                                if (withProgressBar) {
     181                                                        setProgressBar(progress);
     182                                                } else {
     183                                                        callout.setContent('<p>' + progress + '%</p>');
     184                                                }
     185                                        } else {
     186                                                solveButton.text('Downloading: ' + progress + '%').prop('disabled', true);
     187                                        }
     188                                } else if (request.responseText.length >= endIndex) { // Ensure entire chunk is loaded
     189                                        progress = parseInt(request.responseText.slice(startIndex, endIndex));
     190                                        if (hasCallout) {
     191                                                callout.setHeader('Computing...');
     192                                                if (withProgressBar) {
     193                                                        setProgressBar(progress);
     194                                                } else {
     195                                                        callout.setContent('<p>' + progress + '%</p>');
     196                                                }
     197                                        } else {
     198                                                solveButton.text('Computing: ' + progress + '%').prop('disabled', true);
     199                                        }
     200                                        request.position = endIndex;
     201                                }
     202                        }
     203                }; //}}}
     204               
     205                request.onload = function(event) { //{{{
     206                        /* Local variables */
     207                        //{{{
     208                        let buffer                              = {};
     209//                      let bufferInflated              = {};
     210                        let responseText                = '';
     211                        //}}}
     212                       
     213                        // TODO: Get context to this.str2ab or otherwise declare it in order to avoid duplication
     214                        function str2ab(str) { //{{{
     215                                let buffer = new Uint8Array(str.length);
     216                                for (let i = 0, strLen = str.length; i < strLen; ++i) {
     217                                        buffer[i] = str.charCodeAt(i);
     218                                }
     219                                return buffer;
     220                        } //}}}
     221                       
     222                        try {
     223/*
     224                                console.log(request.responseText);
     225                                console.log('request.position : ' + request.position);
     226                                console.log('request.responseType : ' + request.responseType);
     227                                console.log('request.responseText.length : ' + request.responseText.length);
     228*/
     229                                responseText    = window.atob(request.responseText.slice(request.position + 10).replace(/\s/g, ''));
     230//                              console.log('responseText.length : ' + responseText.length);
     231                                buffer                  = str2ab(responseText);
     232//                              console.log('buffer.length : ' + buffer.length);
     233/*
     234                    bufferInflated      = UZIP.inflate(buffer);
     235                                console.log('bufferInflated.length : ' + bufferInflated.length);
     236*/
     237                   
     238/*
     239                                returnBuffer            = new Uint8Array(buffer);
     240                                returnBufferSize        = returnBuffer.byteLength;
     241*/
     242                       
     243                                //Write result buffer to file for debugging. Filename and MIME type are optional.
     244                                //writetofile(returnBuffer, 'resultBuffer', 'application/octet-stream');
     245//                              md.results = parseresultsfrombuffer(md, bufferInflated, bufferInflated.length);
     246                                md.results = parseresultsfrombuffer(md, buffer, buffer.length);
     247                               
     248                                // Let front end script handle changes to callout
     249                                if (hasCallout) {
     250                                        callout.set('Success!', '<p>Solve successful</p>');
     251                                } else {
     252                                        solveButton.text(solveButtonText).prop('disabled', false);
     253                                }
     254                                successCallback();
     255                        } catch (e) {
     256                                console.log(e);
     257                                if (vesl.string.startsWith(responseText, 'Error')) {
     258                                        if (hasCallout) {
     259                                                callout.set(vesl.ERROR_HEADER_GENERAL, '<p>Something went wrong. ' + vesl.ERROR_CONTENT_TRY_AGAIN + '</p>');
     260                                        } else {
     261                                                solveButton.text('ISSM error!').prop('disabled', false);
     262                                        }
     263                                } else {
     264                                        if (hasCallout) {
     265                                                callout.set(vesl.ERROR_HEADER_GENERAL, '<p>Something went wrong. ' + vesl.ERROR_CONTENT_TRY_AGAIN + '</p>');
     266                                        } else {
     267                                                solveButton.text('JS error!').prop('disabled', false);
     268                                        }
     269                                }
     270                                errorCallback();
     271                        }
     272                }; //}}}
     273               
     274                request.responseType = 'application/octet-stream';
     275               
     276                /* Construct request */
     277                let npbuffer = this.str2ab(md.cluster.np.toString());
     278                npbuffer = UZIP.deflate(npbuffer);
     279                let nplength = new Uint32Array(1);
     280                nplength[0] = npbuffer.byteLength;
     281               
     282                let codeversionbuffer = this.str2ab(md.cluster.codeversion.toString());
     283                codeversionbuffer = UZIP.deflate(codeversionbuffer);
     284                let codeversionlength = new Uint32Array(1);
     285                codeversionlength[0] = codeversionbuffer.byteLength;
     286               
     287                let runtimenamebuffer = this.str2ab(runtimename);
     288                runtimenamebuffer = UZIP.deflate(runtimenamebuffer);
     289                let runtimenamelength = new Uint32Array(1);
     290                runtimenamelength[0] = runtimenamebuffer.byteLength;
     291               
     292                let namebuffer = this.str2ab(name);
     293                namebuffer = UZIP.deflate(namebuffer);
     294                let namelength = new Uint32Array(1);
     295                namelength[0] = namebuffer.byteLength;
     296               
     297                let toolkitsbuffer = this.str2ab(toolkitsstring);
     298                toolkitsbuffer = UZIP.deflate(toolkitsbuffer);
     299                let toolkitslength = new Uint32Array(1);
     300                toolkitslength[0] = toolkitsbuffer.byteLength;
     301               
     302                let solutionbuffer = this.str2ab(solutionstring);
     303                solutionbuffer = UZIP.deflate(solutionbuffer);
     304                let solutionlength = new Uint32Array(1);
     305                solutionlength[0] = solutionbuffer.byteLength;
     306               
     307                let binbuffer = new Uint8Array(fid.rawbuffer()); //seems that 16 bits length could be incompatible.
     308                binbuffer = UZIP.deflate(binbuffer);
     309                let binlength = new Uint32Array(1);
     310                binlength[0] = binbuffer.byteLength;
     311               
     312                let data = new Blob(
     313                        [
     314                                nplength,
     315                                npbuffer,
     316                                codeversionlength,
     317                                codeversionbuffer,
     318                                runtimenamelength,
     319                                runtimenamebuffer,
     320                                namelength,
     321                                namebuffer,
     322                                toolkitslength,
     323                                toolkitsbuffer,
     324                                solutionlength,
     325                                solutionbuffer,
     326                                binlength,
     327                                binbuffer
     328                        ]
     329                );
    11330
    12         this.url=options.getfieldvalue('url','');
    13         this.np=options.getfieldvalue('np',3);
    14         this.codeversion=options.getfieldvalue('codeversion',20486);
    15         this.codepath=options.getfieldvalue('codepath','issmdir/bin');
    16         this.executionpath=options.getfieldvalue('executionpath','issmdir/execution');
    17         //}}}
    18         //methods
    19         this.disp= function(){// {{{
    20                 console.log(sprintf('   generic class echo:'));
    21                 console.log(sprintf('    url: "%s"',this.url));
    22                 console.log(sprintf('    np: %i',this.np));
    23                 console.log(sprintf('    codepath: "%s"',this.codepath));
    24                 console.log(sprintf('    executionpath: "%s"',this.executionpath));
    25         }// }}}
    26         this.classname= function(){// {{{
    27                 return "generic";
    28         }// }}}
    29         this.checkconsistency = function (md,solution,analyses) { //{{{
    30                 if (cluster.np<1){
    31                         md.checkmessage('number of processors should be at least 1');
    32                 }
    33                 if (isNaN(cluster.np)){
    34                         md.checkmessage('number of processors should not be NaN!');
    35                 }
    36         } //}}}
    37         this.BuildQueueScript = function (cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota) { // {{{
    38 
    39                         //write queuing script
    40                         //what is the executable being called?
    41                         executable='issm.exe';
    42 
    43                         fid=fopen(modelname+'.queue','w');
    44                         fprintf(fid,'#!%s\n',cluster.shell);
    45                         fprintf(fid,'mpiexec -np %i %s/%s %s %s %s 2> %s.errlog >%s.outlog ',cluster.np,cluster.codepath,executable,EnumToString(solution),cluster.executionpath+'/'+dirname,modelname,modelname,modelname);                                   
    46                         fclose(fid);
    47         } //}}}
    48         this.UploadAndRun = function (md,callbackfunction,callbackerrorfunction,callbackid,fid,toolkitsstring,solutionstring,name,runtimename) { //{{{
    49                 if (!navigator.onLine) { //{{{
    50                         $(callbackid).html(sprintf("%-16s", "NO CONNECTION")).prop("disabled", false);
    51                         callbackerrorfunction();
    52                         return;
    53                 } //}}}
    54                 var request = new XMLHttpRequest();
    55                 request.open("POST", this.url, true);
    56                 $(callbackid).html(sprintf("%-16s", "CONNECTING...")).prop("disabled", true);
    57                 request.position = 0; //Keep track of current parsing position in repsonseText
    58                 request.timeout = 180000;
    59                 request.ontimeout = function (event) { //{{{
    60                         $(callbackid).html(sprintf("%-16s", "TIMEOUT")).prop("disabled", false);
    61                         callbackerrorfunction();
    62                 } //}}}
    63                 request.onerror = function (event) { //{{{
    64                         $(callbackid).html(sprintf("%-16s", "COULD NOT RUN")).prop("disabled", false);
    65                         callbackerrorfunction();
    66                 } //}}}
    67                 request.upload.onprogress = function(event) { //{{{
    68                         var progress = (event.loaded / event.total * 100).toFixed(0);
    69                         $(callbackid).html(sprintf("%-20s", "UPLOADING: " + progress + "%"));
    70         } //}}}
    71                 request.onprogress = function (event) { //{{{
    72                         //Receive updates by parsing message length as a 32-bit hex string of form 0x*09ABCDEF))
    73                         var startIndex = request.position;
    74                         var endIndex = request.position + 10;
    75                         if (request.responseText.length >= endIndex) { //Ensure entire hex string is loaded
    76                                 var chunkSize = parseInt(request.responseText.slice(startIndex, endIndex));
    77                                 startIndex = endIndex;
    78                                 endIndex = startIndex + chunkSize;
    79                                 if (chunkSize >= 1024) { //Arbitrary maximium size of message (Must be below minimium size of model results)
    80                                         $(callbackid).html(sprintf("%-20s", "DOWNLOADING: " + ((request.responseText.length - request.position) / chunkSize * 100).toFixed(0) + "%")).prop("disabled", true);
    81                                 }
    82                                 else if (request.responseText.length >= endIndex) { //Ensure entire chunk is loaded
    83                                         var responseChunk = request.responseText.slice(startIndex, endIndex);
    84                                         $(callbackid).html(responseChunk);
    85                                         request.position = endIndex;
    86                                 }
    87                         }
    88                 }; //}}}
    89                 request.onload = function (event) { //{{{
    90                         //get context to this.str2ab to avoid duplciation
    91                         function str2ab(str) {
    92                                 var buf = new Uint8Array(str.length);
    93                                 for (var i=0, strLen=str.length; i < strLen; i++) {
    94                                         buf[i] = str.charCodeAt(i);
    95                                 }
    96                                 return buf;
    97                         }
    98                         var responseText = window.atob(request.responseText.slice(request.position + 10).replace(/\s/g, ''));
    99             var buffer = pako.inflate(str2ab(responseText));
    100                         var returnBuffer = new Uint8Array(buffer);
    101                         var returnBuffer_size = returnBuffer.byteLength;
    102                         try {
    103                                 //Write result buffer to file for debugging. Filename and MIME type are optional.
    104                                 //writetofile(returnBuffer, "resultBuffer", "application/octet-stream");
    105                                 md.results = parseresultsfrombuffer(md,returnBuffer,returnBuffer_size);
    106                                 $(callbackid).html(sprintf("%-16s", "RUN")).prop("disabled", false);
    107                                 callbackfunction();
    108                         }
    109                         catch (e) {
    110                                 if (responseText.startsWith('Error')) {
    111                                         console.log(responseText);
    112                                         $(callbackid).html(sprintf("%-16s", "ISSM ERROR")).prop("disabled", false);
    113                                 }
    114                                 else {
    115                                         $(callbackid).html(sprintf("%-16s", "JS ERROR")).prop("disabled", false);
    116                                         console.log(e);
    117                                 }
    118                                 callbackerrorfunction();
    119                         }
    120                        
    121                 }; //}}}
    122                
    123                 var npbuffer = this.str2ab(md.cluster.np.toString());
    124                 npbuffer = pako.deflate(npbuffer);
    125                 var nplength = new Uint32Array(1);
    126                 nplength[0] = npbuffer.byteLength;
    127                
    128                 var codeversionbuffer = this.str2ab(md.cluster.codeversion.toString());
    129                 codeversionbuffer = pako.deflate(codeversionbuffer);
    130                 var codeversionlength = new Uint32Array(1);
    131                 codeversionlength[0] = codeversionbuffer.byteLength;
    132                
    133                 var runtimenamebuffer = this.str2ab(runtimename);
    134                 runtimenamebuffer = pako.deflate(runtimenamebuffer);
    135                 var runtimenamelength = new Uint32Array(1);
    136                 runtimenamelength[0] = runtimenamebuffer.byteLength;
    137                
    138                 var namebuffer = this.str2ab(name);
    139                 namebuffer = pako.deflate(namebuffer);
    140                 var namelength = new Uint32Array(1);
    141                 namelength[0] = namebuffer.byteLength;
    142                
    143                 var toolkitsbuffer = this.str2ab(toolkitsstring);
    144                 toolkitsbuffer = pako.deflate(toolkitsbuffer);
    145                 var toolkitslength = new Uint32Array(1);
    146                 toolkitslength[0] = toolkitsbuffer.byteLength;
    147                
    148                 var solutionbuffer = this.str2ab(solutionstring);
    149                 solutionbuffer = pako.deflate(solutionbuffer);
    150                 var solutionlength = new Uint32Array(1);
    151                 solutionlength[0] = solutionbuffer.byteLength;
    152                
    153                 var binbuffer = new Uint8Array(fid.rawbuffer()); //seems that 16 bits length could be incompatible.
    154                 binbuffer = pako.deflate(binbuffer);
    155                 var binlength = new Uint32Array(1);
    156                 binlength[0] = binbuffer.byteLength;
    157                
    158                 var data = new Blob([nplength,npbuffer,codeversionlength,codeversionbuffer,runtimenamelength,runtimenamebuffer,namelength,namebuffer,toolkitslength,toolkitsbuffer,solutionlength,solutionbuffer,binlength,binbuffer]);
    159                
    160                 request.responseType = 'application/octet-stream';
     331                // Send request
    161332                request.send(data);
    162333               
    163         } //}}}
     334                if (hasCallout) {
     335                        callout.set('Connecting...', '');
     336                } else {
     337                        solveButton.text('Connecting...').prop('disabled', true);
     338                }
     339        }; //}}}
     340       
    164341        this.ab2str = function(buf) { //{{{
    165342                return String.fromCharCode.apply(null, new Uint16Array(buf));
    166         } //}}}
     343        }; //}}}
     344       
    167345        this.str2ab = function(str) { //{{{
    168                 var buf = new Uint8Array(str.length);
    169                 for (var i=0, strLen=str.length; i < strLen; i++) {
     346                let buf = new Uint8Array(str.length);
     347               
     348                for (let i = 0, strLen = str.length; i < strLen; i++) {
    170349                        buf[i] = str.charCodeAt(i);
    171350                }
     351               
    172352                return buf;
    173         } //}}}
     353        }; //}}}
    174354}
Note: See TracChangeset for help on using the changeset viewer.