Skip to main content

Running Source Code Tasks

Learn how to run programmatically single-source applications on the Signaloid Cloud Compute Engine

You can run a single-source application on the Signaloid Cloud Compute Engine via an API request. The example single-source C application below calculates how uncertainties in empirical model parameters affect the uncertainty distribution of the model's output, for a model of a physical process. The original source code lives in Brown-Ham model example. This code calculates the output of the model and prints the result to the standard output.

#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <uxhw.h>

static void
loadInputs(double * G, double * M, double * Rs, double * b, double * gamma, double * phi)
{
double empiricalTaylorFactorValues[] = {
3.2, 3.9, 4.1, 3.2, 3.8, 3.8, 2.1, 3.0, 1.9, 3.9,
2.3, 2.2, 3.2, 2.2, 3.9, 2.2, 1.9, 3.2, 3.9, 3.1,
};

*M = UxHwDoubleDistFromSamples(empiricalTaylorFactorValues, sizeof(empiricalTaylorFactorValues)/sizeof(double));
*G = UxHwDoubleUniformDist(6E10, 8E10);
*Rs = UxHwDoubleMixture(UxHwDoubleGaussDist(1E-8, 2E-9), UxHwDoubleGaussDist(3E-8, 2E-9), 0.5);
*b = 2.54E-10;
*gamma = UxHwDoubleUniformDist(0.15, 0.25);
*phi = UxHwDoubleUniformDist(0.3, 0.45);
}

int
main(int argc, char * argv[])
{
double G, M, Rs, b, gamma, phi, sigmaCMpa;

loadInputs(&G, &M, &Rs, &b, &gamma, &phi);

sigmaCMpa = ((M*gamma)/(2.0*b))*(sqrt((8.0*gamma*phi*Rs)/(M_PI*G*pow(b, 2))) - phi)/1000000;

printf("Alloy strength (σc)\t\t= %.1E MPa\n", sigmaCMpa);

return 0;
}

Prerequisites

To run a source code task via the API, you will need to have the following:

  • An API key to access the Signaloid Cloud API. Please refer to Authentication for more details.

Set up the task request

The Source Code task request object has the following schema:

  type TraceVariable = {
File: string;
LineNumber: number;
Expression: string;
}

type SourceCodeTaskRequest = {
Type: "SourceCode";
SourceCode: {
Object: "SourceCode";
Code: string;
Arguments: string;
Language: "C" | "C++";
};
Overrides?: {
Core?: string;
TraceVariables?: TraceVariable[];
};
};

Define your source code as a string

caution

Correctly Escaping Strings for special characters: Ensure that the Code field of the task request object is a valid JSON string. This might require you to make sure special characters are escaped properly. Refer to the documentation for your host language for details on how to escape special characters in strings.

Note

Escaping special characters in JavaScript: In this application we have chosen to manually escape the \n characters as \\n in the C code. This will allow the printf statement to correctly receive the \n character instructing it to print a new line as intended. An alternative approach would have been to define the source code as a raw JavaScript string and use JSON.stringify to escape the string.

  const applicationCode = `#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <uxhw.h>

static void
loadInputs(double * G, double * M, double * Rs, double * b, double * gamma, double * phi)
{
double empiricalTaylorFactorValues[] = {
3.2, 3.9, 4.1, 3.2, 3.8, 3.8, 2.1, 3.0, 1.9, 3.9,
2.3, 2.2, 3.2, 2.2, 3.9, 2.2, 1.9, 3.2, 3.9, 3.1,
};

*M = UxHwDoubleDistFromSamples(empiricalTaylorFactorValues, sizeof(empiricalTaylorFactorValues)/sizeof(double));
*G = UxHwDoubleUniformDist(6E10, 8E10);
*Rs = UxHwDoubleMixture(UxHwDoubleGaussDist(1E-8, 2E-9), UxHwDoubleGaussDist(3E-8, 2E-9), 0.5);
*b = 2.54E-10;
*gamma = UxHwDoubleUniformDist(0.15, 0.25);
*phi = UxHwDoubleUniformDist(0.3, 0.45);
}

int
main(int argc, char * argv[])
{
double G, M, Rs, b, gamma, phi, sigmaCMpa;

loadInputs(&G, &M, &Rs, &b, &gamma, &phi);

sigmaCMpa = ((M*gamma)/(2.0*b))*(sqrt((8.0*gamma*phi*Rs)/(M_PI*G*pow(b, 2))) - phi)/1000000;

printf("Alloy strength (σc)\\t\\t= %.1E MPa\\n", sigmaCMpa);

return 0;
}`;

