Introducing the Standalone Applications Beta Program

Presentation by:
		Chris Cooley
		Wolfram Research, Inc.

Plan for this presentation

Explanation of the project

Introduction of the beta program

Example of the development process

The goal

Make Wolfram Language-based applications practical and appealing

Project components

Expression API

Also called Wolfram Language Runtime

Allows the “compilation” of Wolfram Language code into executables and libraries

Project components

Expression API

Also called Wolfram Language Runtime

Allows the “compilation” of Wolfram Language code into executables and libraries

Code signing

Allows Wolfram Language to be executed even in the absence of a license

Project components

Expression API

Also called Wolfram Language Runtime

Allows the “compilation” of Wolfram Language code into executables and libraries

Code signing

Allows Wolfram Language to be executed even in the absence of a license

Pruning strategies

Allow applications to bundle a reduced Wolfram Language layout that only contains necessary components for a given application

A Critical Concept (1/2)

The kernel dynamic library is a crucial component of the Wolfram system

A Critical Concept (1/2)

The kernel dynamic library is a crucial component of the Wolfram system

The kernel dynamic library implements the programming language and some core functionality

A Critical Concept (1/2)

The kernel dynamic library is a crucial component of the Wolfram system

The kernel dynamic library implements the programming language and some core functionality

The kernel dynamic library is found within SystemFiles/Libraries/<$SystemID>

A Critical Concept (2/2)

Expression API

The expression API is a set of C functions exported from the kernel dynamic library that allow expressions to be built up, evaluated, and deconstructed

Expression API

The expression API is a set of C functions exported from the kernel dynamic library that allow expressions to be built up, evaluated, and deconstructed

Any application that links against the kernel dynamic library will have the kernel run in their process

Expression API

The expression API is a set of C functions exported from the kernel dynamic library that allow expressions to be built up, evaluated, and deconstructed

Any application that links against the kernel dynamic library will have the kernel run in their process

We hope that the expression API is intuitive to users outside of the Wolfram ecosystem

Expression API Documentation

Expression API Documentation

Unofficial draft: https://www.wolframcloud.com/obj/ccooley/swadoc/runtimeinterface.html

Standalone applications SDK (1/4)

The SDK is a static library that developers will link against when creating standalone applications

Standalone applications SDK (2/4)

Example of shell command for compiling C code that uses the expression API

cc application.c -o application -I /Applications/Mathematica.app/Contents/SystemFiles/Components/StandaloneApplicationsSDK/MacOSX-x86-64 /Applications/Mathematica.app/Contents/SystemFiles/Components/StandaloneApplicationsSDK/MacOSX-x86-64/StandaloneApplicationsSDK.a

Standalone applications SDK (3/4)

Example of IDE settings for compiling C code that uses the expression API

Standalone applications SDK (4/4)

Example of IDE settings for compiling C code that uses the expression API

Simple command-line example (1/4)

https://writings.stephenwolfram.com/2024/07/yet-more-new-ideas-and-new-functions-launching-version-14-1-of-wolfram-language-mathematica/#standalone-wolfram-language-applications

Simple command-line example (2/4)

Simple command-line example (3/4)

Simple command-line example (4/4)

Code signing (1/2)

The code signing feature allows signed Wolfram Language material to be executed even in the absence of a license

Code signing (1/2)

The code signing feature allows signed Wolfram Language material to be executed even in the absence of a license

What is covered by code signing?

Code signing (1/2)

The code signing feature allows signed Wolfram Language material to be executed even in the absence of a license

What is covered by code signing?

Wolfram Language files

Code signing (1/2)

The code signing feature allows signed Wolfram Language material to be executed even in the absence of a license

What is covered by code signing?

Wolfram Language files

Wolfram Language symbols

Code signing (1/2)

The code signing feature allows signed Wolfram Language material to be executed even in the absence of a license

What is covered by code signing?

Wolfram Language files

Wolfram Language symbols

MX files

Code signature modules (1/2)

Code signature modules simplify the task of code signing

Code signature modules (1/2)

