i4SMQ

                In particular, he completely sold out
                (within four days) a batch of (20000 x 700 $)
                of safe flamethrowers (for the case of a
                zombie apocalypse) ..

                Elon Musk ..,
                https://lenta.ru/news/2018/04/26/cyborg/
                https://lenta.ru/news/2018/02/01/flamesoflove/

i52-i55 session plan:

Day I.   Windows Subsystem for Linux (RedStone 4), JSLinux, WebAssembly.
Day II.  Docker for Ubuntu. Fedora 28.
Day III. Sabade likvideerimine. Kokkuvõte.

             ---===<<< DAY I >>>===---

RedStone IV, Native Container WSL, Benchmarks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  https://docs.microsoft.com/en-us/windows/wsl/install-win10

GUI

  Control Panel -> Programs and Features ->
    Turn Windows Features On or Off -> Windows Subsystem for Linux.

PowerShell as Administrator and run:

  PS C:\WINDOWS\system32> Enable-WindowsOptionalFeature \
                          -Online -FeatureName \
                          Microsoft-Windows-Subsystem-Linux

Windows Store: Search Ubuntu: Get it, Launch.

Ubuntu Bionic 18.04LTS Released
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Step I. VirtualBox / Install
............................

  ISO:   ubuntu-18.04-desktop-amd64.iso
  CPU:   4 cores
  RAM:   4096MB
  HDD:   20GB Sata
  VIDEO: 128GB 3-D accelerated

minimal installation: web browser and basic utilities.
erase disk and install ubuntu
virtu/virtu on UBOX log in automatically

5 minutes later..

Terminal: Add to favorites, Font Monospace 14

  # apt-get update
  # apt-get upgrade
  # apt-get clean
  # echo "dd if=/dev/zero of=biig; rm biig" > /usr/local/bin/c
  # chmod 755 /usr/local/bin/c

Software & Updates -> Updates -> Automatically check for updates: Never

Backed up as:

  Bionic-20GB-i4Sinit.7z 4458MB 1010MB

Step II. Compile and CrossCompile
.................................

  # apt-get install openssh-server

Add port forwarding rule for VirtualBox if in NAT

  # apt-get install build-essential mingw-w64 binutils-mingw-w64 vim
  134MB / 776MB

where

mingw-w64 - Development environment targeting 32- and 64-bit Windows
binutils-mingw-w64 - Cross-binutils for Win32 and Win64 using MinGW-w64

NOTE: VirtualBox 5.2.8 guest-additions kills boot (5.2.10 works fine)

Step III. WebAssembly
.....................

  Follow this:

    https://codelabs.developers.google.com/codelabs/web-assembly-intro
          /index.html?index=..%2F..%2Findex#0

  # apt-get install python2.7 python-minimal nodejs cmake default-jre
  54 / 246MB
  # apt-get install git
  5 / 34MB
  $ cd ~
  $ git clone https://github.com/juj/emsdk.git
  $ cd emsdk
  $ git pull
  $ ./emsdk install latest
  $ ./emsdk activate latest
  $ source ./emsdk_env.sh

Step IV. Game of Life. Based on [1]
...................................

  $ ed lyff.c
  $ ed build.sh
  $ ed index.html
  $ chmod 755 build.sh
  $ ./build.sh
  $ python -m SimpleHTTPServer
  firefox [ localhost:8000 ]

Backed up as:

  BIONIC-20GB-i4Sa.7z 5.999GB 1.382GB

Step V. Mandelbrot
------------------

Install apache2

Download and build [2] (see ^Links:) in some public location, lets say

  /var/www/html/mbrot

Read here:

  https://groups.google.com/forum/#!topic/emscripten-discuss/C7-i1gqWay4

Do this:

  # cat /etc/apache2/mods-available/mime.conf | grep wasm
      #
      AddType application/wasm .wasm
      AddOutputFilterByType DEFLATE application/wasm

Restart apache2

  # service apache2 restart

Read here:

  https://groups.google.com/forum/#!topic/emscripten-discuss/avogJZbxrwU

Do this:

  # cat Makefile | grep -A4 'em++'
      em++ --bind --std=c++11 mandelbrot.cpp -s WASM=1 \
           -s ALLOW_MEMORY_GROWTH=1 \
           -s "EXTRA_EXPORTED_RUNTIME_METHODS=['addOnPostRun']" \
           -o mandelbrot.js

See result as

  firefox [ localhost/mbrot ]

Step VI. Dices
-------------

Follow

  https://tutorialzine.com/2017/06/getting-started-with-web-assembly

Implant primes.c into webAssembly. Compare execution time with:

  1. bellard.org/jslinux (machine x86 CLI)
  2. WSL
  3. Native W10:
       install Git for Windows,
       Strawberry Perl,
       allow local scripts in PowerShell

     PS C:\WINDOWS\system32> Set-ExecutionPolicy remotesigned
     > Get-ExecutionPolicy
     > gcc primes.c -o primes.exe

Optimize algorithm to boost performance 50-100 times.

Links:
......

  [1]. https://codelabs.developers.google.com/codelabs
         /web-assembly-intro/index.html?index=..%2F..%2Findex#0

  [2]. https://github.com/googlecodelabs/web-assembly-introduction
         /archive/master.zip

Annex A. Game of Life
.....................

build.sh

  #!/bin/bash

  emcc \
    -o output.js *.c \
    -s WASM=1 -s ONLY_MY_CODE=1 \
    -s EXPORTED_FUNCTIONS="['_board_step','_board_init','_board_ref']"

