Concrete
WebsiteLibrariesProducts & ServicesDevelopersSupport
2.6
2.6
  • Welcome
  • Get Started
    • What is Concrete?
    • Installation
    • Quick start
    • Compatibility
    • Terminology
  • Core features
    • Overview
    • Table lookups
    • Bit extraction
    • Rounding
    • Truncating
    • Floating points
    • Comparisons
    • Min/Max operations
    • Bitwise operations
    • Common tips
    • Extensions
    • Tagging
  • Compilation
    • Composition
    • Compression
    • Reuse arguments
    • Multi precision
    • Multi parameters
    • Modules
    • Decorator
    • Direct circuits
  • Execution / Analysis
    • Simulation
    • Progressbar
    • Statistics
    • Formatting and drawing
    • Debug
  • Guides
    • Configure
    • Manage keys
    • Deploy
  • Tutorials
    • See all tutorials
    • Part I: Concrete - FHE compiler
    • Part II: The Architecture of Concrete
  • References
    • API
  • Explanations
    • Compiler workflow
    • Frontend fusing
    • Compiler backend
      • Adding a new backend
    • Optimizer
    • MLIR FHE dialects
      • FHELinalg dialect
      • FHE dialect
      • TFHE dialect
      • Concrete dialect
      • Tracing dialect
      • Runtime dialect
      • SDFG dialect
    • Security
    • Call FHE circuits from other languages
    • Project layout
  • Developers
    • Contributing
    • Release note
    • Feature request
    • Bug report
Powered by GitBook

Libraries

  • TFHE-rs
  • Concrete
  • Concrete ML
  • fhEVM

Developers

  • Blog
  • Documentation
  • Github
  • FHE resources

Company

  • About
  • Introduction to FHE
  • Media
  • Careers
On this page

Was this helpful?

Export as PDF
  1. Execution / Analysis

Simulation

PreviousDirect circuitsNextProgressbar

Last updated 1 year ago

Was this helpful?

During development, the speed of homomorphic execution can be a blocker for fast prototyping. You could call the function you're trying to compile directly, of course, but it won't be exactly the same as FHE execution, which has a certain probability of error (see ).

To overcome this issue, simulation is introduced:

from concrete import fhe
import numpy as np

@fhe.compiler({"x": "encrypted"})
def f(x):
    return (x + 1) ** 2

inputset = [np.random.randint(0, 10, size=(10,)) for _ in range(10)]
circuit = f.compile(inputset, p_error=0.1, fhe_simulation=True)

sample = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

actual = f(sample)
simulation = circuit.simulate(sample)

print(actual.tolist())
print(simulation.tolist())

After the simulation runs, it prints the following:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 4, 9, 16, 16, 36, 49, 64, 81, 100]

There are some operations which are not supported in simulation yet. They will result in compilation failures. You can revert to simulation using graph execution using circuit.graph(...) instead of circuit.simulate(...), which won't simulate FHE, but it will evaluate the computation graph, which is like simulating the operations without any errors due to FHE.

Exactness