Code signature modules simplify the task of code signing

Code signatures modules can be generated in various ways

Example: A Wolfram web page where code is submitted and then signed

Code signature modules (2/2)

Developers compile the generated C file into their application

Example compilation command: cc CodeSignatureModule1.c [PREVIOUS OPTIONS ...]

Pruning (1/4)

The layout for the Wolfram Engine is a few gigabytes uncompressed

This footprint discourages developers from bundling the layout

Pruning attempts to reduce this footprint

Pruning (2/4)

One major pruning strategy is changing the BLAS backend

MKL is somewhere around a gigabyte

For certain applications, we can change the BLAS backend to a smaller alternative

Pruning (3/4)

Another major strategy is removing layout components that are not needed by a particular application

We have two methods for determining and removing unnecessary components

(Will come back to this later)

Pruning (4/4)

Large layout components that are possible pruning “targets” (based on an analysis of the macOS version of 13.1)

Introducing the beta program

Airy Optics (1/2)

Airy Optics (2/2)

LSPServer

A standalone application that packages our LSPServer functionality for Visual Studio Code

https://marketplace.visualstudio.com/items?itemName=WolframResearch.wolfram

LSPServer

A standalone application that packages our LSPServer functionality for Visual Studio Code

https://marketplace.visualstudio.com/items?itemName=WolframResearch.wolfram

The existing LSPServer functionality uses a dedicated kernel that is launched from Visual Studio Code, but this kernel consumes a license

Development: Step 1

Determine what you are using WL for

Needs["LSPServer`"]; LSPServer`StartServer[];

Development: Step 2

Determine what you are using WL for

Needs["LSPServer`"]; LSPServer`StartServer[];

Connect to expression API

/* lspserverapp.c */

#include "WolframLanguageRuntimeV1SDK.h"

int main(int argc, char **argv)
{
    (void) WLR_SDK_START_KERNEL(WLR_EXECUTABLE, WLR_SIGNED_CODE_MODE, "Resources/LayoutFiles", NULL);

    (void) wlr_Eval(wlr_E(wlr_Symbol("Get"), wlr_E(wlr_Symbol("FileNameJoin"), wlr_Symbol("$InstallationDirectory"), wlr_String(".."), wlr_String("ApplicationFiles"), wlr_String("lspserverapp.wl"))));

    return 0;
}

/* lspserverapp.wl */

Needs["LSPServer`"]; LSPServer`StartServer[];

Code signing, revisited (1/2)

wlr_StartRuntime takes an argument that controls the signing behavior

Code signing, revisited (1/2)

wlr_StartRuntime takes an argument that controls the signing behavior

WLR_SIGNED_CODE_MODE forces the kernel to enter signed code mode

Code signing, revisited (1/2)

wlr_StartRuntime takes an argument that controls the signing behavior

WLR_SIGNED_CODE_MODE forces the kernel to enter signed code mode

WLR_LICENSE_OR_SIGNED_CODE_MODE allows the kernel to use a license if one is available, using signed code mode as a fallback

Code signing, revisited (2/2)

The expression API uses code signing to protect evaluations

Code signing, revisited (2/2)

The expression API uses code signing to protect evaluations

For example, wlr_Eval will produce an error if the kernel is in signed code mode, and it’s expression argument contains an unapproved symbol

Development: Step 3

Determine what you are using WL for

Needs["LSPServer`"]; LSPServer`StartServer[];

Connect to expression API

/* lspserverapp.c */

#include "WolframLanguageRuntimeV1SDK.h"

int main(int argc, char **argv)
{
    (void) WLR_SDK_START_KERNEL(WLR_EXECUTABLE, WLR_SIGNED_CODE_MODE, "Resources/LayoutFiles", NULL);

    (void) wlr_Eval(wlr_E(wlr_Symbol("Get"), wlr_E(wlr_Symbol("FileNameJoin"), wlr_Symbol("$InstallationDirectory"), wlr_String(".."), wlr_String("ApplicationFiles"), wlr_String("lspserverapp.wl"))));

    return 0;
}