Task request object for an uncertaintry-tracking (UT) C0 or C0 Pro core

You can use the Code field to specify the source code of your application as a string. The Language field specifies the programming language of the source code. The Arguments field specifies the command line arguments to be passed to the application when it is executed.

  // Core ID of the C0-S+ core
const coreID = "cor_b21e4de9927158c1a5b603c2affb8a09";

const taskRequest = {
Type: "SourceCode",
SourceCode: {
Object: "SourceCode",
Code: applicationCode,
Arguments: "",
Language: "C",
},
Overrides: {
Core: coreID,
},
};

Task request object for a C0 or C0 Pro Reference core

When running an application on the Reference microarchitecture on C0 or C0 Pro, the Signaloid Cloud Compute Engine needs to know which variables of your source code to trace. To show distributional output at the end of execution, the Signaloid Cloud Compute Engine needs to accumulate the particle values of variables across the different re-executions of the application. The traced variables can be of double or float base type, including typedef definitions to these types. See here for more details about what kinds of expressions you can trace.

Note

Use the TraceVariables element in Overrides of the task request object to instruct the Signaloid Cloud Compute Engine about the variables to trace. Your source code may contain multiple variables with the same name, defined in different scopes of your source code. Because of this, the Signaloid Cloud Developer Platform needs to know the file and line number of the declaration of the variable that you wish to trace to be able to uniquely identify it.

The following code snippets show how to use the Signaloid API calls to instruct the Signaloid Cloud Compute Engine to run on C0 Reference core the source code shown at the top of the page. The TraceVariables element of the Task object, instructs the Signaloid Cloud Compute Engine to trace variable sigmaCMpa, in line 25 of file main.c. By convention, the file name of source code task in Signaloid Cloud Compute Engine is always main.c.

Note

Escaping special characters in JavaScript: In this application we have chosen to manually escape the \n characters as \\n in the C code. This will allow the printf statement to correctly receive the \n character instructing it to print a new line as intended. An alternative approach would have been to define the source code as a raw JavaScript string and use JSON.stringify to escape the string.

  // Core ID of the C0-Reference core
const coreID = "cor_9a3efb0094405df5aeb61cf1f29606a0";

const taskRequest = {
Type: "SourceCode",
SourceCode: {
Object: "SourceCode",
Code: applicationCode,
Arguments: "",
Language: "C",
},
Overrides: {
Core: coreID,
TraceVariables: [{ Expression: "sigmaCMpa", File: "main.c", LineNumber: 25 }]
},
};

Submit the task to the API

Submit the task request to the API via a POST request to /tasks. The code snippet below shows how to submit the task request to the API using the axios library.

  // API token generated from signaloid.io/settings/api
const apiToken = "scce_yourSignaloidCloudApiKey";

// Setup HTTP client
const axios = require("axios");
const signaloidClient = axios.create({
baseURL: "https://api.signaloid.io",
});

// Setup request headers
signaloidClient.defaults.headers["Authorization"] = `${apiToken}`;
signaloidClient.defaults.headers["Content-Type"] = "application/json";

console.log("Submitting the task to the API...");
let taskPostResponse;
try {
taskPostResponse = await signaloidClient.post("/tasks", taskRequest);

if (taskPostResponse.data.TaskID) {
console.log(`...task successfully created with ID: ${taskPostResponse.data.TaskID}`);
}
} catch (error) {
console.log("Error:", error);
}

If the task is valid, and the API has accepted the request, the taskPostResponse variable will contain information about the task. The code snippet below shows the contents of the taskPostResponse variable after the task has been successfully created.

{
"data": {
"Object": "Task",
"TaskID": "tsk_6dcae4d1c4f585901efa12a89a063996",
"Owner": "usr_yourSignaloidCloudUserID",
"Application": {...}, // The application that was submitted to the API
"Status": "Accepted",
[...other response keys omitted]
},
"status": 202,
"statusText": "Accepted",
[...other response keys omitted]
}

You can now use the TaskID to retrieve the status and outputs of the task from the API.