lyff.c

  /*
   * Copyright 2017 Google Inc. All rights reserved.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   * implied. See the. License for the specific language governing
   * permissions and limitations under the License.
   */

  typedef unsigned char byte;

  #define DIM 100
  #define SIZE ((DIM + 2) * (DIM + 2) / 8)  // byte size

  static byte boardA[SIZE], boardB[SIZE];
  static byte *board = (byte *) &boardA;

  // Gets the cell on the default board.
  byte get_cell(int x, int y) {
    int pos = (y * (DIM + 2)) + x;
    int i = pos / 8;
    byte off = 1 << (pos % 8);
    return board[i] & off;
  }

  // Sets a cell on a board.
  void set_cell_ref(byte *b, int x, int y) {
    int pos = (y * (DIM + 2)) + x;
    int i = pos / 8;
    byte off = 1 << (pos % 8);
    b[i] |= off;
  }

  // Clears a board.
  void clear_board_ref(byte *b) {
    for (int i = 0; i < SIZE; ++i) {
      b[i] = 0;
    }
  }

  // Steps through one iteration of Conway's Game of Life.
  // Returns the number of now alive cells, or -1 if no cells
  // changed this iteration: i.e., stable game.

  int board_step() {
    int total_alive = 0;
    int change = 0;

    // place output in A/B board
    byte *next = (byte *) &boardA;
    if (board == next) {
      next = (byte *) &boardB;
    }
    clear_board_ref(next);

    for (int x = 1; x <= DIM; ++x) {
      for (int y = 1; y <= DIM; ++y) {
        byte alive = get_cell(x, y);
        byte out = 0;

        int count = 0;
        for (int off = 0; off < 9; ++off) {
          if (off == 4) { continue; }  // this is 'us'

          int dx = (off % 3) - 1;
          int dy = (off / 3) - 1;

          if (!get_cell(x + dx, y + dy)) { continue; }
          if (++count > 3) { break; }
        }

        if (count == 3 || (count == 2 && alive)) {
          out = 1;
        }
        if (out) {
          // TODO: hold onto index, pass around?
          set_cell_ref(next, x, y);
          ++total_alive;
        }
        if (out != alive) {
          ++change;
        }
      }
    }

    board = next;
    if (change == 0) {
      return -1;  // we're stable
    }
    return total_alive;
  }

  // Count the total number of alive cells.
  int board_count() {
    int count = 0;
    for (int i = 0; i < SIZE; ++i) {
      byte v = board[i];
      while (v) {
        count += v & 1;
        v >>= 1;
      }
    }
    return count;
  }

  // Returns the pointer location of the rendered board.
  byte *board_ref() {
    return board;
  }

  // Clears the board.
  void board_init() {
    clear_board_ref(board);

    // TODO: dummy board setup
    board[85] = 255;
    board[120] = 255;
    board[132] = 255;
    board[800] = 255;
    board[720] = 254;
    board[700] = 255;
    board[600] = 255;
    board[601] = 255;
    board[602] = 255;
    board[603] = 255;
    board[604] = 255;
    board[605] = 255;
    board[606] = 255;
  }

index.html

  <!DOCTYPE html>
  <html>
  <head>
  <script>
    async function createWebAssembly(path, importObject) {
      const bytes = await window.fetch(path).then(x => x.arrayBuffer());
      return WebAssembly.instantiate(bytes, importObject);
    }

    const memory = new WebAssembly.Memory({initial: 256, maximum: 256});
    const env = {
      'abortStackOverflow': _ => { throw new Error('overflow'); },
      'table': new WebAssembly.Table(
                 {initial: 0, maximum: 0, element: 'anyfunc'}
               ),
      'tableBase': 0,
      'memory': memory,
      'memoryBase': 1024,
      'STACKTOP': 0,
      'STACK_MAX': memory.buffer.byteLength,
    };
    const importObject = {env};

    createWebAssembly('output.wasm', importObject).then(wa => {
      const exports = wa.instance.exports;
      console.info('got exports', exports);
      exports._board_init();  // setup lyff board

      function getBoardBuffer() {
        return new Uint8Array(memory.buffer, exports._board_ref());
      }

      function draw() {
        const buffer = getBoardBuffer();

        const dim = 100;  // nb. fixed size
        canvas.width = canvas.height = dim + 2;
        canvas.style.width = canvas.style.height = `${dim*5}px`;
        const data = new ImageData(canvas.width, canvas.height);

        for (var x = 1; x <= dim; ++x) {
          for (var y = 1; y <= dim; ++y) {
            var pos = (y * (dim + 2)) + x;
            var i = (pos / 8) << 0;
            var off = 1 << (pos % 8);

            var alive = (buffer[i] & off);
            if (!alive) { continue; }

            const doff = (y * canvas.width + x) * 4;
            data.data[doff+0] = 255;
            data.data[doff+3] = 255;
          }
        }

        canvas.getContext('2d').putImageData(data, 0, 0)
      }

      draw();

      canvas.onclick = ev => {
        exports._board_step();
        draw();
      };

    }).catch(err => console.warn('err loading wasm', err));

  </script>
  <style>
    canvas {
      image-rendering: pixelated;
      border: 2px solid green;
    }
  </style>
  </head>
  <body>
    <canvas id="canvas"
            style="image-rendering: pixelated; border: 2px solid blue;">
    </canvas>
  </body>
  </html>

Annex B.
........

primes.c

  #include <stdio.h>
  #include <stdlib.h>

  int is_prime(int);

  int main(void) {
      unsigned long n=10000000, sum=0;
      for (int j = 1; j <= n; j++) {
          if (is_prime(j)) {
              // printf("%d\n", j);
              sum++;
          }
      }
      printf("%ld of %ld are primes\n", sum, n);
      return 0;
  }

  int is_prime(int num) {
      if (num <= 1) return 0;
      for (int i = 2; i * i <= num; i++) {
          if (num % i == 0) {
              return 0;
          }
      }
      return 1;
  }

