Easily Implement Stochastic Differential Equations, Bayesian Methods, and More

Easily implement particle and Kalman filters for sensor fusion, Bayesian inference methods in machine learning, numerical solution of stochastic differential equations using Brownian motion processes, uncertainty quantification (UQ) in high-performance engineering simulations, and more. Take advantage of Signaloid's UxHw® technology to replace your implementations of Monte Carlo methods, in these use cases, with deterministic computations on probability distributions; no Monte Carlo loops required. Start with your existing unmodified code in any language supported by the LLVM compiler infrastructure.

Minimal Code Changes

Signaloid's UxHw technology gives your applications the abstraction of running over a virtual processor whose input data can be annotated with probability distributions. The processor performs arithmetic on these distributions as it runs binaries, detecting correlations as they occur.

Our LLVM-based compiler toolsuite lets you compile applications in any of the frontend languages supported by LLVM (e.g., C/C++). When you run your applications over the Signaloid C0 virtual processor:

Input distributions

automatically parsed from standard input (using scanf) or explicitly injected using calls to the UxHw interface API.

Input distributions

automatically parsed from standard input (using scanf) or explicitly injected using calls to the UxHw interface API.

Input distributions

automatically parsed from standard input (using scanf) or explicitly injected using calls to the UxHw interface API.

Every arithmetic operation

propagates probability distributions associated with its operands, to its result, deterministically.

Every arithmetic operation

propagates probability distributions associated with its operands, to its result, deterministically.

Every arithmetic operation

propagates probability distributions associated with its operands, to its result, deterministically.

Output values

carry their complete probability distributions.

Output values

carry their complete probability distributions.

Output values

carry their complete probability distributions.

Three Ways to Integrate:

Cloud-Based Kernel Compilation and Task Execution

Run applications over the UxHw virtualization layer without needing to setup and maintain your own infrastructure. Build on our secure ISO 27001 and SOC2 Type II certified platform, with geographic redundancy and auto-scaling to workloads.

Use our REST APIs to pre-compile codebases, launch compiled tasks, and retrieve results. The Signaloid Cloud Compute Engine (SCCE) SDK eases integration and the signaloid-cli command-line utility even allowing you to build complete UxHw-enhanced web applications, complete with UI elements optimized for interactive input and display of probability distributions.

Create Build from Repository.

Create Build from Repository.

Launch Task from Build.

Launch Task from Build.

Get Output from Task.

Get Output from Task.

Best for:

Cloud-native applications

Batch processing

Integration with existing pipelines

Integrate with Existing CPU and GPU Hardware

Deploy the UxHw virtualization layer on your existing hardware. Whether server-based on-premises hardware like AWS Outpost servers, or edge compute hardware like Nvidia Jetson and Nvidia DRIVE, augment your existing hardware and software optimization investments.

Use UxHw virtualization layer as the sole execution environment.

Deploy UxHw-augmented software components side by side with your traditional components.

Best for:

Harness existing CPUs/GPUs

Complement existing optimizations

On-premises/edge deployment

Our Specialized Hardware Modules

Achieve even greater speedups than the default UxHw technology, with additional hardware acceleration.

Augment your on-premises server-based UxHw deployments with our high-end FPGA-based UxHw accelerators built on Xilinx/AMD Virtex Ultrascale FPGAs. No software changes needed to your existing UxHw-enhanced applications that you've previously deployed on our cloud-based and on-premises integration modes.

For low-power edge-of-network deployments, our C0-microSD, C0-microSD+, C0-SD, and C0-M.2 modules allow you to easily integrate UxHw technology into your existing systems, with no hardware modifications necessary. These modules present a mass storage device interface through which you can send UxHw-enhanced applications for execution and retrieve results. Achieve easier implementation and faster execution without needing custom kernel drivers to interface with these hardware modules.

Achieve speedup over non-hardware-accelerated UxHw

Achieve speedup over non-hardware-accelerated UxHw

Achieve speedup over non-hardware-accelerated UxHw

No changes needed to existing UxHw-enhanced software

No changes needed to existing UxHw-enhanced software

No changes needed to existing UxHw-enhanced software

Edge computing variants supplied in easily-integrated form factor

Edge computing variants supplied in easily-integrated form factor

Edge computing variants supplied in easily-integrated form factor

Best for:

Quantitative Finance

Robotics

Industrial automation

Edge computing

Visualization of one example use case (Brownian motion in quantitative finance), implemented with traditional methods (first) compared to running on Signaloid's UxHw technology (second).

Dig Deeper: UxHw Execution Semantics

