License#

prophys is proprietary software by RhineQC GmbH. This page explains what runs without a license, what needs one, and how to install and check a license.

The free tier#

prophys is one installable package. The Python modelling layer you write models in is documented and unrestricted. Its optimized native kernels perform the numerics and enforce a free tier measured in structural objects:

Tier

Limit

Checked

Free

Up to 250 structural objects per model

When the model is compiled (ProbabilityModel.compile), summed over every structure the model declares, and again by each native operation for the objects it receives

Licensed

No limit

A model within the free tier, the kind of model the examples and figures of this documentation use, runs with no license file at all. Evaluation, teaching, prototyping and small studies never require a licensing step.

What counts#

Structural objects are the entities a model declares. Each declared structure is counted once, however many operations use it, and the counts of all structures of the model are added up:

The inputs of a single native operation are checked against the same limit when it runs: for example the receptors and sources of superpose(), the edges passed to network_potentials() or the cells of a raster passed to ray_integral().

What never counts#

  • Monte Carlo sample counts (n_samples in ProbabilityModel.compile)

  • the number of observations passed to calibrate() or finetune()

  • training steps, optimiser steps and gradient evaluations

  • scalar parameters, random variables and symbolic arithmetic

So you can calibrate a small model against as much data, at as high a Monte Carlo precision, as you like, entirely for free. The license question is only how large the model itself is.

import prophys as prp

# Free tier: 200 houses and a 4-vertex zone, 204 objects in total.
houses = prp.PointList(house_coords_200x2, site)
zone = prp.Polygon(four_vertices, site)

# Also free: marginalising over 10 000 Monte Carlo samples of that model.
compiled = model.compile(n_samples=10_000)

# Needs a license: a model declaring 5 000 points.
many_points = prp.PointList(coords_5000x2, site)

A model beyond the free tier is refused when it is compiled, with a message that names its size:

error[LIC103] this model declares 303 structural objects, which exceeds the
prophys free tier (250 objects per model). Set PROPHYS_LICENSE to a valid
license to compile a model of this size.
  --> ProbabilityModel(d)
   = hint see prp.license_status() and prp.free_tier_limit()

A single operation beyond the limit is refused in the same way when it runs. Nothing is silently truncated, degraded or approximated.

Learned surrogates#

Network and tree surrogates (Learned Surrogates) have a free tier of their own, checked from the network program or tree spec inside the native kernels on every call, on the CPU, on the GPU and in the runtime library.

Surrogate

Free tier

Needs a license

Network

Up to four weighted layers built from dense, residual, Fourier, random Fourier feature and layer norm layers, with any activation and output head

More weighted layers, or any attention layer, LoRA adapter, monotone, input convex or Lipschitz layer, or the time aggregation and Fourier mixer of a neural operator such as DPOT

Tree ensemble

Up to 20 trees of depth up to 4 with fixed split features

More or deeper trees, or learned split features

A surrogate beyond the free tier warns when it is built (LIC101), and a model using it is refused when it is compiled (LIC103) and when it is evaluated.

The pretrained prior fitted network (Prior Fitted Network) is a licensed asset: InContextRegressor.pretrained() loads it only with a valid license and otherwise raises LIC102. It also uses prefix attention, which needs a license to run.

Installing a license#

Set PROPHYS_LICENSE to the path of your license file, or to the license text itself:

export PROPHYS_LICENSE=/path/to/prophys.lic

That is all most installations need. A license is a signed document naming the licensee, the issue date and the expiry date. prophys verifies it offline, so no network connection is required, and a license cannot be forged or its check bypassed from Python. The variable is read again whenever a model is compiled, so a license set after import prophys takes effect without restarting the process.

Machine-locked, site and floating licenses#

A license is bound in one of three ways:

Binding

Where it is valid

Machine-locked

Only on the machines whose fingerprints it lists. Run python -c "import prophys; print(prophys.machine_fingerprint())" on each machine and send the values to RhineQC with your order.

Site

On any machine of the licensee, with no per-machine setup.

Floating

Not tied to a machine; the number of concurrent users is part of the license agreement.

On containers, CI runners and autoscaled cloud machines the host identity changes between runs. Set PROPHYS_MACHINE_ID to a fixed value shared by your fleet and have the license bound to the fingerprint it produces, or ask for a site or floating license instead.

Checking the license#

import prophys as prp

valid, licensee, detail = prp.license_status()
print(valid, licensee, detail)

print(prp.license_binding())     # "unbound", "node", "site" or "floating"
print(prp.free_tier_limit())     # 250

detail explains the status in words. A license that is rejected says why: it has expired, it is bound to other machines, it was issued in the future (which usually means the system clock is wrong), or its text is malformed. Without a valid license prophys keeps running on the free tier.

prophys.license_status()[source]#

Report whether a valid license is active.

Reads PROPHYS_LICENSE again and updates the native kernel gate, so a license set after import prophys takes effect immediately.

Returns:

whether a valid license is active, the licensee it was issued to (empty without a license), and a readable explanation of the status.

Return type:

(valid, licensee, detail)

Example

>>> import prophys as prp
>>> valid, licensee, detail = prp.license_status()
prophys.free_tier_limit()[source]#

Return the free tier limit, the number of structural objects a model may declare without a license.

Structural objects are the entities a model declares: points of a PointList, polygon and polyline vertices, line segments, raster cells, mesh elements and network nodes, summed over the model’s structures when it is compiled. Every native operation also checks the objects it receives (for example the receptors and sources of a physics primitive) against the same limit. Monte Carlo samples, observations and training steps never count. See the license page of the documentation.

Return type:

int

prophys.machine_fingerprint()[source]#

Return this machine’s license fingerprint, for requesting a node locked license.

The fingerprint is a hash of a stable host identifier. It is empty when the machine has none. Set PROPHYS_MACHINE_ID to pin one, which is the recommended setup for containers, CI runners and autoscaled cloud machines.

Return type:

str

prophys.license_binding()[source]#

Return how the active license is bound.

Returns:

"unbound" (no machine check, or no license), "node" (valid on the listed machines only), "site" (any machine of the licensee) or "floating" (not tied to a machine).

Return type:

str