Skip to content
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# hec-p-isa-tools
HERACLES P-ISA Tools
# HERACLES P-ISA Tools

This repository consists of tools relating to Intel's HERACLES Polynomial-ISA.
Each tool in this repo is self contained and has its own local README.

The set of tools currently includes the [kernel generator](./kerngen).
70 changes: 41 additions & 29 deletions kerngen/README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
# Introduction

This is the kernel generator (kerngen) responsible for producing HERACLES ISA
kernels for various polynomial operations that occur in FHE. A kernel are code
snippets of p-ISA instructions with the purpose of implementing some high level
polynomial gate.
This is the kernel generator (`kerngen`) responsible for producing HERACLES ISA
kernels for various polynomial operations that occur in cryptography (or
elsewhere) such as in homomorphic encryption (HE). A kernel is a code snippet
of p-ISA instructions with the purpose of implementing some high level
polynomial operation.

Kerngen essentially takes an higher level language as input and outputs the
kernels requested.

# Dependencies
`kerngen` is written as a pure python program. Requirements required to be
installed,

- python >= 3.10
- pip
- pip (recommend >= 24.0)
- and python [requirements](./requirements.txt).

and what is listed in the [requirements](./requirements.txt) file. To install
the python dependencies and development tools simply run,
To install the python dependencies and development tools simply run,

```bash
pip -r requirements.txt
Expand All @@ -24,20 +25,27 @@ pip -r requirements.txt
# Implementation

The design is a simplified interpreter pattern. A domain specific language
(DSL) defined as 'high language' is received as input to the kernel generator.
This 'high language' describes FHE scheme and context parameters, as well as
the operation with relative operands. This language is interpreted as a `high
level instruction` which is then mapped to its corresponding `low level p-ISA
instruction`. The resulting ISA kernel is sent to `stdout`.
defined as a 'kernel language' is received as input to the kernel generator.
This kernel language describes (which can be used for HE schemes) operations on
polynomials with given context parameters. This language is interpreted as a
`high level instruction` which is then mapped to its corresponding `low level
p-ISA instruction`. `kerngen` uses a common unix command line utility
convention and the resulting p-ISA kernel is sent to `stdout`.


# Input high language
# Input kernel language

There are several kinds of commands. Keywords that cannot be used for kernel
names `CONTEXT`, `DATA`, `IMMEDIATE`. All other commands are assumed to be
operations. All ops are case insensitive, but the convention we use the
operations capitalized. These are defined in the
[manifest.json](./pisa_generators/manifest.json) file.
names,
```
- `CONTEXT`
- `DATA`
- `IMM`
```

All other commands are assumed to be operations. All operations are case
insensitive, but the convention we use is the operations are capitalized. These
are defined in the [manifest.json](./pisa_generators/manifest.json) file.
```
CONTEXT BGV 8192 4
DATA a 2
Expand All @@ -47,8 +55,8 @@ ADD c a b
```

## CONTEXT
Context defines the global properties `(scheme, poly_order, max_rns)` of the
input script.
Context defines the global properties `(scheme, poly_order, max_rns,
key_rns(optional))` of the input script.
`CONTEXT` sets a global context for properties required by the kernels.
- first field defines what we call scheme. In reality, it specifies the set of
kernel instructions given in the manifest file, see []().
Expand All @@ -57,15 +65,20 @@ kernels how many units (multiples of the native polynomial size) are required
and handled.
- third field defines the max RNS, the global max number of how many moduli that
the kernels can have or need to handle.
- (optional) fourth field defines the key RNS, the number of additional moduli
that the relinearization key has relative to the third field. i.e. If `max_rns`
is 3 and `key_rns` is 1 the total max RNS of the relinearization key will be 4.
Note this field is only required for calling the `relin` kernel.

## DATA
`DATA` defines symbols to be used and their attribute(s) (`num_parts`) where
`num_parts` is the number of polynomials that comprise the data variable.

## IMMEDIATE
`IMMEDIATE` declares a fixed symbol name that can be used for operations that
`IMM` declares a fixed symbol name that can be used for operations that
expect and immediate value(s).


# Generating kernels

The main entry point to the kernel generator is [kerngen.py](kerngen.py). This
Expand All @@ -89,7 +102,7 @@ disabled by passing the `-q` or `--quiet` flag to the kernel generator, i.e.,

You can add new kernel generators that you have developed by creating a class
that inherits from the `HighOp` abstract class (interface) and implementing the
`to_pisa` method; turning this instruction into a p-isa instruction class.
`to_pisa` method; turning this instruction into a p-ISA instruction class.
Examples can be seen in the simpler implementations given in
[basic.py](./pisa_generators/basic.py). Also, provide a class method
`from_string` that will be passed the args for that command.
Expand Down Expand Up @@ -138,7 +151,7 @@ represent the inputs and outputs of the operation. This type represents the
polynomials and holds information such as the `name` of symbol that represents
the polynomial, the number of `parts`, and the `rns`.

At a high level kernels convert high-level operations into low-level p-isa
At a high level kernels convert high-level operations into low-level p-ISA
operations, thus all kernels will need to inherit from `HighOp` and define the
conversion function `to_pisa` as follows
```python
Expand All @@ -151,7 +164,7 @@ class NewKernel(HighOp):
input0: Polys

def to_pisa(self) -> list[PIsaOp]:
"""Return the p-isa equivalent of the NewKernel operation"""
"""Return the p-ISA equivalent of the NewKernel operation"""
```

If the kernel consists of an algorithm already represented by an existing
Expand All @@ -169,8 +182,8 @@ see [square.py](./pisa_generators/square.py) for a complete example of this.

# Mixed operations
You will find that during kernel writing, you will end up with a collection of
either p-isa operation objects, other kernel objects, or a mixture of both. For
your convienince a useful function `mixed_to_pisa_ops` is provided that can
either p-ISA operation objects, other kernel objects, or a mixture of both. For
your convenience a useful function `mixed_to_pisa_ops` is provided that can
take all of these sequentially and outputs the required `list[PIsaOp]`.


Expand All @@ -179,6 +192,5 @@ Tests are provided in the [tests](./tests) directory and use the
[pytest](https://pypi.org/project/pytest/) framework. To run the tests run the
following
```bash
cd tests
pytest .
pytest <test-directory>
```
3 changes: 2 additions & 1 deletion kerngen/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pydantic ~= 2.7
# NOTE pytest requires pydantic to be to be [1.7, 2.0)
pydantic ~= 1.10

# for dev / commits
black ~= 24.3
Expand Down
11 changes: 0 additions & 11 deletions kerngen/scratch

This file was deleted.

2 changes: 1 addition & 1 deletion kerngen/tests/test_kerngen.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def fixture_gen_op_data(request):
f"{request.param} a b c",
)
# TODO: Build this string properly
out = f"13, {Op[request.param].value}, a_0_0_0, b_0_0_0, c_0_0_0, 0"
out = f"0, {Op[request.param].value}, a_0_0_0, b_0_0_0, c_0_0_0, 0"
return "\n".join(in_lines), out


Expand Down