UxHw technology propagates distribution metadata alongside the non-distributional data when running your binaries, without requiring any explicit changes to your software. You can however explicitly access the distributional information when you need to, such as to retrieve summary statistics from the final algorithm output or to explicitly inject or manipulate distributional data and distributions correlations.

/*
 *	Kernel for arithmetic Brownian motion, exploiting UxHw.
 */
double
arithmeticBrownianMotion(size_t numberOfSteps)
{
	/*
	 *	When running on UxHw-enabled platforms, all `float` and `double` values
	 *	have an associated distribution, in addition to their default semantics.
	 */
	double		dt;
	double		b1;
	double		b1Dt;
	double		sqrtDt;
	double		sigmaSquared;
	double		Z;
	double		X;

	sigmaSquared	= pow(kArithmeticBrownianMotionConfigSigma, 2.0);
	dt				= (double)kArithmeticBrownianMotionConfigDefaultT / numberOfSteps;
	sqrtDt			= pow(dt, 0.5);
	b1				= kArithmeticBrownianMotionConfigR - 0.5 * sigmaSquared;
	b1Dt			= b1 * dt;

	X = kArithmeticBrownianMotionConfigX0;
	for (size_t i = 0; i < numberOfSteps; i++)
	{
		/*
		 *	The function UxHwDoubleGaussDist() returns a `double` that also has
		 *	associated with it a complete probability distribution.
		 */
		Z = UxHwDoubleGaussDist(0.0, 1.0);
		X += b1Dt + kArithmeticBrownianMotionConfigSigma * sqrtDt * Z;
	}

	/*
	 *	When running on UxHw-enabled platforms, variable X has both its default
	 *	floating-point semantics as well as the full distribution of the final
	 *	time step.
	 */
	return  X

/*
 *	Kernel for arithmetic Brownian motion, exploiting UxHw.
 */
double
arithmeticBrownianMotion(size_t numberOfSteps)
{
	/*
	 *	When running on UxHw-enabled platforms, all `float` and `double` values
	 *	have an associated distribution, in addition to their default semantics.
	 */
	double		dt;
	double		b1;
	double		b1Dt;
	double		sqrtDt;
	double		sigmaSquared;
	double		Z;
	double		X;

	sigmaSquared	= pow(kArithmeticBrownianMotionConfigSigma, 2.0);
	dt				= (double)kArithmeticBrownianMotionConfigDefaultT / numberOfSteps;
	sqrtDt			= pow(dt, 0.5);
	b1				= kArithmeticBrownianMotionConfigR - 0.5 * sigmaSquared;
	b1Dt			= b1 * dt;

	X = kArithmeticBrownianMotionConfigX0;
	for (size_t i = 0; i < numberOfSteps; i++)
	{
		/*
		 *	The function UxHwDoubleGaussDist() returns a `double` that also has
		 *	associated with it a complete probability distribution.
		 */
		Z = UxHwDoubleGaussDist(0.0, 1.0);
		X += b1Dt + kArithmeticBrownianMotionConfigSigma * sqrtDt * Z;
	}

	/*
	 *	When running on UxHw-enabled platforms, variable X has both its default
	 *	floating-point semantics as well as the full distribution of the final
	 *	time step.
	 */
	return  X

/*
 *	Kernel for arithmetic Brownian motion, exploiting UxHw.
 */
double
arithmeticBrownianMotion(size_t numberOfSteps)
{
	/*
	 *	When running on UxHw-enabled platforms, all `float` and `double` values
	 *	have an associated distribution, in addition to their default semantics.
	 */
	double		dt;
	double		b1;
	double		b1Dt;
	double		sqrtDt;
	double		sigmaSquared;
	double		Z;
	double		X;

	sigmaSquared	= pow(kArithmeticBrownianMotionConfigSigma, 2.0);
	dt				= (double)kArithmeticBrownianMotionConfigDefaultT / numberOfSteps;
	sqrtDt			= pow(dt, 0.5);
	b1				= kArithmeticBrownianMotionConfigR - 0.5 * sigmaSquared;
	b1Dt			= b1 * dt;

	X = kArithmeticBrownianMotionConfigX0;
	for (size_t i = 0; i < numberOfSteps; i++)
	{
		/*
		 *	The function UxHwDoubleGaussDist() returns a `double` that also has
		 *	associated with it a complete probability distribution.
		 */
		Z = UxHwDoubleGaussDist(0.0, 1.0);
		X += b1Dt + kArithmeticBrownianMotionConfigSigma * sqrtDt * Z;
	}

	/*
	 *	When running on UxHw-enabled platforms, variable X has both its default
	 *	floating-point semantics as well as the full distribution of the final
	 *	time step.
	 */
	return  X

Used by Developers at:

Configure UxHw To Match Your Use Case

Choose the right UxHw technology variant for your use case:

UxHw Core Type

UxHw Core Type

UxHw Core Type

Description

Description

Description

Best For

Best For

Best For

C0

C0

C0

High-performance uncertainty tracking

High-performance uncertainty tracking

High-performance uncertainty tracking

Advanced debugging capabilities

Advanced debugging capabilities

Advanced debugging capabilities

C0-Pro

C0-Pro

C0-Pro

Higher representation precision

Higher representation precision

Higher representation precision

High-performance workloads

High-performance workloads

High-performance workloads

C0-Reference

C0-Reference

C0-Reference

Monte Carlo equivalent (guaranteed accuracy)

Monte Carlo equivalent (guaranteed accuracy)

Monte Carlo equivalent (guaranteed accuracy)

Validation and debugging

Validation and debugging

Validation and debugging

C0-Bypass

C0-Bypass

C0-Bypass

Standard execution (no uncertainty)

Standard execution (no uncertainty)

Standard execution (no uncertainty)

Porting and testing

Porting and testing

Porting and testing

Quick Start (5 Minutes)

1

Sign Up

Create a free account on Signaloid Cloud Developer Platform.

2

Write Code

Use the in-browser editor or connect your GitHub repository.

/*
 *	Simple Bethe-Bloch radiation transport implementation, exploiting UxHw.
 *	You can copy and paste directly into Signaloid Cloud Developer Platform
 *	code editor.
 */
#include <stdio.h>
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <uxhw.h>

const float		kInitialEnergy					= 800.0;
const float		kProtonMass						= 938.3;
const float		kElectronMass					= 0.511;
const float		kZconcrete						= 11;
const float		kIconcrete						= 0.000286;
const float		kLconcrete						= 0.1;
const int		kPartitionSize					= 100;
const float		kCollisionProbabilityDensityPerL= 50;
const float		kLowerBoundOnInelasticEnergyLoss= 0.7;
const float		kFudgeFactor1					= 0.15*kZconcrete;
const float		kFudgeFactor2					= 2*kElectronMass/kIconcrete;

float
betheBloch(float energy)
{
	float	beta = pow (1 - kProtonMass /(energy + kProtonMass), 2);
	float	dEdx = (kFudgeFactor1/beta)*log(kFudgeFactor2*beta);

	return dEdx;
}

int
main(void)
{
	/*
	 *	When running on UxHw-enabled platforms, all `float` and `double` values
	 *	have an associated distribution, in addition to their default semantics.
	 */
	float	energy = kInitialEnergy;
	float	dx = kLconcrete / kPartitionSize;
	float	inelasticCollisionProbability = dx*kCollisionProbabilityDensityPerL;

	for (int i=0; i<kPartitionSize; i++)
	{
		float	dEdx = betheBloch(energy);
		float	dE = fmaxf(dEdx*dx, 0);

		energy -= dE;
		energy = UxHwDoubleMixture(	energy,
						energy*UxHwFloatUniformDist(kLowerBoundOnInelasticEnergyLoss, 1),
						1 - inelasticCollisionProbability);
	}

	/*
	 *	When running on UxHw-enabled platforms, the variable `energy` at this point has
	 *	both its default floating-point semantics as well as an associated distribution.
	 *	You can use UxHw API functions to query any of the properties of this associated
	 *	distribution, or even display the full distribution.
	 */
	printf("Energy Absorbed = %f (mean value of distributional information is %f)\n",
			kInitialEnergy - energy,
            UxHwFloatNthMoment(energy,1));

	return 0

/*
 *	Simple Bethe-Bloch radiation transport implementation, exploiting UxHw.
 *	You can copy and paste directly into Signaloid Cloud Developer Platform
 *	code editor.
 */
#include <stdio.h>
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <uxhw.h>

const float		kInitialEnergy					= 800.0;
const float		kProtonMass						= 938.3;
const float		kElectronMass					= 0.511;
const float		kZconcrete						= 11;
const float		kIconcrete						= 0.000286;
const float		kLconcrete						= 0.1;
const int		kPartitionSize					= 100;
const float		kCollisionProbabilityDensityPerL= 50;
const float		kLowerBoundOnInelasticEnergyLoss= 0.7;
const float		kFudgeFactor1					= 0.15*kZconcrete;
const float		kFudgeFactor2					= 2*kElectronMass/kIconcrete;

float
betheBloch(float energy)
{
	float	beta = pow (1 - kProtonMass /(energy + kProtonMass), 2);
	float	dEdx = (kFudgeFactor1/beta)*log(kFudgeFactor2*beta);

	return dEdx;
}

int
main(void)
{
	/*
	 *	When running on UxHw-enabled platforms, all `float` and `double` values
	 *	have an associated distribution, in addition to their default semantics.
	 */
	float	energy = kInitialEnergy;
	float	dx = kLconcrete / kPartitionSize;
	float	inelasticCollisionProbability = dx*kCollisionProbabilityDensityPerL;

	for (int i=0; i<kPartitionSize; i++)
	{
		float	dEdx = betheBloch(energy);
		float	dE = fmaxf(dEdx*dx, 0);

		energy -= dE;
		energy = UxHwDoubleMixture(	energy,
						energy*UxHwFloatUniformDist(kLowerBoundOnInelasticEnergyLoss, 1),
						1 - inelasticCollisionProbability);
	}

	/*
	 *	When running on UxHw-enabled platforms, the variable `energy` at this point has
	 *	both its default floating-point semantics as well as an associated distribution.
	 *	You can use UxHw API functions to query any of the properties of this associated
	 *	distribution, or even display the full distribution.
	 */
	printf("Energy Absorbed = %f (mean value of distributional information is %f)\n",
			kInitialEnergy - energy,
            UxHwFloatNthMoment(energy,1));

	return 0

/*
 *	Simple Bethe-Bloch radiation transport implementation, exploiting UxHw.
 *	You can copy and paste directly into Signaloid Cloud Developer Platform
 *	code editor.
 */
#include <stdio.h>
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <uxhw.h>

const float		kInitialEnergy					= 800.0;
const float		kProtonMass						= 938.3;
const float		kElectronMass					= 0.511;
const float		kZconcrete						= 11;
const float		kIconcrete						= 0.000286;
const float		kLconcrete						= 0.1;
const int		kPartitionSize					= 100;
const float		kCollisionProbabilityDensityPerL= 50;
const float		kLowerBoundOnInelasticEnergyLoss= 0.7;
const float		kFudgeFactor1					= 0.15*kZconcrete;
const float		kFudgeFactor2					= 2*kElectronMass/kIconcrete;

float
betheBloch(float energy)
{
	float	beta = pow (1 - kProtonMass /(energy + kProtonMass), 2);
	float	dEdx = (kFudgeFactor1/beta)*log(kFudgeFactor2*beta);

	return dEdx;
}

int
main(void)
{
	/*
	 *	When running on UxHw-enabled platforms, all `float` and `double` values
	 *	have an associated distribution, in addition to their default semantics.
	 */
	float	energy = kInitialEnergy;
	float	dx = kLconcrete / kPartitionSize;
	float	inelasticCollisionProbability = dx*kCollisionProbabilityDensityPerL;

	for (int i=0; i<kPartitionSize; i++)
	{
		float	dEdx = betheBloch(energy);
		float	dE = fmaxf(dEdx*dx, 0);

		energy -= dE;
		energy = UxHwDoubleMixture(	energy,
						energy*UxHwFloatUniformDist(kLowerBoundOnInelasticEnergyLoss, 1),
						1 - inelasticCollisionProbability);
	}

	/*
	 *	When running on UxHw-enabled platforms, the variable `energy` at this point has
	 *	both its default floating-point semantics as well as an associated distribution.
	 *	You can use UxHw API functions to query any of the properties of this associated
	 *	distribution, or even display the full distribution.
	 */
	printf("Energy Absorbed = %f (mean value of distributional information is %f)\n",
			kInitialEnergy - energy,
            UxHwFloatNthMoment(energy,1));

	return 0

3

Run

Click “Compile and Run.” Hover over outputs to see full distributions.

4

Integrate

Use the REST API to integrate into your production systems.

import { SignaloidClient } from '@signaloid/scce-sdk';

const client = new SignaloidClient({ apiKey: process.env.SIGNALOID_API_KEY });
const task = await client.tasks.create({ sourceCode: myCode });
const result = await client.tasks.waitForCompletion(task.id);
import { SignaloidClient } from '@signaloid/scce-sdk';

const client = new SignaloidClient({ apiKey: process.env.SIGNALOID_API_KEY });
const task = await client.tasks.create({ sourceCode: myCode });
const result = await client.tasks.waitForCompletion(task.id);
import { SignaloidClient } from '@signaloid/scce-sdk';

const client = new SignaloidClient({ apiKey: process.env.SIGNALOID_API_KEY });
const task = await client.tasks.create({ sourceCode: myCode });
const result = await client.tasks.waitForCompletion(task.id);

Use Cases

Schedule a Demo Call
Request Whitepaper
Schedule a Demo Call
Request Whitepaper
Schedule a Demo Call
Request Whitepaper