Menu

#99 WASM build

Unstable (example)
open
nobody
5
2020-10-29
2020-10-19
No

I have managed to successfully compile and build Ngspice for WASM with Emscripten. I have made a Docker container which encapsulates all the required components and procedures. Details can be found here:
https://github.com/danchitnis/ngspice

@h_vogt However, few problems do exist:
1. I had to remove the following section from misc_time.c due to memset.

#ifdef HAVE_GETRUSAGE
    int ret;
    struct rusage ruse;

    memset(&ruse, 0, sizeof(ruse));
    ret = getrusage(RUSAGE_SELF, &ruse);
    if(ret == -1) {
      perror("getrusage(): ");
      return 1;
    }
    return ((double)ruse.ru_utime.tv_sec + (double) ruse.ru_utime.tv_usec / 1000000.0);
#else

I am not sure what this function does? It doesn't seem to have any implications when running ngspice.
2. During compilation emmake make, there is a warning being generated that warning: unknown warning option '-Wno-unused-but-set-variable'; did you mean '-Wno-unused-const-variable'? [-Wunknown-warning-option]. Where is the option to change the CC compiler flags in the ngspice codebase?
3. OPENMP is not supported neither in WASM nor Emscripten yet. However this might change by the introduction SIMD instructions for WASM.
4. The shared library option doesn't seem to work well with Emscripten at the moment.

It would be nice to add a WASM build to ngspice build options.

Discussion

  • Holger Vogt

    Holger Vogt - 2020-10-20

    memset is used in more than 20 places throughout the ngspice source code. So I do not understand why this one here creates problems, and the others do not.

    CC compiler flags are set in configure.ac (see e.g. line 238).

    OpenMP may be deselected by not giving --enable-openmp during the configure step.

    What does 4. mean exactly? Any error messages during compile? Any strange behavior or results?

     
  • Holger Vogt

    Holger Vogt - 2020-10-20

    The previous discussion in #96 said that it is not memset, but getrusage (may in combination with memset) which does not do.

    So we simply have to exclude getrusage. This should be done during the configure step. In configure.ac there is a check for operating system at compile time (lines 307 ff.) Could there be an entry for Emscripten as well? We then could set a flag to exclude getrusage.

     
  • Danial Chitnis

    Danial Chitnis - 2020-10-20

    Hi Holger,
    1. yes it is getrusage, the errors happen in memset, otherwise memset is fine. We can add a enable_wasm flag there.
    2. I found the CC flags, I have to test it now. These warnings happen on every file and clutter the compiler output.
    3. This is fine for now.
    4. I am not sure where the problem is. It seems that emccis not strict enough when compiling shared libraries, and doesn't give any errors. Then, the code actually doesn't run and hardly gets past the first few lines without a fatal exit. The problem might be in the linking process. Getting the shared library working doesn't have a significant benefit over the interactive version. The reason is both run in the virtual WASM machine in a similar way.

    Few more step to get a clean WASM version of ngspice without any hacks!

     
  • Holger Vogt

    Holger Vogt - 2020-10-20

    Again looking at some blogs from internet: It is not the memset function written by ngspice people, but a _memset function that is part of the getrusage function. So getrusage seems to be basically flawed in emcc.

    You may try replacing
    #ifdef HAVE_GETRUSAGE
    by
    #if defined(HAVE_GETRUSAGE) && !defined(__EMSCRIPTEN__)

     

    Last edit: Holger Vogt 2020-10-21
  • Danial Chitnis

    Danial Chitnis - 2020-10-22
    1. I changed the flag in configure.ac line 237 to CFLAGS="$CFLAGS -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wnested-externs -Wold-style-definition -Wredundant-decls -Wconversion -Wno-unused-const-variable". This removed the previous unknown option warning. Can we make a separate CC flag for emscripten?
    2. The getrusage bug has disappeared! I am not sure this was due to ngspice 33 or Emscripten 2.0.7 releases. There is no need for patches or flags here.

    I have attached the config and make log here. Is the build process as expected? The generated wasm seems to run correctly. I will update my Docker file with these new changes.

     

    Last edit: Danial Chitnis 2020-10-22
  • Holger Vogt

    Holger Vogt - 2020-10-22

    Can we make a separate CC flag for emscripten?

    Yes, as soon as we know how to safely detect emscripten or emcc in configure.ac .

     

    Last edit: Holger Vogt 2020-10-22
  • Holger Vogt

    Holger Vogt - 2020-10-22

    Please check if
    -Wno-unused
    is o.k. instead of
    -Wno-unused-but-set-variable

     
  • Danial Chitnis

    Danial Chitnis - 2020-10-22

    -Wno-unused-const-variable
    instead of
    -Wno-unused-but-set-variable
    works fine.

    Currently, I am doing: sed -i 's/-Wno-unused-but-set-variable/-Wno-unused-const-variable/g' ./configure.ac

    I have updated the demo to show ngspice version and build timestamp

     
  • Holger Vogt

    Holger Vogt - 2020-10-23

    emcc seems to be not up-to-date concernig possible error message flags (compared to gcc).

    In an ngspice release I will not tinker around with sed or so.

    If there is a means to safely auto-detect the emscripten environment in configure.ac, I would consider adding a branch to avoid the offensive flag. Unfortunately I do not have emscripten (and I am not considering to install it locally), so I have to rely on your input here.

     

    Last edit: Holger Vogt 2020-10-23
  • Danial Chitnis

    Danial Chitnis - 2020-10-29

    Hi Holger, this seems to work in configure.ac

    if test "x$GCC" = xyes; then
            CFLAGS="$CFLAGS -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wnested-externs -Wold-style-definition -Wredundant-decls -Wconversion -Wno-unused-but-set-variable"
        fi
    
        # Set flags for Emscripten and emcc
        AC_MSG_CHECKING([for Emscripten])
        AS_IF([test "x$EMSCRIPTEN" != "x"], [
        AC_MSG_RESULT([yes])
        CFLAGS="-g -O2 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wnested-externs -Wold-style-definition -Wredundant-decls -Wconversion -Wno-unused-const-variable"], [
        AC_MSG_RESULT([no])
        ])
    

    It has to be placed after GCC test, otherwise $CFLAGS will be overwritten.

    I am developing inside containers, so no local installation is needed. I have made a Github mirror, which eventually enables some automatic building and testing in the cloud.

     

Log in to post a comment.