/* lspserverapp.wl */

Needs["LSPServer`"]; LSPServer`StartServer[];

Sign your Wolfram Language code

Use the Wolfram web page to get a C file (i.e., a code signature module) that you can compile with lspserverapp.c

Development: Step 4

Determine what you are using WL for

Needs["LSPServer`"]; LSPServer`StartServer[];

Connect to expression API

/* lspserverapp.c */

#include "WolframLanguageRuntimeV1SDK.h"

int main(int argc, char **argv)
{
    (void) WLR_SDK_START_KERNEL(WLR_EXECUTABLE, WLR_SIGNED_CODE_MODE, "Resources/LayoutFiles", NULL);

    (void) wlr_Eval(wlr_E(wlr_Symbol("Get"), wlr_E(wlr_Symbol("FileNameJoin"), wlr_Symbol("$InstallationDirectory"), wlr_String(".."), wlr_String("ApplicationFiles"), wlr_String("lspserverapp.wl"))));

    return 0;
}

/* lspserverapp.wl */

Needs["LSPServer`"]; LSPServer`StartServer[];

Sign your Wolfram Language code

Use the code signature module web form to get a C file that you can compile with lspserverapp.c

Bundle a Wolfram Language layout

Bundle a layout at Resources/LayoutFiles relative to the lspserverapp executable

Development: Step 5

Determine what you are using WL for

Needs["LSPServer`"]; LSPServer`StartServer[];

Connect to expression API

/* lspserverapp.c */

#include "WolframLanguageRuntimeV1SDK.h"

int main(int argc, char **argv)
{
    (void) WLR_SDK_START_KERNEL(WLR_EXECUTABLE, WLR_SIGNED_CODE_MODE, "Resources/LayoutFiles", NULL);

    (void) wlr_Eval(wlr_E(wlr_Symbol("Get"), wlr_E(wlr_Symbol("FileNameJoin"), wlr_Symbol("$InstallationDirectory"), wlr_String(".."), wlr_String("ApplicationFiles"), wlr_String("lspserverapp.wl"))));

    return 0;
}

/* lspserverapp.wl */

Needs["LSPServer`"]; LSPServer`StartServer[];

Sign your Wolfram Language code

Use the code signature module web form to get a C file that you can compile with lspserverapp.c

Bundle a Wolfram Language layout

Bundle a layout at Resources/LayoutFiles relative to the lspserverapp executable

Prune the bundled Wolfram Language layout

Pruning, revisited

We have two methods for determining and removing unnecessary components

Dynamic analysis

Static analysis

Pruning: Dynamic analysis

We run the Wolfram Language application in a special mode where the files it accesses are recorded

Pruning: Dynamic analysis

We run the Wolfram Language application in a special mode where the files it accesses are recorded

The accessed files give us a good guess as to what layout components are critical and what components can be removed

Pruning: Dynamic analysis

We run the Wolfram Language application in a special mode where the files it accesses are recorded

The accessed files give us a good guess as to what layout components are critical and what components can be removed

This mechanism currently involves an amount of pruning by hand

Pruning: Static analysis

We have a tool that automatically analyzes an application’s Wolfram Language source code, and prunes a layout

Currently this mechanism tends to underprune

End

Sign up to be notified when the beta program begins at https://www.wolframcloud.com/obj/ccooley/standalone

Email is at ccooley@wolfram.com

Appendix: Code signing restriction table

The following table shows what material can be successfully evaluated in various situations:

Appendix: Code signing and the parser

Code signing affects all Wolfram Language functions that uses the parser to read in Wolfram Language expressions. This means Get, Read, etc.

These functions will return $Failed and output the message General::signingviolation if a signing violation occurs

(Code signing also affects the loading of MX files using DumpGet or Get.)

Appendix: Additional development goals

Automated tooling for code signing and pruning

Expression API integration with LibraryLink and Compiler

Support for applications with a front end-based interface

Appendix: Bug fixes in 14.2

“Certain expression API functions cannot be called from C++”

“Standalone applications SDK is broken on ARM Mac”