├── .clang-format ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ └── scorecard.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .pylintrc ├── .typos.toml ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── HEADER ├── LICENSE ├── README.md ├── SECURITY.md ├── assembler_tools └── hec-assembler-tools │ ├── README.md │ ├── assembler │ ├── common │ │ ├── __init__.py │ │ ├── config.py │ │ ├── constants.py │ │ ├── counter.py │ │ ├── cycle_tracking.py │ │ ├── decorators.py │ │ ├── priority_queue.py │ │ ├── queue_dict.py │ │ ├── run_config.py │ │ └── utilities.py │ ├── instructions │ │ ├── __init__.py │ │ ├── cinst │ │ │ ├── __init__.py │ │ │ ├── bload.py │ │ │ ├── bones.py │ │ │ ├── cexit.py │ │ │ ├── cinstruction.py │ │ │ ├── cload.py │ │ │ ├── cnop.py │ │ │ ├── cstore.py │ │ │ ├── csyncm.py │ │ │ ├── ifetch.py │ │ │ ├── kgload.py │ │ │ ├── kgseed.py │ │ │ ├── kgstart.py │ │ │ ├── nload.py │ │ │ └── xinstfetch.py │ │ ├── instruction.py │ │ ├── minst │ │ │ ├── __init__.py │ │ │ ├── minstruction.py │ │ │ ├── mload.py │ │ │ ├── mstore.py │ │ │ └── msyncc.py │ │ └── xinst │ │ │ ├── __init__.py │ │ │ ├── add.py │ │ │ ├── copy.py │ │ │ ├── exit.py │ │ │ ├── intt.py │ │ │ ├── irshuffle.py │ │ │ ├── mac.py │ │ │ ├── maci.py │ │ │ ├── move.py │ │ │ ├── mul.py │ │ │ ├── muli.py │ │ │ ├── nop.py │ │ │ ├── ntt.py │ │ │ ├── parse_xntt.py │ │ │ ├── rshuffle.py │ │ │ ├── sub.py │ │ │ ├── twintt.py │ │ │ ├── twntt.py │ │ │ ├── xinstruction.py │ │ │ └── xstore.py │ ├── memory_model │ │ ├── __init__.py │ │ ├── hbm.py │ │ ├── mem_info.py │ │ ├── mem_utilities.py │ │ ├── memory_bank.py │ │ ├── register_file.py │ │ ├── spad.py │ │ └── variable.py │ ├── spec_config │ │ ├── isa_spec.py │ │ └── mem_spec.py │ └── stages │ │ ├── __init__.py │ │ ├── asm_scheduler.py │ │ ├── preprocessor.py │ │ └── scheduler.py │ ├── config │ ├── isa_spec.json │ └── mem_spec.json │ ├── debug_tools │ ├── README.md │ ├── deadlock_test.py │ ├── isolation_test.py │ ├── main.py │ ├── order_test.py │ └── xinst_timing_check │ │ ├── inject_bundles.py │ │ ├── spec_config.py │ │ ├── xinst │ │ ├── __init__.py │ │ ├── add.py │ │ ├── exit.py │ │ ├── intt.py │ │ ├── mac.py │ │ ├── maci.py │ │ ├── move.py │ │ ├── mul.py │ │ ├── muli.py │ │ ├── nop.py │ │ ├── ntt.py │ │ ├── rshuffle.py │ │ ├── sub.py │ │ ├── twintt.py │ │ ├── twntt.py │ │ ├── xinstruction.py │ │ └── xstore.py │ │ └── xtiming_check.py │ ├── docsrc │ ├── changelog.md │ ├── inst_spec │ │ ├── cinst │ │ │ ├── cinst_bload.md │ │ │ ├── cinst_bones.md │ │ │ ├── cinst_cexit.md │ │ │ ├── cinst_cload.md │ │ │ ├── cinst_cstore.md │ │ │ ├── cinst_csyncm.md │ │ │ ├── cinst_ifetch.md │ │ │ ├── cinst_nload.md │ │ │ ├── cinst_nop.md │ │ │ └── cinst_xinstfetch.md │ │ ├── minst │ │ │ ├── minst_mload.md │ │ │ ├── minst_mstore.md │ │ │ └── minst_msyncc.md │ │ └── xinst │ │ │ ├── xinst_add.md │ │ │ ├── xinst_exit.md │ │ │ ├── xinst_intt.md │ │ │ ├── xinst_mac.md │ │ │ ├── xinst_maci.md │ │ │ ├── xinst_move.md │ │ │ ├── xinst_mul.md │ │ │ ├── xinst_muli.md │ │ │ ├── xinst_nop.md │ │ │ ├── xinst_ntt.md │ │ │ ├── xinst_rshuffle.md │ │ │ ├── xinst_sub.md │ │ │ ├── xinst_twintt.md │ │ │ ├── xinst_twntt.md │ │ │ └── xinst_xstore.md │ └── specs.md │ ├── he_as.py │ ├── he_link.py │ ├── he_prep.py │ ├── linker │ ├── __init__.py │ ├── instructions │ │ ├── __init__.py │ │ ├── cinst │ │ │ ├── __init__.py │ │ │ ├── bload.py │ │ │ ├── bones.py │ │ │ ├── cexit.py │ │ │ ├── cinstruction.py │ │ │ ├── cload.py │ │ │ ├── cnop.py │ │ │ ├── cstore.py │ │ │ ├── csyncm.py │ │ │ ├── ifetch.py │ │ │ ├── kgload.py │ │ │ ├── kgseed.py │ │ │ ├── kgstart.py │ │ │ ├── nload.py │ │ │ └── xinstfetch.py │ │ ├── instruction.py │ │ ├── minst │ │ │ ├── __init__.py │ │ │ ├── minstruction.py │ │ │ ├── mload.py │ │ │ ├── mstore.py │ │ │ └── msyncc.py │ │ └── xinst │ │ │ ├── __init__.py │ │ │ ├── add.py │ │ │ ├── exit.py │ │ │ ├── intt.py │ │ │ ├── mac.py │ │ │ ├── maci.py │ │ │ ├── move.py │ │ │ ├── mul.py │ │ │ ├── muli.py │ │ │ ├── nop.py │ │ │ ├── ntt.py │ │ │ ├── rshuffle.py │ │ │ ├── sub.py │ │ │ ├── twintt.py │ │ │ ├── twntt.py │ │ │ ├── xinstruction.py │ │ │ └── xstore.py │ ├── loader.py │ └── steps │ │ ├── __init__.py │ │ ├── program_linker.py │ │ └── variable_discovery.py │ └── requirements.txt ├── docs ├── Encrypted-Computing-SDK │ ├── Overview │ │ ├── EncryptedComputingSDK-Polynomial_Instruction_Set_Architecture_Tools-public.pdf │ │ └── EncryptedComputingSDK-Polynomial_Instruction_Set_Architecture_Tools-public.pptx │ └── empty_file.txt └── images │ ├── SDK_Integration_3rd_party.png │ ├── SDK_Phase_1.png │ └── SDK_Roadmap.png ├── p-isa_tools ├── CMakeLists.txt ├── CPPLINT.cfg ├── cmake │ └── dependencies.cmake ├── common │ ├── CMakeLists.txt │ ├── config.h.in │ ├── graph │ │ └── graph.h │ ├── p_isa │ │ ├── isa_instruction.h │ │ ├── p_isa.h │ │ ├── p_isa_hardware_models.h │ │ ├── p_isa_instruction.cpp │ │ ├── p_isa_instruction.h │ │ ├── p_isa_instructions.h │ │ ├── p_isa_performance_modeler.cpp │ │ ├── p_isa_performance_modeler.h │ │ └── parser │ │ │ ├── p_isa_parser.cpp │ │ │ └── p_isa_parser.h │ ├── string.h │ └── timer │ │ └── timer.h ├── docs │ ├── doxyfile.in │ └── srcs │ │ └── p_isa_instruction_set.md ├── functional_modeler │ ├── CMakeLists.txt │ ├── README.md │ ├── data_handlers │ │ ├── hec_dataformats_handler.h │ │ └── json_data_handler.h │ ├── functional_models │ │ ├── multiregister.h │ │ ├── p_isa_functional_model.h │ │ ├── p_isa_memory_model.h │ │ └── utility_functions.h │ ├── main.cpp │ └── pisa_runtime │ │ ├── p_isa_instruction_trace.h │ │ └── pisaprogramruntime.h └── kerngen │ ├── .gitignore │ ├── README.md │ ├── __init__.py │ ├── high_parser │ ├── __init__.py │ ├── config.py │ ├── generators.py │ ├── options_handler.py │ ├── parser.py │ ├── pisa_operations.py │ └── types.py │ ├── kerngen.py │ ├── pisa_generators │ ├── __init__.py │ ├── basic.py │ ├── decomp.py │ ├── manifest.json │ ├── mod.py │ ├── ntt.py │ ├── relin.py │ ├── rescale.py │ ├── rotate.py │ └── square.py │ ├── requirements.txt │ ├── tests │ └── test_kerngen.py │ └── vsc_kerlang_extension │ ├── .vscodeignore │ ├── LICENSE │ ├── README.md │ ├── grammars │ └── kerlang.tmLanguage.json │ ├── heracles-kerlang-syntax-0.0.1.vsix │ ├── language-configuration.json │ ├── package.json │ └── themes │ └── kerlang.tmTheme.json ├── pytest.ini └── tutorials └── kerngen └── SimpleExamples ├── ADD_16K1rns.ker ├── ADD_16K4rns.ker ├── ADD_C16K1rns_pyramid.ker ├── ADD_C16K4rns.ker ├── MUL_C16K1rns.ker └── RELIN_C16K1rns.ker /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | Language: Cpp 4 | BasedOnStyle: Microsoft 5 | AccessModifierOffset: -4 6 | AlignAfterOpenBracket: Align 7 | AlignConsecutiveAssignments: true 8 | AlignConsecutiveMacros: true 9 | AlignOperands: true 10 | AlignTrailingComments: false 11 | AllowAllArgumentsOnNextLine: true 12 | AllowAllConstructorInitializersOnNextLine: true 13 | AllowAllParametersOfDeclarationOnNextLine: true 14 | AllowShortCaseLabelsOnASingleLine: false 15 | AllowShortFunctionsOnASingleLine: Inline 16 | AllowShortIfStatementsOnASingleLine: false 17 | AllowShortLoopsOnASingleLine: false 18 | AlwaysBreakAfterDefinitionReturnType: None 19 | AlwaysBreakAfterReturnType: None 20 | AlwaysBreakTemplateDeclarations: true 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterCaseLabel: true 25 | AfterClass: true 26 | AfterControlStatement: true 27 | AfterEnum: true 28 | AfterFunction: true 29 | AfterNamespace: false 30 | AfterObjCDeclaration: true 31 | AfterStruct: true 32 | AfterUnion: true 33 | BeforeCatch: true 34 | BeforeElse: true 35 | IndentBraces: false 36 | BreakBeforeBinaryOperators: NonAssignment 37 | BreakBeforeBraces: Custom 38 | BreakBeforeTernaryOperators: false 39 | BreakConstructorInitializers: AfterColon 40 | ColumnLimit: 0 41 | CompactNamespaces: false 42 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 43 | ConstructorInitializerIndentWidth: 4 44 | ContinuationIndentWidth: 4 45 | Cpp11BracedListStyle: false 46 | DerivePointerAlignment: false 47 | FixNamespaceComments: true 48 | IndentCaseLabels: false 49 | IndentPPDirectives: None 50 | IndentWidth: 4 51 | NamespaceIndentation: None 52 | PenaltyBreakBeforeFirstCallParameter: 19 53 | PenaltyBreakComment: 300 54 | PenaltyBreakFirstLessLess: 120 55 | PenaltyBreakString: 1000 56 | PenaltyBreakTemplateDeclaration: 10 57 | PenaltyExcessCharacter: 1000000 58 | PenaltyReturnTypeOnItsOwnLine: 1000 59 | PointerAlignment: Right 60 | SortIncludes: true 61 | SortUsingDeclarations: true 62 | SpaceAfterCStyleCast: false 63 | SpaceAfterLogicalNot: false 64 | SpaceBeforeAssignmentOperators: true 65 | SpaceBeforeCpp11BracedList: false 66 | SpaceBeforeCtorInitializerColon: true 67 | SpaceBeforeInheritanceColon: true 68 | SpaceBeforeParens: ControlStatements 69 | SpaceBeforeRangeBasedForLoopColon: true 70 | SpaceInEmptyParentheses: false 71 | SpacesBeforeTrailingComments: 1 72 | SpacesInAngles: false 73 | SpacesInContainerLiterals: true 74 | SpacesInCStyleCastParentheses: false 75 | SpacesInParentheses: false 76 | SpacesInSquareBrackets: false 77 | ReflowComments: false 78 | UseTab: Never 79 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Version Information (Put N/A for Not Applicable)** 11 | | Software | Version(s) | 12 | | ---------------------------| --------------- | 13 | | Linux | | 14 | | Git | | 15 | | CMake | | 16 | | Compiler (GCC, Clang, etc.)| | 17 | | Python | | 18 | | Doxygen | | 19 | | Kernel Generator | | 20 | | Documentation | | 21 | 22 | **Describe the bug**\ 23 | A clear and concise description of what the bug is. 24 | 25 | **To Reproduce**\ 26 | Steps to reproduce the behavior: 27 | 1. Go to '...' 28 | 2. Click on '....' 29 | 3. Scroll down to '....' 30 | 4. etc. 31 | 5. See error 32 | 33 | **Expected behavior**\ 34 | A clear and concise description of what you expected to happen. 35 | 36 | **Screenshots**\ 37 | If applicable, add screenshots to help explain your problem. 38 | 39 | **Additional context**\ 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.**\ 11 | A clear and concise description of what the problem is. _Ex. I'm always 12 | frustrated when [...]_ 13 | 14 | **Describe the solution you would like**\ 15 | A clear and concise description of what you want to happen. 16 | 17 | **Describe alternatives you have considered**\ 18 | A clear and concise description of any alternative solutions or features you 19 | have considered. 20 | 21 | **Additional context**\ 22 | Add any other context or screenshots about the feature request here. 23 | 24 | **If the feature request is approved, would you be willing to submit a PR**\ 25 | Yes / No _(Help can be provided if you need assistance submitting a PR)_ 26 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Proposed changes 2 | 3 | Describe the big picture of your changes here to communicate to the maintainers 4 | why we should accept this pull request. If it fixes a bug or resolves a feature 5 | request, be sure to link to that issue. 6 | 7 | ## Types of changes 8 | 9 | What types of changes does your code introduce to the Encrypted Computing SDK project? 10 | _Put an `x` in the boxes that apply_ 11 | 12 | - [ ] Bugfix (non-breaking change which fixes an issue) 13 | - [ ] New feature (non-breaking change which adds functionality) 14 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 15 | - [ ] Documentation update (if none of the other choices apply) 16 | 17 | ## Checklist 18 | 19 | _Put an `x` in the boxes that apply. You can also fill these out after creating 20 | the PR. If you are unsure about any of them, do not hesitate to ask. We are 21 | here to help! This is simply a reminder of what we are going to look for before 22 | merging your code._ 23 | 24 | - [ ] I have read the [CONTRIBUTING](https://github.com/IntelLabs/encrypted-computing-sdk/blob/main/CONTRIBUTING.md) agreement 25 | - [ ] Current formatting and unit tests / base functionality passes locally with my changes 26 | - [ ] I have added tests that prove my fix is effective or that my feature works (if appropriate) 27 | - [ ] I have added necessary documentation (if appropriate) 28 | - [ ] Any dependent changes have been merged and published in downstream modules 29 | 30 | ## Further comments 31 | 32 | If this is a relatively large or complex change, kick off the discussion by 33 | explaining why you chose the solution you did, what alternatives you 34 | considered, etc. 35 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "pip" # See documentation for possible values 4 | directory: "/" # Look everywhere for package manifests 5 | schedule: 6 | interval: "weekly" 7 | ignore: 8 | - dependency-name: "*" 9 | update-types: ["version-update:semver-major"] 10 | -------------------------------------------------------------------------------- /.github/workflows/scorecard.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. They are provided 2 | # by a third-party and are governed by separate terms of service, privacy 3 | # policy, and support documentation. 4 | 5 | name: Scorecard supply-chain security 6 | on: 7 | # For Branch-Protection check. Only the default branch is supported. See 8 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection 9 | branch_protection_rule: 10 | # To guarantee Maintained check is occasionally updated. See 11 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained 12 | schedule: 13 | - cron: '44 15 * * 0' 14 | push: 15 | branches: [ "main" ] 16 | pull_request: 17 | branches: [ "main" ] 18 | 19 | # Declare default permissions as read only. 20 | permissions: read-all 21 | 22 | jobs: 23 | analysis: 24 | name: Scorecard analysis 25 | runs-on: ubuntu-latest 26 | permissions: 27 | # Needed to upload the results to code-scanning dashboard. 28 | security-events: write 29 | # Needed to publish results and get a badge (see publish_results below). 30 | id-token: write 31 | 32 | steps: 33 | - name: "Checkout code" 34 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 35 | with: 36 | persist-credentials: false 37 | 38 | - name: "Run analysis" 39 | uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 40 | with: 41 | results_file: results.sarif 42 | results_format: sarif 43 | publish_results: true 44 | 45 | - name: "Upload artifact" 46 | uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 47 | with: 48 | name: SARIF file 49 | path: results.sarif 50 | retention-days: 5 51 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | default_language_version: 5 | # force all unspecified python hooks to run python3 6 | python: python3.10 7 | repos: 8 | - repo: https://github.com/pre-commit/pre-commit-hooks 9 | rev: v4.5.0 # Updated 2024/04 10 | hooks: 11 | - id: trailing-whitespace 12 | - id: end-of-file-fixer 13 | - id: check-merge-conflict 14 | - id: mixed-line-ending 15 | - id: check-yaml 16 | args: 17 | - --allow-multiple-documents 18 | - repo: https://github.com/crate-ci/typos 19 | rev: v1.20.9 # Updated 2024/04 20 | hooks: 21 | - id: typos 22 | - repo: https://github.com/Lucas-C/pre-commit-hooks 23 | rev: v1.5.1 # Updated 2023/07 24 | hooks: 25 | - id: insert-license 26 | name: insert-license-shell 27 | files: \.(sh|py)$ 28 | args: 29 | - --license-filepath 30 | # defaults to: LICENSE.txt 31 | - HEADER 32 | - id: insert-license 33 | name: insert-license-cpp 34 | files: \.(c|cc|cxx|cpp|h|hpp|hxx|inl|h.in)$ 35 | args: 36 | - --license-filepath 37 | # defaults to: LICENSE.txt 38 | - HEADER 39 | - --comment-style 40 | - // # defaults to: # 41 | - id: remove-tabs 42 | name: remove-tabs 43 | files: \.(py)$ 44 | args: [--whitespaces-count, '4'] 45 | - repo: https://github.com/psf/black-pre-commit-mirror 46 | rev: 24.4.0 # Updated 2024/04 47 | hooks: 48 | - id: black 49 | language_version: python3.10 50 | - repo: https://github.com/pre-commit/mirrors-mypy 51 | rev: v1.9.0 # Last checked 2024/04 52 | hooks: 53 | - id: mypy 54 | - repo: local 55 | hooks: 56 | - id: pylint 57 | name: pylint 58 | entry: pylint 59 | language: system 60 | types: [python] 61 | args: 62 | - -rn # Only display messages 63 | - -sn # Don't display the score 64 | - --source-roots=kerngen # Working directory 65 | - id: clang-format-14 66 | name: clang-format-14 67 | entry: clang-format-14 68 | language: system 69 | files: \.(c|cc|cxx|cpp|h|hpp|hxx|inl)$ 70 | args: ["-i", "--style=file"] 71 | - id: cpplint 72 | name: cpplint 73 | entry: cpplint 74 | language: system 75 | files: \.(c|cc|cxx|cpp|h|hpp|hxx)$ 76 | args: 77 | - --recursive 78 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | 3 | # Pylint config containing overrides 4 | [BASIC] 5 | good-names = iN, logN 6 | 7 | [MESSAGES CONTROL] 8 | # W0511 are TODO 9 | disable=W0511 10 | 11 | # pydantic and pylint don't always play nice 12 | # apparently due to libraries with compiled code 13 | [MASTER] 14 | extension-pkg-allow-list=pydantic 15 | 16 | [CLASSES] 17 | # Minimum number of public methods for a class (see R0903). 18 | min-public-methods = 0 19 | 20 | [DESIGN] 21 | 22 | # Maximum number of attributes for a class (see R0902). 23 | max-attributes=8 24 | 25 | [FORMAT] 26 | # `black` takes care of our line lengths, but just in case it gets ridiculous 27 | max-line-length=230 28 | -------------------------------------------------------------------------------- /.typos.toml: -------------------------------------------------------------------------------- 1 | [default] 2 | #extend-ignore-re = ["helo byd"] 3 | 4 | [default.extend-identifiers] 5 | 6 | 7 | [default.extend-words] 8 | # variation of params 9 | parms = "parms" 10 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # Default codeowner for all files 5 | * @faberga @kylanerace @christopherngutierrez @joserochh 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ### License 4 | 5 | The Intel Encrypted Computing SDK project is licensed under the terms in [LICENSE](https://github.com/IntelLabs/encrypted-computing-sdk/blob/main/LICENSE). By contributing to the project, you agree to the license and copyright terms therein and release your contribution under these terms. 6 | 7 | ### Sign your work 8 | 9 | Please use the sign-off line at the end of the patch. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: if you can certify 10 | the below (from [developercertificate.org](http://developercertificate.org/)): 11 | 12 | ``` 13 | Developer Certificate of Origin 14 | Version 1.1 15 | 16 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 17 | 660 York Street, Suite 102, 18 | San Francisco, CA 94110 USA 19 | 20 | Everyone is permitted to copy and distribute verbatim copies of this 21 | license document, but changing it is not allowed. 22 | 23 | Developer's Certificate of Origin 1.1 24 | 25 | By making a contribution to this project, I certify that: 26 | 27 | (a) The contribution was created in whole or in part by me and I 28 | have the right to submit it under the open source license 29 | indicated in the file; or 30 | 31 | (b) The contribution is based upon previous work that, to the best 32 | of my knowledge, is covered under an appropriate open source 33 | license and I have the right under that license to submit that 34 | work with modifications, whether created in whole or in part 35 | by me, under the same open source license (unless I am 36 | permitted to submit under a different license), as indicated 37 | in the file; or 38 | 39 | (c) The contribution was provided directly to me by some other 40 | person who certified (a), (b) or (c) and I have not modified 41 | it. 42 | 43 | (d) I understand and agree that this project and the contribution 44 | are public and that a record of the contribution (including all 45 | personal information I submit with it, including my sign-off) is 46 | maintained indefinitely and may be redistributed consistent with 47 | this project or the open source license(s) involved. 48 | ``` 49 | 50 | Then you just add a line to every git commit message: 51 | 52 | Signed-off-by: Joe Smith 53 | 54 | Use your real name (sorry, no pseudonyms or anonymous contributions.) 55 | 56 | If you set your `user.name` and `user.email` git configs, you can sign your 57 | commit automatically with `git commit -s`. 58 | -------------------------------------------------------------------------------- /HEADER: -------------------------------------------------------------------------------- 1 | Copyright (C) 2024 Intel Corporation 2 | SPDX-License-Identifier: Apache-2.0 3 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. 3 | 4 | ## Reporting a Vulnerability 5 | Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). 6 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/common/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | def makeUniquePath(path: str) -> str: 4 | """ 5 | Returns a unique, normalized, and absolute version of the given file path. 6 | 7 | Args: 8 | path (str): The file path to be processed. 9 | 10 | Returns: 11 | str: A unique, normalized, and absolute version of the input path. 12 | """ 13 | return os.path.normcase(os.path.realpath(os.path.expanduser(path))) 14 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/common/config.py: -------------------------------------------------------------------------------- 1 |  2 | class GlobalConfig: 3 | """ 4 | A configuration class for controlling various aspects of the assembler's behavior. 5 | 6 | Attributes: 7 | suppressComments (bool): 8 | If True, no comments will be emitted in the output generated by the assembler. 9 | 10 | useHBMPlaceHolders (bool): 11 | Specifies whether to use placeholders (names) for variable locations in HBM 12 | or the actual variable locations. 13 | 14 | useXInstFetch (bool): 15 | Specifies whether `xinstfetch` instructions should be added into CInstQ or not. 16 | When no `xinstfetch` instructions are added, it is assumed that the HERACLES 17 | automated mechanism for `xinstfetch` will be activated. 18 | 19 | debugVerbose (int): 20 | If greater than 0, verbose prints will occur. Its value indicates how often to 21 | print within loops (every `debugVerbose` iterations). This is used for internal 22 | debugging purposes. 23 | hashHBM (bool): Specifies whether the target architecture has HBM or not. 24 | """ 25 | 26 | suppressComments = False 27 | useHBMPlaceHolders = True 28 | useXInstFetch = True 29 | debugVerbose: int = 0 30 | hasHBM = True 31 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/common/decorators.py: -------------------------------------------------------------------------------- 1 |  2 | class classproperty(object): 3 | """ 4 | A decorator that allows a method to be accessed as a class-level property 5 | rather than on instances of the class. 6 | """ 7 | 8 | def __init__(self, f): 9 | """ 10 | Initializes the classproperty with the given function. 11 | 12 | Args: 13 | f (function): The function to be used as a class-level property. 14 | """ 15 | self.f = f 16 | 17 | def __get__(self, obj, owner): 18 | """ 19 | Retrieves the value of the class-level property. 20 | 21 | Args: 22 | obj: The instance of the class (ignored in this context). 23 | owner: The class that owns the property. 24 | 25 | Returns: 26 | The result of calling the decorated function with the class as an argument. 27 | """ 28 | return self.f(owner) 29 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/common/utilities.py: -------------------------------------------------------------------------------- 1 | 2 | def clamp(x, minimum = float("-inf"), maximum = float("inf")): 3 | """ 4 | Clamp a value between a specified minimum and maximum. 5 | 6 | This function ensures that a given value `x` is constrained within the 7 | bounds defined by `minimum` and `maximum`. 8 | 9 | Args: 10 | x: The value to be clamped. 11 | minimum (float, optional): The lower bound to clamp `x` to. 12 | maximum (float, optional): The upper bound to clamp `x` to. 13 | 14 | Returns: 15 | The clamped value. 16 | """ 17 | if x < minimum: 18 | return minimum 19 | if x > maximum: 20 | return maximum 21 | return x 22 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/instructions/__init__.py: -------------------------------------------------------------------------------- 1 |  2 | def tokenizeFromLine(line: str) -> list: 3 | """ 4 | Tokenizes a line of text and extracts any comment present. 5 | 6 | This function processes a line of text, removing line breaks and splitting the line 7 | into tokens based on commas. It also identifies and extracts comments, which are 8 | denoted by the pound symbol `#`. 9 | 10 | Args: 11 | line (str): Line of text to tokenize. 12 | 13 | Returns: 14 | tuple: A tuple containing the tokens and the comment. The `tokens` are a tuple of strings, 15 | and `comment` is a string. The `comment` is an empty string if no comment is found in the line. 16 | """ 17 | tokens = tuple() 18 | comment = "" 19 | if line: 20 | line = ''.join(line.splitlines()) # remove line breaks 21 | comment_idx = line.find('#') 22 | if comment_idx >= 0: 23 | # Found a comment 24 | comment = line[comment_idx + 1:] 25 | line = line[:comment_idx] 26 | tokens = tuple(map(lambda s: s.strip(), line.split(','))) 27 | retval = (tokens, comment) 28 | return retval 29 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/instructions/cinst/__init__.py: -------------------------------------------------------------------------------- 1 |  2 | from . import bload, bones, cexit, cload, cnop, cstore, csyncm, ifetch, kgload, kgseed, kgstart, nload, xinstfetch 3 | 4 | # MInst aliases 5 | 6 | BLoad = bload.Instruction 7 | BOnes = bones.Instruction 8 | CExit = cexit.Instruction 9 | CLoad = cload.Instruction 10 | CNop = cnop.Instruction 11 | CStore = cstore.Instruction 12 | CSyncm = csyncm.Instruction 13 | IFetch = ifetch.Instruction 14 | KGLoad = kgload.Instruction 15 | KGSeed = kgseed.Instruction 16 | KGStart = kgstart.Instruction 17 | NLoad = nload.Instruction 18 | XInstFetch = xinstfetch.Instruction 19 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/instructions/cinst/cinstruction.py: -------------------------------------------------------------------------------- 1 | from assembler.common.cycle_tracking import CycleType 2 | from ..instruction import BaseInstruction 3 | 4 | class CInstruction(BaseInstruction): 5 | """ 6 | Represents a CInstruction, which is a type of BaseInstruction. 7 | 8 | This class provides the basic structure and functionality for CInstructions, including 9 | methods for converting to CInst ASM-ISA format. 10 | 11 | Attributes: 12 | id (int): User-defined ID for the instruction. 13 | throughput (int): The throughput of the instruction. 14 | latency (int): The latency of the instruction. 15 | comment (str): An optional comment for the instruction. 16 | """ 17 | 18 | # Constructor 19 | # ----------- 20 | 21 | def __init__(self, 22 | id: int, 23 | throughput : int, 24 | latency : int, 25 | comment: str = ""): 26 | """ 27 | Constructs a new CInstruction. 28 | 29 | Parameters: 30 | id (int): User-defined ID for the instruction. It will be bundled with a nonce to form a unique ID. 31 | throughput (int): The throughput of the instruction. 32 | latency (int): The latency of the instruction. 33 | comment (str, optional): An optional comment for the instruction. 34 | """ 35 | super().__init__(id, throughput, latency, comment=comment) 36 | 37 | 38 | # Methods and properties 39 | # ---------------------- 40 | 41 | def _get_cycle_ready(self): 42 | """ 43 | Returns the cycle ready value for the instruction. 44 | 45 | This method overrides the base method to provide a specific cycle ready value for CInstructions. 46 | 47 | Returns: 48 | CycleType: A CycleType object with bundle and cycle set to 0. 49 | """ 50 | return CycleType(bundle = 0, cycle = 0) 51 | 52 | def _toCASMISAFormat(self, *extra_args) -> str: 53 | """ 54 | Converts the instruction to CInst ASM-ISA format. 55 | 56 | This method constructs the ASM-ISA format string for the instruction by combining 57 | the instruction's sources and destinations with any additional arguments. 58 | 59 | Parameters: 60 | extra_args: Additional arguments for the conversion. 61 | 62 | Returns: 63 | str: The CInst ASM-ISA format string of the instruction. 64 | """ 65 | 66 | preamble = [] 67 | # instruction sources 68 | extra_args = tuple(src.toCASMISAFormat() for src in self.sources) + extra_args 69 | # instruction destinations 70 | extra_args = tuple(dst.toCASMISAFormat() for dst in self.dests) + extra_args 71 | return self.toStringFormat(preamble, 72 | self.OP_NAME_ASM, 73 | *extra_args) 74 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/instructions/minst/__init__.py: -------------------------------------------------------------------------------- 1 |  2 | from . import mload, mstore, msyncc 3 | 4 | # MInst aliases 5 | 6 | MLoad = mload.Instruction 7 | MStore = mstore.Instruction 8 | MSyncc = msyncc.Instruction 9 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/instructions/minst/minstruction.py: -------------------------------------------------------------------------------- 1 | from assembler.common.cycle_tracking import CycleType 2 | from ..instruction import BaseInstruction 3 | 4 | class MInstruction(BaseInstruction): 5 | """ 6 | Represents a memory-level instruction (MInstruction). 7 | 8 | This class is used to encapsulate the properties and behaviors of a memory-level instruction, 9 | including its throughput, latency, and a unique counter value that increases with each 10 | MInstruction created. 11 | 12 | Methods: 13 | count: Returns the MInstruction counter value for this instruction. 14 | """ 15 | 16 | __minst_count = 0 # Internal Minst counter 17 | 18 | def __init__(self, 19 | id: int, 20 | throughput: int, 21 | latency: int, 22 | comment: str = ""): 23 | """ 24 | Constructs a new MInstruction. 25 | 26 | Parameters: 27 | id (int): User-defined ID for the instruction. It will be bundled with a nonce to form a unique ID. 28 | 29 | throughput (int): The throughput of the instruction. 30 | 31 | latency (int): The latency of the instruction. 32 | 33 | comment (str, optional): A comment for the instruction. Defaults to an empty string. 34 | """ 35 | super().__init__(id, throughput, latency, comment=comment) 36 | self.__count = MInstruction.__minst_count 37 | 38 | @property 39 | def count(self): 40 | """ 41 | Returns the MInstruction counter value for this instruction. 42 | 43 | This value monotonically increases per MInstruction created. 44 | 45 | Returns: 46 | int: The counter value for this MInstruction. 47 | """ 48 | return self.__count 49 | 50 | def _get_cycle_ready(self): 51 | """ 52 | Returns a CycleType object indicating when the instruction is ready. 53 | 54 | Returns: 55 | CycleType: A CycleType object with bundle and cycle set to 0. 56 | """ 57 | return CycleType(bundle=0, cycle=0) 58 | 59 | def _toMASMISAFormat(self, *extra_args) -> str: 60 | """ 61 | Converts the instruction to MInst ASM-ISA format. 62 | 63 | See inherited for more information. 64 | 65 | Parameters: 66 | extra_args: Additional arguments for formatting. 67 | 68 | Returns: 69 | str: The instruction in MInst ASM-ISA format. 70 | """ 71 | # Instruction sources 72 | extra_args = tuple(src.toMASMISAFormat() for src in self.sources) + extra_args 73 | # Instruction destinations 74 | extra_args = tuple(dst.toMASMISAFormat() for dst in self.dests) + extra_args 75 | return self.toStringFormat(None, 76 | self.OP_NAME_ASM, 77 | *extra_args) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/assembler/stages/__init__.py: -------------------------------------------------------------------------------- 1 | import networkx as nx 2 | from assembler.memory_model.variable import Variable 3 | 4 | def buildVarAccessListFromTopoSort(dependency_graph: nx.DiGraph): 5 | """ 6 | Given the dependency directed acyclic graph of XInsts, builds the list of 7 | estimated usage order for the variables. 8 | 9 | This is used when deciding which variable to evict from register files or SPAD when 10 | a memory location is needed and all are occupied (furthest used: FTBU). Least recently 11 | used (LRU) is used as tie breaker. 12 | 13 | Usage order is estimated because order of instructions may change based on their 14 | dependencies and timings during scheduling. 15 | 16 | Returns: 17 | list(instruction_id: tuple): 18 | The topological sort of the instructions. Since the topological sort is required 19 | for this function, it is returned to caller to be reused if needed. 20 | """ 21 | 22 | topo_sort = list(nx.topological_sort(dependency_graph)) 23 | for idx, node in enumerate(topo_sort): 24 | instr = dependency_graph.nodes[node]['instruction'] 25 | vars = set(instr.sources + instr.dests) 26 | for v in vars: 27 | v.accessed_by_xinsts.append(Variable.AccessElement(idx, instr.id)) 28 | 29 | return topo_sort 30 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/config/mem_spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "mem_spec": { 3 | "max_cache_size_in_bytes": "64 MiB", 4 | "max_hbm_size_in_bytes": "64 GiB", 5 | "max_xinst_queue_size_in_bytes": "1 MiB", 6 | "max_cinst_queue_size_in_bytes": "128 KiB", 7 | "max_minst_queue_size_in_bytes": "128 KiB", 8 | "max_store_buffer_size_in_bytes": "128 KiB", 9 | "num_register_banks": 4, 10 | "num_registers_per_bank": 72, 11 | "bytes_per_xinstruction": 8, 12 | "max_instructions_per_bundle": 64, 13 | "num_blocks_per_twid_meta_word": 4, 14 | "num_blocks_per_kgseed_meta_word": 4, 15 | "num_routing_table_registers": 1, 16 | "num_ones_meta_registers": 1, 17 | "num_twiddle_meta_registers": 32, 18 | "twiddle_meta_register_size_in_bytes": "8 KiB", 19 | "max_residuals": 64 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/spec_config.py: -------------------------------------------------------------------------------- 1 | import os 2 | import xinst 3 | from assembler.isa_spec import SpecConfig 4 | 5 | class XTC_SpecConfig (SpecConfig): 6 | 7 | __target_xops = { 8 | "add" : xinst.add.Instruction, 9 | "exit" : xinst.exit_mod.Instruction, 10 | "intt" : xinst.intt.Instruction, 11 | "mac" : xinst.mac.Instruction, 12 | "maci" : xinst.maci.Instruction, 13 | "move" : xinst.move.Instruction, 14 | "mul" : xinst.mul.Instruction, 15 | "muli" : xinst.muli.Instruction, 16 | "nop" : xinst.nop.Instruction, 17 | "ntt" : xinst.ntt.Instruction, 18 | "rshuffle" : xinst.rshuffle.Instruction, 19 | "sub" : xinst.sub.Instruction, 20 | "twintt" : xinst.twintt.Instruction, 21 | "twntt" : xinst.twntt.Instruction, 22 | "xstore" : xinst.xstore.Instruction, 23 | } 24 | 25 | _target_ops = { 26 | "xinst": __target_xops 27 | } 28 | 29 | _target_attributes = { 30 | "num_tokens" : "SetNumTokens", 31 | "num_dests" : "SetNumDests", 32 | "num_sources" : "SetNumSources", 33 | "default_throughput" : "SetDefaultThroughput", 34 | "default_latency" : "SetDefaultLatency", 35 | "special_latency_max" : "SetSpecialLatencyMax", 36 | "special_latency_increment": "SetSpecialLatencyIncrement", 37 | } 38 | 39 | @classmethod 40 | def dump_isa_spec_to_json(cls, filename): 41 | """ 42 | Uninmplemented for this child class. 43 | """ 44 | print("WARNING: 'dump_isa_spec_to_json' unimplemented for xinst_timing_check") 45 | 46 | @classmethod 47 | def initialize_isa_spec(cls, module_dir, isa_spec_file): 48 | 49 | if not isa_spec_file: 50 | isa_spec_file = os.path.join(module_dir, "../../config/isa_spec.json") 51 | isa_spec_file = os.path.abspath(isa_spec_file) 52 | 53 | if not os.path.exists(isa_spec_file): 54 | raise FileNotFoundError( 55 | f"Required ISA Spec file not found: {isa_spec_file}\n" 56 | "Please provide a valid path using the `isa_spec` option, " 57 | "or use a valid default file at: `/config/isa_spec.json`." 58 | ) 59 | 60 | cls.init_isa_spec_from_json(isa_spec_file) 61 | 62 | return isa_spec_file 63 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/__init__.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | from . import add, mul, muli, mac, maci, ntt, intt, twntt, twintt, rshuffle, sub, move, xstore, nop 3 | from . import exit as exit_mod 4 | 5 | # XInst aliases 6 | 7 | Add = add.Instruction 8 | Mul = mul.Instruction 9 | Muli = muli.Instruction 10 | Mac = mac.Instruction 11 | Maci = maci.Instruction 12 | NTT = ntt.Instruction 13 | iNTT = intt.Instruction 14 | twNTT = twntt.Instruction 15 | twiNTT = twintt.Instruction 16 | rShuffle = rshuffle.Instruction 17 | Sub = sub.Instruction 18 | Move = move.Instruction 19 | XStore = xstore.Instruction 20 | Exit = exit_mod.Instruction 21 | Nop = nop.Instruction 22 | 23 | # collection of XInstructions with P-ISA or intermediate P-ISA equivalents 24 | ASMISA_INSTRUCTIONS = ( Add, Mul, Muli, Mac, Maci, NTT, iNTT, twNTT, twiNTT, rShuffle, Sub, Move, XStore, Exit, Nop ) 25 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/add.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents an `add` instruction, inheriting from XInstruction. 6 | 7 | This instructions adds two polynomials stored in the register file and 8 | store the result in a register. 9 | 10 | For more information, check the specification: 11 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_add.md 12 | """ 13 | 14 | @classmethod 15 | def fromASMISALine(cls, line: str) -> list: 16 | """ 17 | Parse an ASM ISA line to create an Instruction object. 18 | 19 | Parameters: 20 | line (str): The line of text to parse. 21 | 22 | Returns: 23 | list: An Instruction object if parsing is successful, None otherwise. 24 | 25 | Raises: 26 | ValueError: If the line cannot be parsed into an Instruction. 27 | """ 28 | retval = None 29 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 30 | if tokens: 31 | tokens, comment = tokens 32 | if len(tokens) < 3 or tokens[2] != cls.name: 33 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 34 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 35 | retval = cls(int(tokens[0][1:]), # Bundle 36 | int(tokens[1]), # PISA instruction number 37 | dst_src_map['dst'], 38 | dst_src_map['src'], 39 | cls._OP_DEFAULT_THROUGHPUT, 40 | cls._OP_DEFAULT_LATENCY, 41 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 42 | comment) 43 | return retval 44 | 45 | @classmethod 46 | def _get_name(cls) -> str: 47 | """ 48 | Gets the name of the instruction. 49 | 50 | Returns: 51 | str: The name of the instruction, which is "add". 52 | """ 53 | return "add" 54 | 55 | def __init__(self, 56 | bundle: int, 57 | pisa_instr: int, 58 | dsts: list, 59 | srcs: list, 60 | throughput: int, 61 | latency: int, 62 | other: list = [], 63 | comment: str = ""): 64 | """ 65 | Constructs a new Instruction object. 66 | 67 | Parameters: 68 | bundle (int): The bundle number. 69 | pisa_instr (int): The PISA instruction number. 70 | dsts (list): List of destination registers. 71 | srcs (list): List of source registers. 72 | throughput (int): The throughput of the instruction. 73 | latency (int): The latency of the instruction. 74 | other (list): Additional parameters for the instruction. 75 | comment (str): Optional comment for the instruction. 76 | """ 77 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) 78 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/exit.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents an `bexit` instruction, inheriting from XInstruction. 6 | 7 | This instruction terminates execution of an instruction bundle. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_exit.md 11 | """ 12 | 13 | @classmethod 14 | def fromASMISALine(cls, line: str) -> list: 15 | """ 16 | Parses an ASM ISA line to create an Instruction object. 17 | 18 | Parameters: 19 | line (str): The line of text to parse. 20 | 21 | Returns: 22 | list: An Instruction object if parsing is successful, None otherwise. 23 | 24 | Raises: 25 | ValueError: If the line cannot be parsed into an Instruction. 26 | """ 27 | retval = None 28 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 29 | if tokens: 30 | tokens, comment = tokens 31 | if len(tokens) < 3 or tokens[2] != cls.name: 32 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 33 | retval = cls(int(tokens[0][1:]), # Bundle 34 | int(tokens[1]), # PISA instruction number 35 | [], 36 | [], 37 | cls._OP_DEFAULT_THROUGHPUT, 38 | cls._OP_DEFAULT_LATENCY, 39 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 40 | comment) 41 | return retval 42 | 43 | @classmethod 44 | def _get_name(cls) -> str: 45 | """ 46 | Gets the name of the instruction. 47 | 48 | Returns: 49 | str: The name of the instruction, which is "bexit". 50 | """ 51 | return "bexit" 52 | 53 | def __init__(self, 54 | bundle: int, 55 | pisa_instr: int, 56 | dsts: list, 57 | srcs: list, 58 | throughput: int, 59 | latency: int, 60 | other: list = [], 61 | comment: str = ""): 62 | """ 63 | Constructs a new Instruction object. 64 | 65 | Parameters: 66 | bundle (int): The bundle number. 67 | pisa_instr (int): The PISA instruction number. 68 | dsts (list): List of destination registers. 69 | srcs (list): List of source registers. 70 | throughput (int): The throughput of the instruction. 71 | latency (int): The latency of the instruction. 72 | other (list): Additional parameters for the instruction. 73 | comment (str): Optional comment for the instruction. 74 | """ 75 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/intt.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents an `intt` instruction, inheriting from XInstruction. 6 | 7 | The Inverse Number Theoretic Transform (iNTT), converts NTT form to positional form. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_intt.md 11 | """ 12 | 13 | @classmethod 14 | def fromASMISALine(cls, line: str) -> list: 15 | """ 16 | Parses an ASM ISA line to create an Instruction object. 17 | 18 | Parameters: 19 | line (str): The line of text to parse. 20 | 21 | Returns: 22 | list: An Instruction object if parsing is successful, None otherwise. 23 | 24 | Raises: 25 | ValueError: If the line cannot be parsed into an Instruction. 26 | """ 27 | retval = None 28 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 29 | if tokens: 30 | tokens, comment = tokens 31 | if len(tokens) < 3 or tokens[2] != cls.name: 32 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 33 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 34 | retval = cls(int(tokens[0][1:]), # Bundle 35 | int(tokens[1]), # PISA instruction number 36 | dst_src_map['dst'], 37 | dst_src_map['src'], 38 | cls._OP_DEFAULT_THROUGHPUT, 39 | cls._OP_DEFAULT_LATENCY, 40 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 41 | comment) 42 | return retval 43 | 44 | @classmethod 45 | def _get_name(cls) -> str: 46 | """ 47 | Gets the name of the instruction. 48 | 49 | Returns: 50 | str: The name of the instruction, which is "intt". 51 | """ 52 | return "intt" 53 | 54 | def __init__(self, 55 | bundle: int, 56 | pisa_instr: int, 57 | dsts: list, 58 | srcs: list, 59 | throughput: int, 60 | latency: int, 61 | other: list = [], 62 | comment: str = ""): 63 | """ 64 | Constructs a new Instruction object. 65 | 66 | Parameters: 67 | bundle (int): The bundle number. 68 | pisa_instr (int): The PISA instruction number. 69 | dsts (list): List of destination registers. 70 | srcs (list): List of source registers. 71 | throughput (int): The throughput of the instruction. 72 | latency (int): The latency of the instruction. 73 | other (list): Additional parameters for the instruction. 74 | comment (str): Optional comment for the instruction. 75 | """ 76 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/mac.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents a `mac` Instruction for element-wise polynomial multiplication and accumulation. 6 | 7 | For more information, check the specification: 8 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_mac.md 9 | 10 | Methods: 11 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 12 | """ 13 | 14 | @classmethod 15 | def fromASMISALine(cls, line: str) -> list: 16 | """ 17 | Parses an ASM ISA line to create an Instruction instance. 18 | 19 | Args: 20 | line (str): The ASM ISA line to parse. 21 | 22 | Returns: 23 | list: A list containing the parsed Instruction instance. 24 | 25 | Raises: 26 | ValueError: If the line cannot be parsed into the expected format. 27 | """ 28 | retval = None 29 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 30 | if tokens: 31 | tokens, comment = tokens 32 | if len(tokens) < 3 or tokens[2] != cls.name: 33 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 34 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 35 | retval = cls(int(tokens[0][1:]), # Bundle 36 | int(tokens[1]), # Pisa 37 | dst_src_map['dst'], 38 | dst_src_map['src'], 39 | cls._OP_DEFAULT_THROUGHPUT, 40 | cls._OP_DEFAULT_LATENCY, 41 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 42 | comment) 43 | return retval 44 | 45 | @classmethod 46 | def _get_name(cls) -> str: 47 | """ 48 | Gets the name of the instruction. 49 | 50 | Returns: 51 | str: The name of the instruction, which is "mac". 52 | """ 53 | return "mac" 54 | 55 | def __init__(self, 56 | bundle: int, 57 | pisa_instr: int, 58 | dsts: list, 59 | srcs: list, 60 | throughput: int, 61 | latency: int, 62 | other: list = [], 63 | comment: str = ""): 64 | """ 65 | Initializes an Instruction instance. 66 | 67 | Args: 68 | bundle (int): The bundle identifier. 69 | pisa_instr (int): The PISA instruction identifier. 70 | dsts (list): The list of destination operands. 71 | srcs (list): The list of source operands. 72 | throughput (int): The throughput of the instruction. 73 | latency (int): The latency of the instruction. 74 | other (list, optional): Additional parameters. Defaults to an empty list. 75 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 76 | """ 77 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/maci.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents a `maci` Instruction. 6 | 7 | Element-wise polynomial scaling by an immediate value and accumulation. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_maci.md 11 | 12 | Methods: 13 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 14 | """ 15 | 16 | @classmethod 17 | def fromASMISALine(cls, line: str) -> list: 18 | """ 19 | Parses an ASM ISA line to create an Instruction instance. 20 | 21 | Args: 22 | line (str): The ASM ISA line to parse. 23 | 24 | Returns: 25 | list: A list containing the parsed Instruction instance. 26 | 27 | Raises: 28 | ValueError: If the line cannot be parsed into the expected format. 29 | """ 30 | retval = None 31 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 32 | if tokens: 33 | tokens, comment = tokens 34 | if len(tokens) < 3 or tokens[2] != cls.name: 35 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 36 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 37 | retval = cls(int(tokens[0][1:]), # Bundle 38 | int(tokens[1]), # Psisa 39 | dst_src_map['dst'], 40 | dst_src_map['src'], 41 | cls._OP_DEFAULT_THROUGHPUT, 42 | cls._OP_DEFAULT_LATENCY, 43 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 44 | comment) 45 | return retval 46 | 47 | @classmethod 48 | def _get_name(cls) -> str: 49 | """ 50 | Gets the name of the instruction. 51 | 52 | Returns: 53 | str: The name of the instruction, which is "maci". 54 | """ 55 | return "maci" 56 | 57 | def __init__(self, 58 | bundle: int, 59 | pisa_instr: int, 60 | dsts: list, 61 | srcs: list, 62 | throughput: int, 63 | latency: int, 64 | other: list = [], 65 | comment: str = ""): 66 | """ 67 | Initializes an Instruction instance. 68 | 69 | Args: 70 | bundle (int): The bundle identifier. 71 | pisa_instr (int): The PISA instruction identifier. 72 | dsts (list): The list of destination operands. 73 | srcs (list): The list of source operands. 74 | throughput (int): The throughput of the instruction. 75 | latency (int): The latency of the instruction. 76 | other (list, optional): Additional parameters. Defaults to an empty list. 77 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 78 | """ 79 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/move.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents a `move` Instruction. 6 | 7 | This instruction copies data from one register to a different one. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_move.md 11 | 12 | Methods: 13 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 14 | """ 15 | 16 | @classmethod 17 | def fromASMISALine(cls, line: str) -> list: 18 | """ 19 | Parses an ASM ISA line to create an Instruction instance. 20 | 21 | Args: 22 | line (str): The ASM ISA line to parse. 23 | 24 | Returns: 25 | list: A list containing the parsed Instruction instance. 26 | 27 | Raises: 28 | ValueError: If the line cannot be parsed into the expected format. 29 | """ 30 | retval = None 31 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 32 | if tokens: 33 | tokens, comment = tokens 34 | if len(tokens) < 3 or tokens[2] != cls.name: 35 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 36 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 37 | retval = cls(int(tokens[0][1:]), # Bundle 38 | int(tokens[1]), # Pisa 39 | dst_src_map['dst'], 40 | dst_src_map['src'], 41 | cls._OP_DEFAULT_THROUGHPUT, 42 | cls._OP_DEFAULT_LATENCY, 43 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 44 | comment) 45 | return retval 46 | 47 | @classmethod 48 | def _get_name(cls) -> str: 49 | """ 50 | Gets the name of the instruction. 51 | 52 | Returns: 53 | str: The name of the instruction, which is "move". 54 | """ 55 | return "move" 56 | 57 | def __init__(self, 58 | bundle: int, 59 | pisa_instr: int, 60 | dsts: list, 61 | srcs: list, 62 | throughput: int, 63 | latency: int, 64 | other: list = [], 65 | comment: str = ""): 66 | """ 67 | Initializes an Instruction instance. 68 | 69 | Args: 70 | bundle (int): The bundle identifier. 71 | pisa_instr (int): The PISA instruction identifier. 72 | dsts (list): The list of destination operands. 73 | srcs (list): The list of source operands. 74 | throughput (int): The throughput of the instruction. 75 | latency (int): The latency of the instruction. 76 | other (list, optional): Additional parameters. Defaults to an empty list. 77 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 78 | """ 79 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/mul.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents a `mul` Instruction. 6 | 7 | This instructions performs element-wise polynomial multiplication. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_mul.md 11 | 12 | Methods: 13 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 14 | """ 15 | 16 | @classmethod 17 | def fromASMISALine(cls, line: str) -> list: 18 | """ 19 | Parses an ASM ISA line to create an Instruction instance. 20 | 21 | Args: 22 | line (str): The ASM ISA line to parse. 23 | 24 | Returns: 25 | list: A list containing the parsed Instruction instance. 26 | 27 | Raises: 28 | ValueError: If the line cannot be parsed into the expected format. 29 | """ 30 | retval = None 31 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 32 | if tokens: 33 | tokens, comment = tokens 34 | if len(tokens) < 3 or tokens[2] != cls.name: 35 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 36 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 37 | retval = cls(int(tokens[0][1:]), # Bundle 38 | int(tokens[1]), # Pisa 39 | dst_src_map['dst'], 40 | dst_src_map['src'], 41 | cls._OP_DEFAULT_THROUGHPUT, 42 | cls._OP_DEFAULT_LATENCY, 43 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 44 | comment) 45 | return retval 46 | 47 | @classmethod 48 | def _get_name(cls) -> str: 49 | """ 50 | Gets the name of the instruction. 51 | 52 | Returns: 53 | str: The name of the instruction, which is "mul". 54 | """ 55 | return "mul" 56 | 57 | def __init__(self, 58 | bundle: int, 59 | pisa_instr: int, 60 | dsts: list, 61 | srcs: list, 62 | throughput: int, 63 | latency: int, 64 | other: list = [], 65 | comment: str = ""): 66 | """ 67 | Initializes an Instruction instance. 68 | 69 | Args: 70 | bundle (int): The bundle identifier. 71 | pisa_instr (int): The PISA instruction identifier. 72 | dsts (list): The list of destination operands. 73 | srcs (list): The list of source operands. 74 | throughput (int): The throughput of the instruction. 75 | latency (int): The latency of the instruction. 76 | other (list, optional): Additional parameters. Defaults to an empty list. 77 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 78 | """ 79 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/muli.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents a `muli` Instruction. 6 | 7 | This instruction performs element-wise polynomial scaling by an immediate value. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_muli.md 11 | 12 | Methods: 13 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 14 | """ 15 | 16 | @classmethod 17 | def fromASMISALine(cls, line: str) -> list: 18 | """ 19 | Parses an ASM ISA line to create an Instruction instance. 20 | 21 | Args: 22 | line (str): The ASM ISA line to parse. 23 | 24 | Returns: 25 | list: A list containing the parsed Instruction instance. 26 | 27 | Raises: 28 | ValueError: If the line cannot be parsed into the expected format. 29 | """ 30 | retval = None 31 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 32 | if tokens: 33 | tokens, comment = tokens 34 | if len(tokens) < 3 or tokens[2] != cls.name: 35 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 36 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 37 | retval = cls(int(tokens[0][1:]), # Bundle 38 | int(tokens[1]), # Pisa 39 | dst_src_map['dst'], 40 | dst_src_map['src'], 41 | cls._OP_DEFAULT_THROUGHPUT, 42 | cls._OP_DEFAULT_LATENCY, 43 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 44 | comment) 45 | return retval 46 | 47 | @classmethod 48 | def _get_name(cls) -> str: 49 | """ 50 | Gets the name of the instruction. 51 | 52 | Returns: 53 | str: The name of the instruction, which is "muli". 54 | """ 55 | return "muli" 56 | 57 | def __init__(self, 58 | bundle: int, 59 | pisa_instr: int, 60 | dsts: list, 61 | srcs: list, 62 | throughput: int, 63 | latency: int, 64 | other: list = [], 65 | comment: str = ""): 66 | """ 67 | Initializes an Instruction instance. 68 | 69 | Args: 70 | bundle (int): The bundle identifier. 71 | pisa_instr (int): The PISA instruction identifier. 72 | dsts (list): The list of destination operands. 73 | srcs (list): The list of source operands. 74 | throughput (int): The throughput of the instruction. 75 | latency (int): The latency of the instruction. 76 | other (list, optional): Additional parameters. Defaults to an empty list. 77 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 78 | """ 79 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/nop.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents a `nop` Instruction. 6 | 7 | This instruction adds a desired amount of idle cycles to the compute flow. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_nop.md 11 | 12 | Methods: 13 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 14 | """ 15 | 16 | @classmethod 17 | def fromASMISALine(cls, line: str) -> list: 18 | """ 19 | Parses an ASM ISA line to create an Instruction instance. 20 | 21 | Args: 22 | line (str): The ASM ISA line to parse. 23 | 24 | Returns: 25 | list: A list containing the parsed Instruction instance. 26 | 27 | Raises: 28 | ValueError: If the line cannot be parsed into the expected format. 29 | """ 30 | retval = None 31 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 32 | if tokens: 33 | tokens, comment = tokens 34 | if len(tokens) < 4 or tokens[2] != cls.name: 35 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 36 | idle_cycles = int(tokens[3]) + 1 37 | retval = cls( 38 | int(tokens[0][1:]), # Bundle 39 | int(tokens[1]), # Pisa 40 | [], 41 | [], 42 | idle_cycles, 43 | idle_cycles, 44 | tokens[3:], 45 | comment 46 | ) 47 | return retval 48 | 49 | @classmethod 50 | def _get_name(cls) -> str: 51 | """ 52 | Gets the name of the instruction. 53 | 54 | Returns: 55 | str: The name of the instruction, which is "nop". 56 | """ 57 | return "nop" 58 | 59 | def __init__(self, 60 | bundle: int, 61 | pisa_instr: int, 62 | dsts: list, 63 | srcs: list, 64 | throughput: int, 65 | latency: int, 66 | other: list = [], 67 | comment: str = ""): 68 | """ 69 | Initializes an Instruction instance. 70 | 71 | Args: 72 | bundle (int): The bundle identifier. 73 | pisa_instr (int): The PISA instruction identifier. 74 | dsts (list): The list of destination operands. 75 | srcs (list): The list of source operands. 76 | throughput (int): The throughput of the instruction. 77 | latency (int): The latency of the instruction. 78 | other (list, optional): Additional parameters. Defaults to an empty list. 79 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 80 | """ 81 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/ntt.py: -------------------------------------------------------------------------------- 1 | from argparse import Namespace 2 | 3 | from .xinstruction import XInstruction 4 | 5 | class Instruction(XInstruction): 6 | """ 7 | Represents an `ntt` instruction (Number Theoretic Transform). 8 | 9 | Converts positional form to NTT form. 10 | For more information, check the specification: 11 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_ntt.md 12 | 13 | Methods: 14 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 15 | """ 16 | 17 | @classmethod 18 | def fromASMISALine(cls, line: str) -> list: 19 | """ 20 | Parses an ASM ISA line to create an Instruction instance. 21 | 22 | Args: 23 | line (str): The ASM ISA line to parse. 24 | 25 | Returns: 26 | list: A list containing the parsed Instruction instance. 27 | 28 | Raises: 29 | ValueError: If the line cannot be parsed into the expected format. 30 | """ 31 | retval = None 32 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 33 | if tokens: 34 | tokens, comment = tokens 35 | if len(tokens) < 3 or tokens[2] != cls.name: 36 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 37 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 38 | retval = cls(int(tokens[0][1:]), # bundle 39 | int(tokens[1]), # pisa 40 | dst_src_map['dst'], 41 | dst_src_map['src'], 42 | cls._OP_DEFAULT_THROUGHPUT, 43 | cls._OP_DEFAULT_LATENCY, 44 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 45 | comment) 46 | return retval 47 | 48 | @classmethod 49 | def _get_name(cls) -> str: 50 | """ 51 | Gets the name of the instruction. 52 | 53 | Returns: 54 | str: The name of the instruction, which is "ntt". 55 | """ 56 | return "ntt" 57 | 58 | def __init__(self, 59 | bundle: int, 60 | pisa_instr: int, 61 | dsts: list, 62 | srcs: list, 63 | throughput: int, 64 | latency: int, 65 | other: list = [], 66 | comment: str = ""): 67 | """ 68 | Initializes an Instruction instance. 69 | 70 | Args: 71 | bundle (int): The bundle identifier. 72 | pisa_instr (int): The PISA instruction identifier. 73 | dsts (list): The list of destination operands. 74 | srcs (list): The list of source operands. 75 | throughput (int): The throughput of the instruction. 76 | latency (int): The latency of the instruction. 77 | other (list, optional): Additional parameters. Defaults to an empty list. 78 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 79 | """ 80 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/sub.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents a `sub` Instruction. 6 | 7 | This instruction performs element-wise polynomial subtraction. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_sub.md 11 | 12 | Methods: 13 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 14 | """ 15 | 16 | @classmethod 17 | def fromASMISALine(cls, line: str) -> list: 18 | """ 19 | Parses an ASM ISA line to create an Instruction instance. 20 | 21 | Args: 22 | line (str): The ASM ISA line to parse. 23 | 24 | Returns: 25 | list: A list containing the parsed Instruction instance. 26 | 27 | Raises: 28 | ValueError: If the line cannot be parsed into the expected format. 29 | """ 30 | retval = None 31 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 32 | if tokens: 33 | tokens, comment = tokens 34 | if len(tokens) < 3 or tokens[2] != cls.name: 35 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 36 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 37 | retval = cls(int(tokens[0][1:]), # Bundle 38 | int(tokens[1]), # Pisa 39 | dst_src_map['dst'], 40 | dst_src_map['src'], 41 | cls._OP_DEFAULT_THROUGHPUT, 42 | cls._OP_DEFAULT_LATENCY, 43 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 44 | comment) 45 | return retval 46 | 47 | @classmethod 48 | def _get_name(cls) -> str: 49 | """ 50 | Gets the name of the instruction. 51 | 52 | Returns: 53 | str: The name of the instruction, which is "sub". 54 | """ 55 | return "sub" 56 | 57 | def __init__(self, 58 | bundle: int, 59 | pisa_instr: int, 60 | dsts: list, 61 | srcs: list, 62 | throughput: int, 63 | latency: int, 64 | other: list = [], 65 | comment: str = ""): 66 | """ 67 | Initializes an Instruction instance. 68 | 69 | Args: 70 | bundle (int): The bundle identifier. 71 | pisa_instr (int): The PISA instruction identifier. 72 | dsts (list): The list of destination operands. 73 | srcs (list): The list of source operands. 74 | throughput (int): The throughput of the instruction. 75 | latency (int): The latency of the instruction. 76 | other (list, optional): Additional parameters. Defaults to an empty list. 77 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 78 | """ 79 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/twintt.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents a `twintt` Instruction. 6 | 7 | This instruction performs on-die generation of twiddle factors for the next stage of iNTT. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_twintt.md 11 | 12 | Methods: 13 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 14 | """ 15 | 16 | @classmethod 17 | def fromASMISALine(cls, line: str) -> list: 18 | """ 19 | Parses an ASM ISA line to create an Instruction instance. 20 | 21 | Args: 22 | line (str): The ASM ISA line to parse. 23 | 24 | Returns: 25 | list: A list containing the parsed Instruction instance. 26 | 27 | Raises: 28 | ValueError: If the line cannot be parsed into the expected format. 29 | """ 30 | retval = None 31 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 32 | if tokens: 33 | tokens, comment = tokens 34 | if len(tokens) < 3 or tokens[2] != cls.name: 35 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 36 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 37 | retval = cls(int(tokens[0][1:]), # Bundle 38 | int(tokens[1]), # Pisa 39 | dst_src_map['dst'], 40 | dst_src_map['src'], 41 | cls._OP_DEFAULT_THROUGHPUT, 42 | cls._OP_DEFAULT_LATENCY, 43 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 44 | comment) 45 | return retval 46 | 47 | @classmethod 48 | def _get_name(cls) -> str: 49 | """ 50 | Gets the name of the instruction. 51 | 52 | Returns: 53 | str: The name of the instruction, which is "twntt". 54 | """ 55 | return "twntt" 56 | 57 | def __init__(self, 58 | bundle: int, 59 | pisa_instr: int, 60 | dsts: list, 61 | srcs: list, 62 | throughput: int, 63 | latency: int, 64 | other: list = [], 65 | comment: str = ""): 66 | """ 67 | Initializes an Instruction instance. 68 | 69 | Args: 70 | bundle (int): The bundle identifier. 71 | pisa_instr (int): The PISA instruction identifier. 72 | dsts (list): The list of destination operands. 73 | srcs (list): The list of source operands. 74 | throughput (int): The throughput of the instruction. 75 | latency (int): The latency of the instruction. 76 | other (list, optional): Additional parameters. Defaults to an empty list. 77 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 78 | """ 79 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/debug_tools/xinst_timing_check/xinst/twntt.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Represents a `twntt` Instruction. 6 | 7 | This instruction performs on-die generation of twiddle factors for the next stage of NTT. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_twntt.md 11 | 12 | Methods: 13 | fromASMISALine: Parses an ASM ISA line to create an Instruction instance. 14 | """ 15 | 16 | @classmethod 17 | def fromASMISALine(cls, line: str) -> list: 18 | """ 19 | Parses an ASM ISA line to create an Instruction instance. 20 | 21 | Args: 22 | line (str): The ASM ISA line to parse. 23 | 24 | Returns: 25 | list: A list containing the parsed Instruction instance. 26 | 27 | Raises: 28 | ValueError: If the line cannot be parsed into the expected format. 29 | """ 30 | retval = None 31 | tokens = XInstruction.tokenizeFromASMISALine(cls.name, line) 32 | if tokens: 33 | tokens, comment = tokens 34 | if len(tokens) < 3 or tokens[2] != cls.name: 35 | raise ValueError('`line`: could not parse f{cls.name} from specified line.') 36 | dst_src_map = XInstruction.parseASMISASourceDestsFromTokens(tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, 3) 37 | retval = cls(int(tokens[0][1:]), # Bundle 38 | int(tokens[1]), # Pisa 39 | dst_src_map['dst'], 40 | dst_src_map['src'], 41 | cls._OP_DEFAULT_THROUGHPUT, 42 | cls._OP_DEFAULT_LATENCY, 43 | tokens[3 + cls._OP_NUM_DESTS + cls._OP_NUM_SOURCES:], 44 | comment) 45 | return retval 46 | 47 | @classmethod 48 | def _get_name(cls) -> str: 49 | """ 50 | Gets the name of the instruction. 51 | 52 | Returns: 53 | str: The name of the instruction, which is "twintt". 54 | """ 55 | return "twintt" 56 | 57 | def __init__(self, 58 | bundle: int, 59 | pisa_instr: int, 60 | dsts: list, 61 | srcs: list, 62 | throughput: int, 63 | latency: int, 64 | other: list = [], 65 | comment: str = ""): 66 | """ 67 | Initializes an Instruction instance. 68 | 69 | Args: 70 | bundle (int): The bundle identifier. 71 | pisa_instr (int): The PISA instruction identifier. 72 | dsts (list): The list of destination operands. 73 | srcs (list): The list of source operands. 74 | throughput (int): The throughput of the instruction. 75 | latency (int): The latency of the instruction. 76 | other (list, optional): Additional parameters. Defaults to an empty list. 77 | comment (str, optional): A comment associated with the instruction. Defaults to an empty string. 78 | """ 79 | super().__init__(bundle, pisa_instr, dsts, srcs, throughput, latency, other, comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### 2025-05-23 4 | - First release of the HERACLES Code Generation Framework (Reference Implementation) 5 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_bload.md: -------------------------------------------------------------------------------- 1 | # BLOAD - CInst {#bload_CInst} 2 | 3 | Load metadata from scratchpad to register file. 4 | 5 | ## Definition 6 | 7 | Loads metadata from scratchpad to special registers in register file. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | 10 | |-|-|-|-| 11 | | bload | meta_target_idx | spad_src | src_col_num | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 1 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `meta_target_idx` | int32 | Metadata register index in the range `[0, 32)`. | 24 | | `spad_src` | spad_addr | SPAD address of metadata variable to load. | 25 | | `src_col_num` | int32 | Block number inside metadata source variable in the range `[0, 4)` (see notes). | 26 | 27 | ### Notes 28 | 29 | **Uses SPAD-CE data path**: Yes 30 | 31 | Some operations require metadata to indicate parameters and modes of operation that don't change throughout the execution of a program. Metadata is usually loaded once at the start of the program into special registers in the CE. 32 | 33 | The main use of this type of metadata is to generate twiddle factors. 34 | 35 | The destination registers for this instruction are special metadata registers of size 1/4 word. Each is indexed by parameter `meta_target_idx`. 36 | 37 | The source metadata to load is a word in SPAD addressed by `spad_src`. It needs to be partitioned into 4 blocks of size 1/4 word each to fit into the target registers. Since the smallest addressable unit is the word, `bload` features the parameter `src_col_num` to address the block inside the word as shown in the diagram below. 38 | 39 | ``` 40 | word [--------------------------] 41 | block [--0--][--1--][--2--][--3--] 42 | ``` 43 | 44 | Metadata sources must be loaded into the destination registers in the order they appear. If there are `N` metadata variables to load, metadata target index, `meta_target_idx`, monotonically increases with every `bload` from `0` to `4 * N - 1 < 32`. 45 | 46 | There are only 32 destination registers in the CE, supporting up to 8 words of metadata. If there are more words of metadata, then metadata needs to be swapped as needed, requiring tracking of which metadata is loaded for twiddle factor generation. 47 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_bones.md: -------------------------------------------------------------------------------- 1 | # BONES - CInst {#bones_CInst} 2 | 3 | Load metadata of identity (one) from scratchpad to register file. 4 | 5 | ## Definition 6 | 7 | Loads metadata of identity representation for cryptographic operations from scratchpad to special registers in register file. 8 | 9 | | instr | operand 0 | operand 1 | 10 | |-|-|-| 11 | | bones | spad_src | col_num | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 5 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `spad_src` | spad_addr | SPAD address of identity metadata to load. | 24 | | `col_num` | int32 | Block to load from source word. Must be `0` | 25 | 26 | ### Notes 27 | 28 | **Uses SPAD-CE data path**: Yes 29 | 30 | The metadata block for identity is always `0`. 31 | 32 | Some operations require metadata to indicate parameters and modes of operation that don't change throughout the execution of the program. Metadata is loaded once at the start of the program into special registers in the CE. 33 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_cexit.md: -------------------------------------------------------------------------------- 1 | # CEXIT - CInst {#exit_CInst} 2 | 3 | Exits a program. 4 | 5 | ## Definition 6 | 7 | Terminates execution of a HERACLES program. 8 | 9 | | instr | 10 | |-| 11 | | cexit | 12 | 13 | ## Timing 14 | 15 | **Throughput**: `1` clock cycle 16 | 17 | **Latency**: `1` clock cycle 18 | 19 | ## Details 20 | 21 | This instruction has no operands. 22 | 23 | ### Notes 24 | 25 | **Uses SPAD-CE data path**: No 26 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_cload.md: -------------------------------------------------------------------------------- 1 | # CLOAD - CInst {#cload_CInst} 2 | 3 | Load a single polynomial residue from scratchpad into a register. 4 | 5 | ## Definition 6 | 7 | Load a word, corresponding to a single polynomial residue, from scratchpad memory into the register file memory. 8 | 9 | | instr | operand 0 | operand 1 | 10 | |-|-|-| 11 | | cload | dst | src | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 4 clock cycles 16 | 17 | **Latency**: 4 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | register | Destination register where to load the word. | 24 | | `src` | spad_addr | SPAD address from where to load. | 25 | 26 | ### Notes 27 | 28 | **Uses SPAD-CE data path**: Yes 29 | 30 | The register is ready to be used on the clock cycle after `cload` completes. Using the register during `cload` is undefined. 31 | 32 | Instruction `cload` writes to CE registers and thus, it can conflict with another XInst if both are writing to the same bank and get scheduled such that their write phases happen on the same cycle. Because the rule that there cannot be more than one write to the same bank in the same cycle this conflict must be avoided. 33 | 34 | Two ways to mitigate the above conflict are: 35 | 36 | - Carefully track and sync `cload` instructions with all XInsts. 37 | - Use a convention such that `cload` instructions always write to one bank while all other XInsts cannot write their outputs to that bank. 38 | 39 | We have adopted the second option to implement the assembler. First option is cumbersome and prone to errors: By convention, `cload` should always load into **bank 0**. No XInst can write outputs to **bank 0**. 40 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_cstore.md: -------------------------------------------------------------------------------- 1 | # CSTORE - CInst {#cstore_CInst} 2 | 3 | Fetch a single polynomial residue from the intermediate data buffer and store back to SPAD. 4 | 5 | ## Definition 6 | 7 | Pops the top word from the intermediate data buffer queue and stores it in SPAD. 8 | 9 | | instr | operand 0 | 10 | |-|-| 11 | | cstore | dst | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycles* 16 | 17 | **Latency**: 1 clock cycles* 18 | 19 | Variable timing because `cstore` is a blocking instruction. See notes. 20 | 21 | ## Details 22 | 23 | | Operand | Type | Description | 24 | |-|-|-| 25 | | `dst` | spad_addr | Destination SPAD address where to store the word. | 26 | 27 | ### Notes 28 | 29 | **Uses SPAD-CE data path**: No (see XInst [`xstore`](../xinst/xinst_xstore.md) ). 30 | 31 | This instruction will pop the word at the top of the intermediate buffer queue where Xinst `xstore` pushes data to store from CE registers. 32 | 33 | WARNING: If the intermediate buffer is empty, `cstore` blocks the CINST queue execution until there is data ready to pop. Produced code must ensure that there is data in the intermediate buffer, or that there will be a matching `xstore` in the bundle being executed to avoid a deadlock. 34 | 35 | ## See Also 36 | 37 | - CInst [`xstore`](../xinst/xinst_xstore.md) 38 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_csyncm.md: -------------------------------------------------------------------------------- 1 | # CSYNCM - CInst {#csyncm_CInst} 2 | 3 | CINST execution waits for a particular Mfetch instruction to complete. 4 | 5 | ## Definition 6 | 7 | Wait instruction similar to a barrier that stalls the execution of CINST queue until the specified instruction from MINST queue has completed. 8 | 9 | | instr | operand 0 | 10 | |-|-| 11 | | csyncm | inst_num | 12 | 13 | ## Timing 14 | 15 | **Throughput**: varies 16 | 17 | **Latency**: Same as throughput. 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `inst_num` | int32 | Instruction number from the MINST queue for which to wait. | 24 | 25 | ### Notes 26 | 27 | **Uses SPAD-CE data path**: No 28 | 29 | CINST execution resumes with the following instruction in the CINST queue, on the clock cycle after the specified MInst completed. 30 | 31 | Typically used to wait for a value to be loaded from HBM into SPAD. Since load times from HBM vary, assembler cannot assume that all `mload`s from MINST queue will complete in order, thus, every `mload` should have a matching `csyncm`. 32 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_ifetch.md: -------------------------------------------------------------------------------- 1 | # IFETCH - CInst {#ifetch_CInst} 2 | 3 | Fetch a bundle of instructions for execution. 4 | 5 | ## Definition 6 | 7 | Fetch a bundle of instructions from the XINST queue and send it to the CE for execution. 8 | 9 | | instr | operand 0 | 10 | |-|-| 11 | | ifetch | bundle_idx | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycles `*` 16 | 17 | `*` This instruction has the ability to block execution of CINST queue. See details. 18 | 19 | **Latency**: 5 clock cycles 20 | 21 | ## Details 22 | 23 | | Operand | Type | Description | 24 | |-|-|-| 25 | | `bundle_idx` | int32 | Index for the bundle of instructions to fetch. The bundle must exist in the current XINST queue. | 26 | 27 | ### Notes 28 | 29 | **Uses SPAD-CE data path**: Yes 30 | 31 | A bundle is a collection of a pre-defined number contiguous instructions. The instructions in the bundle must have a minimum throughput of 64 clock cycles (except when there is an `exit` instruction in the bundle). The bundle index to which an instruction belongs is clearly indicated in the encoding of the instruction output by the assembler. 32 | 33 | XINST queue contains the instructions for the CE. This queue contains more than one bundle at a time. Instruction `ifetch` schedules the next bundle (from those bundles in XINST) to execute into the CE. 34 | 35 | It takes `ifetch` 2 cycles to start, and 4 more cycles before the CE is completely loaded with the entry point to the new bundle. 36 | 37 | The loaded bundle starts execution in the clock cycle after `ifetch` completed. 38 | 39 | Calling another `ifetch` while a bundle is executing causes undefined behavior. Thus, a new bundle should be fetched after the last bundle's latency elapses. 40 | 41 | Note that this instruction uses the SPAD-CE data path, so, code produced must ensure that an `ifetch` is not executed when a XInst `xstore` is in flight from the current bundle in-flight. This can be mitigated by a matching `cstore` before `ifetch`. 42 | 43 | `*` XINST queue content is filled out by instruction [`xinstfetch`](cinst_xinstfetch.md) . Instruction `xinstfetch` has a variable latency, and there may be occasions when an `ifetch` is encountered while the referenced bundle is part of code still being loaded by `xinstfetch`. If this is the case, `ifetch` will block until the bundle is ready. 44 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_nload.md: -------------------------------------------------------------------------------- 1 | # NLOAD - CInst {#nload_CInst} 2 | 3 | Loads NTT/iNTT routing mapping data. 4 | 5 | ## Definition 6 | 7 | Loads metadata (for NTT/iNTT routing mapping) from scratchpad into a special routing table register. 8 | 9 | | instr | operand 0 | operand 1 | 10 | |-|-|-| 11 | | nload | table_idx_dst | spad_src | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 4 clock cycles 16 | 17 | **Latency**: 4 clock cycless 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `table_idx_dst` | int32 | Destination routing table. Must be in range `[0, 6)` as there are 6 possible routing tables. | 24 | | `spad_src` | spad_addr | SPAD address of metadata variable to load. | 25 | 26 | ### Notes 27 | 28 | **Uses SPAD-CE data path**: Yes 29 | 30 | This instruction loads metadata indicating how will [`rshuffle`](../xinst/xinst_rshuffle.md) instruction shuffle tile pair registers for NTT outputs and iNTT inputs. Shuffling for one of these instructions requires two tables: routing table and auxiliary table. Therefore, the 6 special table registers only support 3 different shuffling operations (NTT, iNTT, and MISC). 31 | 32 | In the current HERACLES implementation, only routing tables `0` and `1` are functional, thus, assembler is able to perform only shuffling instructions for one of NTT or iNTT per bundle, requiring routing table changes whenever the other is needed. 33 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_nop.md: -------------------------------------------------------------------------------- 1 | # NOP - CInst {#nop_CInst} 2 | 3 | Adds desired amount of idle cycles in the Cfetch flow. 4 | 5 | ## Definition 6 | 7 | Introduces idle cycles in the CINST execution flow. 8 | 9 | | instr | operand 0 | 10 | |-|-| 11 | | cnop | cycles | 12 | 13 | ## Timing 14 | 15 | **Throughput**: `1 + cycles` clock cycles 16 | 17 | **Latency**: `1 + cycles` clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `cycles` | int, 10bits | Number of idle cycles to introduce (see notes). | 24 | 25 | ### Notes 26 | 27 | **Uses SPAD-CE data path**: No 28 | 29 | Note that this instruction will cause the compute flow to stall for `1 + cycles` since it takes 1 clock cycle to dispatch the instruction. Therefore, to introduce a single idle cycle, the correct instruction is: 30 | 31 | ``` 32 | cnop, 0 33 | ``` 34 | 35 | Parameter `cycles` is encoded into a 10 bits field, and thus, its value must be less than 1024. If more thatn 1024 idle cycles is required, multiple `cnop` instructions must be scheduled back to back. 36 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/cinst/cinst_xinstfetch.md: -------------------------------------------------------------------------------- 1 | # XINTFETCH - CInst {#xinstfetch_CInst} 2 | 3 | Fetches instructions from the HBM and sends it to the XINST queue. 4 | 5 | ## Definition 6 | 7 | Fetches 1 word (32KB) worth of instructions from the HBM XInst region and sends it to the XINST queue. 8 | 9 | | instr | operand 0 | operand 1 | 10 | |-|-|-| 11 | | xinstfetch | xq_dst | hbm_src | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycles 16 | 17 | **Latency**: Varies 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `xq_dst` | int32 | Dest in XINST queue. | 24 | | `hbm_src` | hbm_addr | Address where to read instructions from HBM XInst region. | 25 | 26 | ### Notes 27 | 28 | **Uses SPAD-CE data path**: No (See CInst [`ifetch`](cinst_ifetch.md)) 29 | 30 | This instruction is special because it moves XInst data from HBM into XINST queue bypassing SPAD because SPAD is cache only for actual data (not instructions). 31 | 32 | Parameter `hbm_src` refers to an HBM address from the XInst region, not the HBM data region. 33 | 34 | The destination `xq_dst` indexes the XINST queue word-wise; this is, the 1MB XINST queue capacity is equivalent to 32 words capacity. Thus this parameter is between `0` and `31` and indicates where to load the XInst inside XINST queue. 35 | 36 | Instruction `xinstfetch` only loads the XInst to execute, but does not initiate their execution. This is initiated by instruction [`ifetch`](cinst_ifetch.md). 37 | 38 | The latency when accessing HBM varies, therefore, there is no specific latency for this instruction. 39 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/minst/minst_mload.md: -------------------------------------------------------------------------------- 1 | # MLOAD - MInst {#mload_MInst} 2 | 3 | Load a single polynomial residue from local memory to scratchpad. 4 | 5 | ## Definition 6 | 7 | Load a word, corresponding to a single polynomial residue, from HBM data region into the SPAD memory. 8 | 9 | | instr | operand 0 | operand 1 | 10 | |-|-|-| 11 | | mload | dst | src | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycles 16 | 17 | **Latency**: varies 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | spad_addr | Destination SPAD address where to load the word. | 24 | | `src` | hbm_addr | HBM data region address from where to load. | 25 | 26 | ### Notes 27 | 28 | Latency for read/write times involving HBM vary. CINST queue can use `csyncm` instruction to synchronize with the MINST queue. On the other hand, MINST can use `msyncc` to synchronize with CINST queue. 29 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/minst/minst_mstore.md: -------------------------------------------------------------------------------- 1 | # MSTORE - MInst {#mstore_MInst} 2 | 3 | Store a single polynomial residue from scratchpad to local memory. 4 | 5 | ## Definition 6 | 7 | Store a word, corresponding to a single polynomial residue, from SPAD memory into HBM data region. 8 | 9 | | instr | operand 0 | operand 1 | 10 | |-|-|-| 11 | | mstore | dst | src | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycles 16 | 17 | **Latency**: varies 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | hbm_addr | Destination HBM data region address where to store the word. | 24 | | `src` | spad_addr | SPAD address of the word to store. | 25 | 26 | ### Notes 27 | 28 | Latency for read/write times involving HBM vary. CINST queue can use `csyncm` instruction to synchronize with the MINST queue. On the other hand, MINST can use `msyncc` to synchronize with CINST queue. 29 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/minst/minst_msyncc.md: -------------------------------------------------------------------------------- 1 | # MSYNCC - MInst {#msyncc_MInst} 2 | 3 | MINST execution waits for a particular instruction in CINST queue to complete. 4 | 5 | ## Definition 6 | 7 | Wait instruction similar to a barrier that stalls the execution of MINST queue until the specified instruction from CINST queue has completed. 8 | 9 | | instr | operand 0 | 10 | |-|-| 11 | | msyncc | inst_num | 12 | 13 | ## Timing 14 | 15 | **Throughput**: varies 16 | 17 | **Latency**: Same as throughput. 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `inst_num` | int32 | Instruction number from the QINST queue for which to wait. | 24 | 25 | ### Notes 26 | 27 | MINST execution resumes with the following instruction in the MINST queue, on the clock cycle after the specified CInst completed. 28 | 29 | Typically used to wait for a value cached in SPAD to be updated before storing it into HMB. 30 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_add.md: -------------------------------------------------------------------------------- 1 | # ADD - XInst {#add_XInst} 2 | 3 | Element-wise polynomial addition. 4 | 5 | ## Definition 6 | 7 | Add two polynomials stored in the register file and store the result in a register. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | 10 | |-|-|-|-|-| 11 | | add | dst | src0 | src1 | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | register | Destination register for result of `src0 + src1`. | 24 | | `src0` | register | Source register for first operand. | 25 | | `src1` | register | Source register for second operand. Must be different than `src0`. | 26 | | `res` | int32 | Residue to use for modular reduction | 27 | 28 | ### Notes 29 | 30 | **Uses SPAD-CE data path**: No 31 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_exit.md: -------------------------------------------------------------------------------- 1 | # EXIT - XInst {#exit_XInst} 2 | 3 | Terminates execution of an instruction bundle. 4 | 5 | ## Definition 6 | 7 | Terminates execution of an instruction bundle at the point it is encountered. CE will stop execution until a new bundle is enqueued. 8 | 9 | | instr | 10 | |-| 11 | | bexit | 12 | 13 | ## Timing 14 | 15 | **Throughput**: `1` clock cycle 16 | 17 | **Latency**: `1` clock cycle 18 | 19 | ## Details 20 | 21 | This instruction has no operands. 22 | 23 | ### Notes 24 | 25 | **Uses SPAD-CE data path**: No 26 | 27 | As bundles require a minimum of 64 cycles to execute, `exit` is used as a bundle exit instruction to maximize the efficiency of short (incomplete) bundles. 28 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_intt.md: -------------------------------------------------------------------------------- 1 | # iNTT - XInst {#intt_XInst} 2 | 3 | Inverse Number Theoretic Transform. Convert NTT form to positional form. 4 | 5 | ## Definition 6 | 7 | Performs one-stage of inverse NTT. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | operand 4 | operand 5 | operand 6 | 10 | |-|-|-|-|-|-|-|-| 11 | | intt | dst_top | dest_bot | src_top | src_bot | src_tw | stage | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst_top` | register | Destination register for top part of the iNTT result. | 24 | | `dst_bot` | register | Destination register for bottom part of the iNTT result. Must be different than `dst_top`. | 25 | | `src_top` | register | Source register for top part of the input NTT. | 26 | | `src_bot` | register | Source register for bottom part of the input NTT. Must be different than `src_top`. | 27 | | `src_tw` | register | Source register for twiddle factors. Must be different than `src_top` and `src_bot`. | 28 | | `stage` | int32 | Stage number of the current iNTT instruction. | 29 | | `res` | int32 | Residue to use for modular reduction. | 30 | 31 | ### Notes 32 | 33 | **Uses SPAD-CE data path**: No 34 | 35 | Both NTT and inverse NTT instructions are defined as one-stage of the transformation. A complete NTT/iNTT transformation is composed of LOG_N such one-stage instructions. 36 | 37 | This instruction matches to HERACLES ISA `intt`. It requires a preceeding, matching [`rmove`](xinst_rmove.md) to shuffle the input bits into correct tile-pairs. 38 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_mac.md: -------------------------------------------------------------------------------- 1 | # MAC - XInst {#mac_XInst} 2 | 3 | Element-wise polynomial multiplication and accumulation. 4 | 5 | ## Definition 6 | 7 | Element-wise multiplication of two polynomials added to a third polynomial, all stored in the register file, and store the result in a register. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | operand 4 | 10 | |-|-|-|-|-|-| 11 | | mac | dst | src0 | src1 | src2 | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | register | Destination register for result of `src1[i] * src2[i] + src0[i]`. | 24 | | `src0` | register | Source register for first operand. Must be the same as `dst`. | 25 | | `src1` | register | Source register for second operand. Must be different than `src0`. | 26 | | `src2` | register | Source register for third operand. Must be different than `src0` and `src1`. | 27 | | `res` | int32 | Residue to use for modular reduction | 28 | 29 | ### Notes 30 | 31 | **Uses SPAD-CE data path**: No 32 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_maci.md: -------------------------------------------------------------------------------- 1 | # MACI - XInst {#maci_XInst} 2 | 3 | Element-wise polynomial scaling by an immediate value and accumulation. 4 | 5 | ## Definition 6 | 7 | Scale a polynomial in the register file by an immediate added to a third polynomial stored in a register, and store the result in a register. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | operand 4 | 10 | |-|-|-|-|-|-| 11 | | maci | dst | src0 | src1 | imm | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | register | Destination register for result of `src1[i] * imm[i] + src0[i]`. | 24 | | `src0` | register | Source register for first operand. Must be same as `dst`. | 25 | | `src1` | register | Source register for second operand. Must be different than `src0`. | 26 | | `imm` | string | Named immediate value. | 27 | | `res` | int32 | Residue to use for modular reduction | 28 | 29 | ### Notes 30 | 31 | **Uses SPAD-CE data path**: No 32 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_move.md: -------------------------------------------------------------------------------- 1 | # MOVE - XInst {#move_XInst} 2 | 3 | Copies data from one register to a different one. 4 | 5 | ## Definition 6 | 7 | Copies data from a source register into a different destination register. 8 | 9 | | instr | operand 0 | operand 1 | 10 | |-|-|-| 11 | | move | dst | src | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | register | Destination register. | 24 | | `src` | register | Source register to copy. Must be different than `dst`, but can be in the same bank. | 25 | 26 | ### Notes 27 | 28 | **Uses SPAD-CE data path**: No 29 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_mul.md: -------------------------------------------------------------------------------- 1 | # MUL - XInst {#mul_XInst} 2 | 3 | Element-wise polynomial multiplication. 4 | 5 | ## Definition 6 | 7 | Element-wise multiplication of two polynomials stored in the register file and store the result in a register. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | 10 | |-|-|-|-|-| 11 | | mul | dst | src0 | src1 | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | register | Destination register for result of `src0[i] * src1[i]`. | 24 | | `src0` | register | Source register for first operand. | 25 | | `src1` | register | Source register for second operand. Must be different than `src0`. | 26 | | `res` | int32 | Residue to use for modular reduction | 27 | 28 | ### Notes 29 | 30 | **Uses SPAD-CE data path**: No 31 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_muli.md: -------------------------------------------------------------------------------- 1 | # MULI - XInst {#muli_XInst} 2 | 3 | Element-wise polynomial scaling by an immediate value. 4 | 5 | ## Definition 6 | 7 | Scale a polynomial in the register file by an immediate and store the result in a register. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | 10 | |-|-|-|-|-| 11 | | muli | dst | src0 | imm | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | register | Destination register for result of `src0[i] * imm[i]`. | 24 | | `src0` | register | Source register for first operand. | 25 | | `imm` | string | Named immediate value. | 26 | | `res` | int32 | Residue to use for modular reduction | 27 | 28 | ### Notes 29 | 30 | **Uses SPAD-CE data path**: No 31 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_nop.md: -------------------------------------------------------------------------------- 1 | # NOP - XInst {#nop_XInst} 2 | 3 | Adds desired amount of idle cycles to the compute flow. 4 | 5 | ## Definition 6 | 7 | Introduces idle cycles in the compute engine. 8 | 9 | | instr | operand 0 | 10 | |-|-| 11 | | nop | cycles | 12 | 13 | ## Timing 14 | 15 | **Throughput**: `1 + cycles` clock cycles 16 | 17 | **Latency**: `1 + cycles` clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `cycles` | int32 | Number of idle cycles to introduce (see notes). | 24 | 25 | ### Notes 26 | 27 | **Uses SPAD-CE data path**: No 28 | 29 | Note that this instruction will cause the compute flow to stall for `1 + cycles` since it takes 1 clock cycle to dispatch the instruction. Therefore, to introduce a single idle cycle, the correct instruction is: 30 | 31 | ``` 32 | nop, 0 33 | ``` 34 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_ntt.md: -------------------------------------------------------------------------------- 1 | # NTT - XInst {#ntt_XInst} 2 | 3 | Number Theoretic Transform. Convert positional form to NTT form. 4 | 5 | ## Definition 6 | 7 | Performs one-stage of NTT on an input positional polynomial. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | operand 4 | operand 5 | operand 6 | 10 | |-|-|-|-|-|-|-|-| 11 | | ntt | dst_top | dest_bot | src_top | src_bot | src_tw | stage | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst_top` | register | Destination register for top part of the NTT result. | 24 | | `dst_bot` | register | Destination register for bottom part of the NTT result. Must be different than `dst_top`. | 25 | | `src_top` | register | Source register for top part of the input polynomial. | 26 | | `src_bot` | register | Source register for bottom part of the input polynomial. Must be different than `src_top`. | 27 | | `src_tw` | register | Source register for original twiddle factors. Must be different than `src_top` and `src_bot`. | 28 | | `stage` | int32 | Stage number of the current NTT instruction. | 29 | | `res` | int32 | Residue to use for modular reduction. | 30 | 31 | ### Notes 32 | 33 | **Uses SPAD-CE data path**: No 34 | 35 | Both NTT and inverse NTT instructions are defined as one-stage of the transformation. A complete NTT/iNTT transformation is composed of LOG_N such one-stage instructions. 36 | 37 | This instruction matches to HERACLES ISA `ntt` with `store_local` bit set. i.e. it requires a subsequent, matching [`rmove`](xinst_rmove.md) to shuffle the output bits into correct tile-pairs. 38 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_sub.md: -------------------------------------------------------------------------------- 1 | # SUB - XInst {#sub_XInst} 2 | 3 | Element-wise polynomial subtraction. 4 | 5 | ## Definition 6 | 7 | Add two polynomials stored in the register file and store the result in a register. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | 10 | |-|-|-|-|-| 11 | | sub | dst | src0 | src1 | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst` | register | Destination register for result of `src0 - src1`. | 24 | | `src0` | register | Source register for first operand. | 25 | | `src1` | register | Source register for second operand. Must be different than `src0`. | 26 | | `res` | int32 | Residue to use for modular reduction | 27 | 28 | ### Notes 29 | 30 | **Uses SPAD-CE data path**: No 31 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_twintt.md: -------------------------------------------------------------------------------- 1 | # TWiNTT - XInst {#twintt_XInst} 2 | 3 | Compute twiddle factors for iNTT. 4 | 5 | ## Definition 6 | 7 | Performs on-die generation of twiddle factors for the next stage of iNTT. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | operand 4 | operand 5 | operand 6 | 10 | |-|-|-|-|-|-|-|-| 11 | | twintt | dst_tw | src_tw | tw_meta | stage | block | ring_dim | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst_tw` | register | Destination register for resulting twiddles. | 24 | | `src_tw` | register | Source register for original twiddle values. | 25 | | `tw_meta` | int32 | Indexing information of the twiddle metadata. | 26 | | `stage` | int32 | Stage number of the corresponding iNTT instruction | 27 | | `block` | int32 | Index of current 16k polynomial chunk. | 28 | | `ring_dim` | int32 | Ring dimension. This is `PMD = 2^ring_dim`, where `PMD` is the poly-modulus degree. | 29 | | `res` | int32 | Residue to use for modular reduction. | 30 | 31 | ### Notes 32 | 33 | **Uses SPAD-CE data path**: No 34 | 35 | Both NTT and inverse NTT instructions are defined as one-stage of the transformation. A complete NTT/iNTT transformation is composed of LOG_N such one-stage instructions. 36 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_twntt.md: -------------------------------------------------------------------------------- 1 | # TWNTT - XInst {#twntt_XInst} 2 | 3 | Compute twiddle factors for NTT. 4 | 5 | ## Definition 6 | 7 | Performs on-die generation of twiddle factors for the next stage of NTT. 8 | 9 | | instr | operand 0 | operand 1 | operand 2 | operand 3 | operand 4 | operand 5 | operand 6 | 10 | |-|-|-|-|-|-|-|-| 11 | | twntt | dst_tw | src_tw | tw_meta | stage | block | ring_dim | res | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 6 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `dst_tw` | register | Destination register for resulting twiddles. | 24 | | `src_tw` | register | Source register for original twiddle values. | 25 | | `tw_meta` | int32 | Indexing information of the twiddle metadata. | 26 | | `stage` | int32 | Stage number of the corresponding NTT instruction | 27 | | `block` | int32 | Index of current 16k polynomial chunk. | 28 | | `ring_dim` | int32 | Ring dimension. This is `PMD = 2^ring_dim`, where `PMD` is the poly-modulus degree. | 29 | | `res` | int32 | Residue to use for modular reduction. | 30 | 31 | ### Notes 32 | 33 | **Uses SPAD-CE data path**: No 34 | 35 | Both NTT and inverse NTT instructions are defined as one-stage of the transformation. A complete NTT/iNTT transformation is composed of LOG_N such one-stage instructions. 36 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/docsrc/inst_spec/xinst/xinst_xstore.md: -------------------------------------------------------------------------------- 1 | # XSTORE - XInst {#xstore_XInst} 2 | 3 | Transfers data from a register into the intermediate data buffer for subsequent transfer into SPAD. 4 | 5 | ## Definition 6 | 7 | Transfers a word from a CE register into the intermediate data buffer. The intermediate data buffer features a FIFO structure, which means that the transferred data is pushed at the end of the queue. 8 | 9 | | instr | operand 0 | 10 | |-|-| 11 | | xstore | src | 12 | 13 | ## Timing 14 | 15 | **Throughput**: 1 clock cycle 16 | 17 | **Latency**: 4 clock cycles 18 | 19 | ## Details 20 | 21 | | Operand | Type | Description | 22 | |-|-|-| 23 | | `src` | register | Source register to store into SPAD. | 24 | 25 | ### Notes 26 | 27 | **Uses SPAD-CE data path**: Yes 28 | 29 | This instruction pushes data blindly into the intermediate data buffer in a LIFO structure. It is the responsibility of the CINST execution queue to pop this data buffer timely, via `cstore` instruction, to avoid overflows. 30 | 31 | The data will be ready in the intermediate data buffer queue one clock cycle after `xstore` completes. Writing to the `src` register during `xstore` is undefined. 32 | 33 | ## See Also 34 | 35 | - CInst [`cstore`](../cinst/cinst_cstore.md) 36 | - CInst [`cload`](../cinst/cinst_cload.md) 37 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/__init__.py: -------------------------------------------------------------------------------- 1 | from assembler.instructions import tokenizeFromLine 2 | from linker.instructions.instruction import BaseInstruction 3 | 4 | def fromStrLine(line: str, factory) -> BaseInstruction: 5 | """ 6 | Parses an instruction from a line of text. 7 | 8 | Parameters: 9 | line (str): Line of text from which to parse an instruction. 10 | 11 | Returns: 12 | BaseInstruction or None: The parsed BaseInstruction object, or None if no object could be 13 | parsed from the specified input line. 14 | """ 15 | retval = None 16 | tokens, comment = tokenizeFromLine(line) 17 | for instr_type in factory: 18 | try: 19 | retval = instr_type(tokens, comment) 20 | except: 21 | retval = None 22 | if retval: 23 | break 24 | 25 | return retval 26 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/__init__.py: -------------------------------------------------------------------------------- 1 |  2 | from . import bload, bones, cexit, cload, cnop, cstore, csyncm, ifetch, kgload, kgseed, kgstart, nload, xinstfetch 3 | 4 | # MInst aliases 5 | 6 | BLoad = bload.Instruction 7 | BOnes = bones.Instruction 8 | CExit = cexit.Instruction 9 | CLoad = cload.Instruction 10 | CNop = cnop.Instruction 11 | CStore = cstore.Instruction 12 | CSyncm = csyncm.Instruction 13 | IFetch = ifetch.Instruction 14 | KGLoad = kgload.Instruction 15 | KGSeed = kgseed.Instruction 16 | KGStart = kgstart.Instruction 17 | NLoad = nload.Instruction 18 | XInstFetch = xinstfetch.Instruction 19 | 20 | def factory() -> set: 21 | """ 22 | Creates a set of all instruction classes. 23 | 24 | Returns: 25 | set: A set containing all instruction classes. 26 | """ 27 | 28 | return { BLoad, 29 | BOnes, 30 | CExit, 31 | CLoad, 32 | CNop, 33 | CStore, 34 | CSyncm, 35 | IFetch, 36 | KGLoad, 37 | KGSeed, 38 | KGStart, 39 | NLoad, 40 | XInstFetch } 41 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/bload.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates the `bload` CInstruction. 6 | 7 | The `bload` instruction loads metadata from the scratchpad to special registers in the register file. 8 | 9 | For more information, check the `bload` Specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_bload.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls)->int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `bload` instruction requires 5 tokens: 19 | , bload, , , 20 | 21 | Returns: 22 | int: The number of tokens, which is 5. 23 | """ 24 | # 5 tokens: 25 | # , bload, , , 26 | # No HBM variant: 27 | # , bload, , , 28 | return 5 29 | 30 | @classmethod 31 | def _get_name(cls) -> str: 32 | """ 33 | Gets the name of the instruction. 34 | 35 | Returns: 36 | str: The name of the instruction, which is "bload". 37 | """ 38 | return "bload" 39 | 40 | def __init__(self, tokens: list, comment: str = ""): 41 | """ 42 | Constructs a new `bload` CInstruction. 43 | 44 | Args: 45 | tokens (list): A list of tokens representing the instruction. 46 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 47 | 48 | Raises: 49 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 50 | """ 51 | super().__init__(tokens, comment=comment) 52 | 53 | 54 | @property 55 | def source(self) -> str: 56 | """ 57 | Name of the source. 58 | This is a Variable name when loaded. Should be set to HBM address to write back. 59 | """ 60 | return self.tokens[3] 61 | 62 | @source.setter 63 | def source(self, value: str): 64 | self.tokens[3] = value 65 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/bones.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `bones` CInstruction. 6 | 7 | The `bones` instruction loads metadata of identity (one) from the scratchpad to the register file. 8 | 9 | For more information, check the `bones` Specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_bones.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls)->int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `bones` instruction requires 4 tokens: 19 | , bones, , 20 | 21 | Returns: 22 | int: The number of tokens, which is 4. 23 | """ 24 | # 4 tokens: 25 | # , bones, , 26 | # No HBM variant: 27 | # , bones, , 28 | return 4 29 | 30 | @classmethod 31 | def _get_name(cls) -> str: 32 | """ 33 | Gets the name of the instruction. 34 | 35 | Returns: 36 | str: The name of the instruction, which is "bones". 37 | """ 38 | return "bones" 39 | 40 | def __init__(self, tokens: list, comment: str = ""): 41 | """ 42 | Constructs a new `bones` CInstruction. 43 | 44 | Args: 45 | tokens (list): A list of tokens representing the instruction. 46 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 47 | 48 | Raises: 49 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 50 | """ 51 | super().__init__(tokens, comment=comment) 52 | 53 | @property 54 | def source(self) -> str: 55 | """ 56 | Name of the source. 57 | This is a Variable name when loaded. Should be set to HBM address to write back. 58 | """ 59 | return self.tokens[2] 60 | 61 | @source.setter 62 | def source(self, value: str): 63 | self.tokens[2] = value 64 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/cexit.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `cexit` CInstruction. 6 | 7 | This instruction terminates execution of a HERACLES program. 8 | 9 | For more information, check the `cexit` Specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_cexit.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `cexit` instruction requires 2 tokens: 19 | , cexit 20 | 21 | Returns: 22 | int: The number of tokens, which is 2. 23 | """ 24 | return 2 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "cexit". 33 | """ 34 | return "cexit" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `cexit` CInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/cinstruction.py: -------------------------------------------------------------------------------- 1 | from linker.instructions.instruction import BaseInstruction 2 | 3 | class CInstruction(BaseInstruction): 4 | """ 5 | Represents a CInstruction, inheriting from BaseInstruction. 6 | """ 7 | 8 | @classmethod 9 | def _get_name_token_index(cls) -> int: 10 | """ 11 | Gets the index of the token containing the name of the instruction. 12 | 13 | Returns: 14 | int: The index of the name token, which is 1. 15 | """ 16 | return 1 17 | 18 | # Constructor 19 | # ----------- 20 | 21 | def __init__(self, tokens: list, comment: str = ""): 22 | """ 23 | Constructs a new CInstruction. 24 | 25 | Parameters: 26 | tokens (list): List of tokens for the instruction. 27 | comment (str): Optional comment for the instruction. 28 | 29 | Raises: 30 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 31 | """ 32 | super().__init__(tokens, comment=comment) 33 | 34 | def to_line(self) -> str: 35 | """ 36 | Retrieves the string form of the instruction to write to the instruction file. 37 | 38 | Returns: 39 | str: The string representation of the instruction, excluding the first token. 40 | """ 41 | return ", ".join(self.tokens[1:]) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/cload.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `cload` CInstruction. 6 | 7 | This instruction loads a single polynomial residue from scratchpad into a register. 8 | 9 | For more information, check the `cload` Specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_cload.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls)->int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `cload` instruction requires 4 tokens: 19 | , cload, , 20 | 21 | Returns: 22 | int: The number of tokens, which is 4. 23 | """ 24 | # 4 tokens: 25 | # , cload, , 26 | # No HBM variant 27 | # , cload, , 28 | return 4 29 | 30 | @classmethod 31 | def _get_name(cls) -> str: 32 | """ 33 | Gets the name of the instruction. 34 | 35 | Returns: 36 | str: The name of the instruction, which is "cload". 37 | """ 38 | return "cload" 39 | 40 | def __init__(self, tokens: list, comment: str = ""): 41 | """ 42 | Constructs a new `cload` CInstruction. 43 | 44 | Args: 45 | tokens (list): A list of tokens representing the instruction. 46 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 47 | 48 | Raises: 49 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 50 | """ 51 | super().__init__(tokens, comment=comment) 52 | 53 | @property 54 | def source(self) -> str: 55 | """ 56 | Name of the source. 57 | This is a Variable name when loaded. Should be set to HBM address to write back. 58 | """ 59 | return self.tokens[3] 60 | 61 | @source.setter 62 | def source(self, value: str): 63 | self.tokens[3] = value 64 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/cnop.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `cnop` CInstruction. 6 | 7 | This instruction adds a desired amount of idle cycles in the Cfetch flow. 8 | 9 | For more information, check the `cnop` Specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_nop.md 11 | 12 | Properties: 13 | cycles: Gets or sets the number of idle cycles. 14 | """ 15 | 16 | @classmethod 17 | def _get_num_tokens(cls) -> int: 18 | """ 19 | Gets the number of tokens required for the instruction. 20 | 21 | The `cnop` instruction requires 3 tokens: 22 | , cnop, 23 | 24 | Returns: 25 | int: The number of tokens, which is 3. 26 | """ 27 | return 3 28 | 29 | @classmethod 30 | def _get_name(cls) -> str: 31 | """ 32 | Gets the name of the instruction. 33 | 34 | Returns: 35 | str: The name of the instruction, which is "cnop". 36 | """ 37 | return "cnop" 38 | 39 | def __init__(self, tokens: list, comment: str = ""): 40 | """ 41 | Constructs a new `cnop` CInstruction. 42 | 43 | Args: 44 | tokens (list): A list of tokens representing the instruction. 45 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 46 | 47 | Raises: 48 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 49 | """ 50 | super().__init__(tokens, comment=comment) 51 | 52 | @property 53 | def cycles(self) -> int: 54 | """ 55 | Gets the number of idle cycles. 56 | 57 | Returns: 58 | int: The number of idle cycles. 59 | """ 60 | return int(self.tokens[2]) 61 | 62 | @cycles.setter 63 | def cycles(self, value: int): 64 | """ 65 | Sets the number of idle cycles. 66 | 67 | Args: 68 | value (int): The number of idle cycles to set. 69 | 70 | Raises: 71 | ValueError: If the value is negative. 72 | """ 73 | if value < 0: 74 | raise ValueError(f'`value` must be non-negative, but {value} received.') 75 | self.tokens[2] = str(value) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/cstore.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `cstore` CInstruction. 6 | 7 | This instruction fetches a single polynomial residue from the intermediate data buffer and stores it back to SPAD. 8 | 9 | For more information, check the `cstore` Specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_cstore.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls)->int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `cstore` instruction requires 3 tokens: 19 | , cstore, 20 | 21 | Returns: 22 | int: The number of tokens, which is 3. 23 | """ 24 | # 3 tokens: 25 | # , cstore, 26 | # No HBM variant 27 | # , cstore, 28 | return 3 29 | 30 | @classmethod 31 | def _get_name(cls) -> str: 32 | """ 33 | Gets the name of the instruction. 34 | 35 | Returns: 36 | str: The name of the instruction, which is "cstore". 37 | """ 38 | return "cstore" 39 | 40 | def __init__(self, tokens: list, comment: str = ""): 41 | """ 42 | Constructs a new `cstore` CInstruction. 43 | 44 | Args: 45 | tokens (list): A list of tokens representing the instruction. 46 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 47 | 48 | Raises: 49 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 50 | """ 51 | super().__init__(tokens, comment=comment) 52 | 53 | @property 54 | def dest(self) -> str: 55 | """ 56 | Name of the destination. 57 | This is a Variable name when loaded. Should be set to HBM address to write back. 58 | """ 59 | return self.tokens[2] 60 | 61 | @dest.setter 62 | def dest(self, value: str): 63 | self.tokens[2] = value 64 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/csyncm.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `csyncm` CInstruction. 6 | 7 | Wait instruction similar to a barrier that stalls the execution of the CINST 8 | queue until the specified instruction from the MINST queue has completed. 9 | 10 | For more information, check the `csyncm` Specification: 11 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_csyncm.md 12 | 13 | Properties: 14 | target: Gets or sets the target MInst. 15 | """ 16 | 17 | @classmethod 18 | def _get_num_tokens(cls) -> int: 19 | """ 20 | Gets the number of tokens required for the instruction. 21 | 22 | The `csyncm` instruction requires 3 tokens: 23 | , csyncm, 24 | 25 | Returns: 26 | int: The number of tokens, which is 3. 27 | """ 28 | return 3 29 | 30 | @classmethod 31 | def _get_name(cls) -> str: 32 | """ 33 | Gets the name of the instruction. 34 | 35 | Returns: 36 | str: The name of the instruction, which is "csyncm". 37 | """ 38 | return "csyncm" 39 | 40 | def __init__(self, tokens: list, comment: str = ""): 41 | """ 42 | Constructs a new `csyncm` CInstruction. 43 | 44 | Args: 45 | tokens (list): A list of tokens representing the instruction. 46 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 47 | 48 | Raises: 49 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 50 | """ 51 | super().__init__(tokens, comment=comment) 52 | 53 | @property 54 | def target(self) -> int: 55 | """ 56 | Gets the target MInst. 57 | 58 | Returns: 59 | int: The target MInst. 60 | """ 61 | return int(self.tokens[2]) 62 | 63 | @target.setter 64 | def target(self, value: int): 65 | """ 66 | Sets the target MInst. 67 | 68 | Args: 69 | value (int): The target MInst to set. 70 | 71 | Raises: 72 | ValueError: If the value is negative. 73 | """ 74 | if value < 0: 75 | raise ValueError(f'`value`: expected non-negative target, but {value} received.') 76 | self.tokens[2] = str(value) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/ifetch.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates an `ifetch` CInstruction. 6 | 7 | This instruction fetches a bundle of instructions from the XINST queue and sends it to the CE for execution. 8 | 9 | For more information, check the `ifetch` Specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_ifetch.md 11 | 12 | Properties: 13 | bundle: Gets or sets the target bundle index. 14 | """ 15 | 16 | @classmethod 17 | def _get_num_tokens(cls) -> int: 18 | """ 19 | Gets the number of tokens required for the instruction. 20 | 21 | The `ifetch` instruction requires 3 tokens: 22 | , ifetch, 23 | 24 | Returns: 25 | int: The number of tokens, which is 3. 26 | """ 27 | return 3 28 | 29 | @classmethod 30 | def _get_name(cls) -> str: 31 | """ 32 | Gets the name of the instruction. 33 | 34 | Returns: 35 | str: The name of the instruction, which is "ifetch". 36 | """ 37 | return "ifetch" 38 | 39 | def __init__(self, tokens: list, comment: str = ""): 40 | """ 41 | Constructs a new `ifetch` CInstruction. 42 | 43 | Args: 44 | tokens (list): A list of tokens representing the instruction. 45 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 46 | 47 | Raises: 48 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 49 | """ 50 | super().__init__(tokens, comment=comment) 51 | 52 | @property 53 | def bundle(self) -> int: 54 | """ 55 | Gets the target bundle index. 56 | 57 | Returns: 58 | int: The target bundle index. 59 | """ 60 | return int(self.tokens[2]) 61 | 62 | @bundle.setter 63 | def bundle(self, value: int): 64 | """ 65 | Sets the target bundle index. 66 | 67 | Args: 68 | value (int): The target bundle index to set. 69 | 70 | Raises: 71 | ValueError: If the value is negative. 72 | """ 73 | if value < 0: 74 | raise ValueError(f'`value`: expected non-negative bundle index, but {value} received.') 75 | self.tokens[2] = str(value) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/kgload.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `kg_load` CInstruction. 6 | """ 7 | 8 | @classmethod 9 | def _get_num_tokens(cls) -> int: 10 | """ 11 | Gets the number of tokens required for the instruction. 12 | 13 | The `kg_load` instruction requires 3 tokens: 14 | , kg_load, 15 | 16 | Returns: 17 | int: The number of tokens, which is 3. 18 | """ 19 | return 3 20 | 21 | @classmethod 22 | def _get_name(cls) -> str: 23 | """ 24 | Gets the name of the instruction. 25 | 26 | Returns: 27 | str: The name of the instruction, which is "kg_load". 28 | """ 29 | return "kg_load" 30 | 31 | def __init__(self, tokens: list, comment: str = ""): 32 | """ 33 | Constructs a new `kg_load` CInstruction. 34 | 35 | Args: 36 | tokens (list): A list of tokens representing the instruction. 37 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 38 | 39 | Raises: 40 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 41 | """ 42 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/kgseed.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `kg_seed` CInstruction. 6 | """ 7 | 8 | @classmethod 9 | def _get_num_tokens(cls) -> int: 10 | """ 11 | Gets the number of tokens required for the instruction. 12 | 13 | The `kg_seed` instruction requires 4 tokens: 14 | , kg_seed, , 15 | 16 | Returns: 17 | int: The number of tokens, which is 4. 18 | """ 19 | return 4 20 | 21 | @classmethod 22 | def _get_name(cls) -> str: 23 | """ 24 | Gets the name of the instruction. 25 | 26 | Returns: 27 | str: The name of the instruction, which is "kg_seed". 28 | """ 29 | return "kg_seed" 30 | 31 | def __init__(self, tokens: list, comment: str = ""): 32 | """ 33 | Constructs a new `kg_seed` CInstruction. 34 | 35 | Args: 36 | tokens (list): A list of tokens representing the instruction. 37 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 38 | 39 | Raises: 40 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 41 | """ 42 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/kgstart.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `kg_start` CInstruction. 6 | """ 7 | 8 | @classmethod 9 | def _get_num_tokens(cls) -> int: 10 | """ 11 | Gets the number of tokens required for the instruction. 12 | 13 | The `kg_start` instruction requires 2 tokens: 14 | , kg_start 15 | 16 | Returns: 17 | int: The number of tokens, which is 2. 18 | """ 19 | return 2 20 | 21 | @classmethod 22 | def _get_name(cls) -> str: 23 | """ 24 | Gets the name of the instruction. 25 | 26 | Returns: 27 | str: The name of the instruction, which is "kg_start". 28 | """ 29 | return "kg_start" 30 | 31 | def __init__(self, tokens: list, comment: str = ""): 32 | """ 33 | Constructs a new `kg_start` CInstruction. 34 | 35 | Args: 36 | tokens (list): A list of tokens representing the instruction. 37 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 38 | 39 | Raises: 40 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 41 | """ 42 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/cinst/nload.py: -------------------------------------------------------------------------------- 1 | from .cinstruction import CInstruction 2 | 3 | class Instruction(CInstruction): 4 | """ 5 | Encapsulates a `nload` CInstruction. 6 | 7 | This instruction loads metadata (for NTT/iNTT routing mapping) from 8 | scratchpad into a special routing table register. 9 | 10 | For more information, check the `nload` Specification: 11 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_nload.md 12 | """ 13 | 14 | @classmethod 15 | def _get_num_tokens(cls)->int: 16 | """ 17 | Gets the number of tokens required for the instruction. 18 | 19 | The `nload` instruction requires 4 tokens: 20 | , nload, , 21 | 22 | Returns: 23 | int: The number of tokens, which is 4. 24 | """ 25 | # 4 tokens: 26 | # , nload, , 27 | # No HBM variant: 28 | # , nload, , 29 | return 4 30 | 31 | @classmethod 32 | def _get_name(cls) -> str: 33 | """ 34 | Gets the name of the instruction. 35 | 36 | Returns: 37 | str: The name of the instruction, which is "nload". 38 | """ 39 | return "nload" 40 | 41 | def __init__(self, tokens: list, comment: str = ""): 42 | """ 43 | Constructs a new `nload` CInstruction. 44 | 45 | Args: 46 | tokens (list): A list of tokens representing the instruction. 47 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 48 | 49 | Raises: 50 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 51 | """ 52 | super().__init__(tokens, comment=comment) 53 | 54 | @property 55 | def source(self) -> str: 56 | """ 57 | Name of the source. 58 | This is a Variable name when loaded. Should be set to HBM address to write back. 59 | """ 60 | return self.tokens[3] 61 | 62 | @source.setter 63 | def source(self, value: str): 64 | self.tokens[3] = value 65 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/minst/__init__.py: -------------------------------------------------------------------------------- 1 |  2 | from . import mload, mstore, msyncc 3 | 4 | # MInst aliases 5 | 6 | MLoad = mload.Instruction 7 | MStore = mstore.Instruction 8 | MSyncc = msyncc.Instruction 9 | 10 | def factory() -> set: 11 | """ 12 | Creates a set of all instruction classes. 13 | 14 | Returns: 15 | set: A set containing all instruction classes. 16 | """ 17 | return { MLoad, 18 | MStore, 19 | MSyncc } 20 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/minst/minstruction.py: -------------------------------------------------------------------------------- 1 |  2 | from linker.instructions.instruction import BaseInstruction 3 | 4 | class MInstruction(BaseInstruction): 5 | """ 6 | Represents an MInstruction, inheriting from BaseInstruction. 7 | """ 8 | 9 | @classmethod 10 | def _get_name_token_index(cls) -> int: 11 | """ 12 | Gets the index of the token containing the name of the instruction. 13 | 14 | Returns: 15 | int: The index of the name token, which is 1. 16 | """ 17 | return 1 18 | 19 | # Constructor 20 | # ----------- 21 | 22 | def __init__(self, tokens: list, comment: str = ""): 23 | """ 24 | Constructs a new MInstruction. 25 | 26 | Parameters: 27 | tokens (list): List of tokens for the instruction. 28 | comment (str): Optional comment for the instruction. 29 | 30 | Raises: 31 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 32 | """ 33 | super().__init__(tokens, comment=comment) 34 | 35 | def to_line(self) -> str: 36 | """ 37 | Retrieves the string form of the instruction to write to the instruction file. 38 | 39 | Returns: 40 | str: The string representation of the instruction, excluding the first token. 41 | """ 42 | return ", ".join(self.tokens[1:]) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/minst/mload.py: -------------------------------------------------------------------------------- 1 | from .minstruction import MInstruction 2 | 3 | class Instruction(MInstruction): 4 | """ 5 | Encapsulates an `mload` MInstruction. 6 | 7 | This instruction loads a single polynomial residue from local memory to scratchpad. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/minst/minst_mload.md 11 | 12 | Properties: 13 | source: Gets or sets the name of the source. 14 | """ 15 | 16 | @classmethod 17 | def _get_num_tokens(cls) -> int: 18 | """ 19 | Gets the number of tokens required for the instruction. 20 | 21 | The `mload` instruction requires 4 tokens: 22 | , mload, , 23 | 24 | Returns: 25 | int: The number of tokens, which is 4. 26 | """ 27 | return 4 28 | 29 | @classmethod 30 | def _get_name(cls) -> str: 31 | """ 32 | Gets the name of the instruction. 33 | 34 | Returns: 35 | str: The name of the instruction, which is "mload". 36 | """ 37 | return "mload" 38 | 39 | def __init__(self, tokens: list, comment: str = ""): 40 | """ 41 | Constructs a new `mload` MInstruction. 42 | 43 | Args: 44 | tokens (list): A list of tokens representing the instruction. 45 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 46 | 47 | Raises: 48 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 49 | """ 50 | super().__init__(tokens, comment=comment) 51 | 52 | @property 53 | def source(self) -> str: 54 | """ 55 | Gets the name of the source. 56 | 57 | This is a Variable name when loaded. Should be set to HBM address to write back. 58 | 59 | Returns: 60 | str: The name of the source. 61 | """ 62 | return self.tokens[3] 63 | 64 | @source.setter 65 | def source(self, value: str): 66 | """ 67 | Sets the name of the source. 68 | 69 | Args: 70 | value (str): The name of the source to set. 71 | """ 72 | self.tokens[3] = value -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/minst/mstore.py: -------------------------------------------------------------------------------- 1 | from .minstruction import MInstruction 2 | 3 | class Instruction(MInstruction): 4 | """ 5 | Encapsulates an `mstore` MInstruction. 6 | 7 | This instruction stores a single polynomial residue from scratchpad to local memory. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/minst/minst_mstore.md 11 | 12 | Properties: 13 | dest: Gets or sets the name of the destination. 14 | """ 15 | 16 | @classmethod 17 | def _get_num_tokens(cls) -> int: 18 | """ 19 | Gets the number of tokens required for the instruction. 20 | 21 | The `mstore` instruction requires 4 tokens: 22 | , mstore, , 23 | 24 | Returns: 25 | int: The number of tokens, which is 4. 26 | """ 27 | return 4 28 | 29 | @classmethod 30 | def _get_name(cls) -> str: 31 | """ 32 | Gets the name of the instruction. 33 | 34 | Returns: 35 | str: The name of the instruction, which is "mstore". 36 | """ 37 | return "mstore" 38 | 39 | def __init__(self, tokens: list, comment: str = ""): 40 | """ 41 | Constructs a new `mstore` MInstruction. 42 | 43 | Args: 44 | tokens (list): A list of tokens representing the instruction. 45 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 46 | 47 | Raises: 48 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 49 | """ 50 | super().__init__(tokens, comment=comment) 51 | 52 | @property 53 | def dest(self) -> str: 54 | """ 55 | Gets the name of the destination. 56 | 57 | This is a Variable name when loaded. Should be set to HBM address to write back. 58 | 59 | Returns: 60 | str: The name of the destination. 61 | """ 62 | return self.tokens[2] 63 | 64 | @dest.setter 65 | def dest(self, value: str): 66 | """ 67 | Sets the name of the destination. 68 | 69 | Args: 70 | value (str): The name of the destination to set. 71 | """ 72 | self.tokens[2] = value -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/minst/msyncc.py: -------------------------------------------------------------------------------- 1 | from .minstruction import MInstruction 2 | 3 | class Instruction(MInstruction): 4 | """ 5 | Encapsulates an `msyncc` MInstruction. 6 | 7 | Wait instruction similar to a barrier that stalls the execution of the MINST 8 | queue until the specified instruction from the CINST queue has completed. 9 | 10 | For more information, check the specification: 11 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/minst/minst_msyncc.md 12 | 13 | Properties: 14 | target: Gets or sets the target CInst. 15 | """ 16 | 17 | @classmethod 18 | def _get_num_tokens(cls) -> int: 19 | """ 20 | Gets the number of tokens required for the instruction. 21 | 22 | The `msyncc` instruction requires 3 tokens: 23 | , msyncc, 24 | 25 | Returns: 26 | int: The number of tokens, which is 3. 27 | """ 28 | return 3 29 | 30 | @classmethod 31 | def _get_name(cls) -> str: 32 | """ 33 | Gets the name of the instruction. 34 | 35 | Returns: 36 | str: The name of the instruction, which is "msyncc". 37 | """ 38 | return "msyncc" 39 | 40 | def __init__(self, tokens: list, comment: str = ""): 41 | """ 42 | Constructs a new `msyncc` MInstruction. 43 | 44 | Args: 45 | tokens (list): A list of tokens representing the instruction. 46 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 47 | 48 | Raises: 49 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 50 | """ 51 | super().__init__(tokens, comment=comment) 52 | 53 | @property 54 | def target(self) -> int: 55 | """ 56 | Gets the target CInst. 57 | 58 | Returns: 59 | int: The target CInst. 60 | """ 61 | return int(self.tokens[2]) 62 | 63 | @target.setter 64 | def target(self, value: int): 65 | """ 66 | Sets the target CInst. 67 | 68 | Args: 69 | value (int): The target CInst to set. 70 | 71 | Raises: 72 | ValueError: If the value is negative. 73 | """ 74 | if value < 0: 75 | raise ValueError(f'`value`: expected non-negative target, but {value} received.') 76 | self.tokens[2] = str(value) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/__init__.py: -------------------------------------------------------------------------------- 1 | from . import add, sub, mul, muli, mac, maci, ntt, intt, twntt, twintt, rshuffle, move, xstore, nop 2 | from . import exit as exit_mod 3 | #from . import copy as copy_mod 4 | 5 | # XInst aliases 6 | 7 | # XInsts with P-ISA equivalent 8 | Add = add.Instruction 9 | Sub = sub.Instruction 10 | Mul = mul.Instruction 11 | Muli = muli.Instruction 12 | Mac = mac.Instruction 13 | Maci = maci.Instruction 14 | NTT = ntt.Instruction 15 | iNTT = intt.Instruction 16 | twNTT = twntt.Instruction 17 | twiNTT = twintt.Instruction 18 | rShuffle = rshuffle.Instruction 19 | # All other XInsts 20 | Move = move.Instruction 21 | XStore = xstore.Instruction 22 | Exit = exit_mod.Instruction 23 | Nop = nop.Instruction 24 | 25 | def factory() -> set: 26 | """ 27 | Creates a set of all instruction classes. 28 | 29 | Returns: 30 | set: A set containing all instruction classes. 31 | """ 32 | return { Add, 33 | Sub, 34 | Mul, 35 | Muli, 36 | Mac, 37 | Maci, 38 | NTT, 39 | iNTT, 40 | twNTT, 41 | twiNTT, 42 | rShuffle, 43 | Move, 44 | XStore, 45 | Exit, 46 | Nop } 47 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/add.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates an `add` XInstruction. 6 | 7 | This instruction adds two polynomials stored in the register file and 8 | stores the result in a register. 9 | 10 | For more information, check the specification: 11 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_add.md 12 | """ 13 | 14 | @classmethod 15 | def _get_num_tokens(cls) -> int: 16 | """ 17 | Gets the number of tokens required for the instruction. 18 | 19 | The `add` instruction requires 7 tokens: 20 | F, , add, , , , 21 | 22 | Returns: 23 | int: The number of tokens, which is 7. 24 | """ 25 | return 7 26 | 27 | @classmethod 28 | def _get_name(cls) -> str: 29 | """ 30 | Gets the name of the instruction. 31 | 32 | Returns: 33 | str: The name of the instruction, which is "add". 34 | """ 35 | return "add" 36 | 37 | def __init__(self, tokens: list, comment: str = ""): 38 | """ 39 | Constructs a new `add` XInstruction. 40 | 41 | Args: 42 | tokens (list): A list of tokens representing the instruction. 43 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 44 | 45 | Raises: 46 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 47 | """ 48 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/exit.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates an `bexit` XInstruction. 6 | 7 | This instruction terminates execution of an instruction bundle. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_exit.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `bexit` instruction requires 3 tokens: 19 | F, , bexit 20 | 21 | Returns: 22 | int: The number of tokens, which is 3. 23 | """ 24 | return 3 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "bexit". 33 | """ 34 | return "bexit" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `bexit` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/intt.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates an `intt` XInstruction. 6 | 7 | The Inverse Number Theoretic Transform (iNTT) converts NTT form to positional form. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_intt.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `intt` instruction requires 10 tokens: 19 | F, , intt, , , , , , , 20 | 21 | Returns: 22 | int: The number of tokens, which is 10. 23 | """ 24 | return 10 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "intt". 33 | """ 34 | return "intt" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `intt` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/mac.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates a `mac` XInstruction. 6 | 7 | Element-wise polynomial multiplication and accumulation. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_mac.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `mac` instruction requires 8 tokens: 19 | F, , mac, , , , , 20 | 21 | Returns: 22 | int: The number of tokens, which is 8. 23 | """ 24 | return 8 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "mac". 33 | """ 34 | return "mac" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `mac` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/maci.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates a `maci` XInstruction. 6 | 7 | Element-wise polynomial scaling by an immediate value and accumulation. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_maci.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `maci` instruction requires 8 tokens: 19 | F, , maci, , , , , 20 | 21 | Returns: 22 | int: The number of tokens, which is 8. 23 | """ 24 | return 8 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "maci". 33 | """ 34 | return "maci" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `maci` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/move.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates a `move` XInstruction. 6 | 7 | This instruction copies data from one register to a different one. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_move.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `move` instruction requires 5 tokens: 19 | F, , move, , 20 | 21 | Returns: 22 | int: The number of tokens, which is 5. 23 | """ 24 | return 5 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "move". 33 | """ 34 | return "move" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `move` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/mul.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates a `mul` XInstruction. 6 | 7 | This instruction performs element-wise polynomial multiplication. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_mul.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `mul` instruction requires 7 tokens: 19 | F, , mul, , , , 20 | 21 | Returns: 22 | int: The number of tokens, which is 7. 23 | """ 24 | return 7 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "mul". 33 | """ 34 | return "mul" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `mul` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/muli.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates a `muli` XInstruction. 6 | 7 | This instruction performs element-wise polynomial scaling by an immediate value. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_muli.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `muli` instruction requires 7 tokens: 19 | F, , muli, , , , 20 | 21 | Returns: 22 | int: The number of tokens, which is 7. 23 | """ 24 | return 7 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "muli". 33 | """ 34 | return "muli" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `muli` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/nop.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates a `nop` XInstruction. 6 | 7 | This instruction adds a desired amount of idle cycles to the compute flow. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_nop.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `nop` instruction requires 4 tokens: 19 | F, , nop, 20 | 21 | Returns: 22 | int: The number of tokens, which is 4. 23 | """ 24 | return 4 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "nop". 33 | """ 34 | return "nop" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `nop` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/ntt.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates an `ntt` XInstruction (Number Theoretic Transform). 6 | Converts positional form to NTT form. 7 | 8 | For more information, check the specification: 9 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_ntt.md 10 | """ 11 | 12 | @classmethod 13 | def _get_num_tokens(cls) -> int: 14 | """ 15 | Gets the number of tokens required for the instruction. 16 | 17 | The `ntt` instruction requires 10 tokens: 18 | F, , ntt, , , , , , , 19 | 20 | Returns: 21 | int: The number of tokens, which is 10. 22 | """ 23 | return 10 24 | 25 | @classmethod 26 | def _get_name(cls) -> str: 27 | """ 28 | Gets the name of the instruction. 29 | 30 | Returns: 31 | str: The name of the instruction, which is "ntt". 32 | """ 33 | return "ntt" 34 | 35 | def __init__(self, tokens: list, comment: str = ""): 36 | """ 37 | Constructs a new `ntt` XInstruction. 38 | 39 | Args: 40 | tokens (list): A list of tokens representing the instruction. 41 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 42 | 43 | Raises: 44 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 45 | """ 46 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/rshuffle.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates an `rshuffle` XInstruction. 6 | """ 7 | 8 | @classmethod 9 | def _get_num_tokens(cls) -> int: 10 | """ 11 | Gets the number of tokens required for the instruction. 12 | 13 | The `rshuffle` instruction requires 9 tokens: 14 | F, , rshuffle, , , , , , 15 | 16 | Returns: 17 | int: The number of tokens, which is 9. 18 | """ 19 | return 9 20 | 21 | @classmethod 22 | def _get_name(cls) -> str: 23 | """ 24 | Gets the name of the instruction. 25 | 26 | Returns: 27 | str: The name of the instruction, which is "rshuffle". 28 | """ 29 | return "rshuffle" 30 | 31 | def __init__(self, tokens: list, comment: str = ""): 32 | """ 33 | Constructs a new `rshuffle` XInstruction. 34 | 35 | Args: 36 | tokens (list): A list of tokens representing the instruction. 37 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 38 | 39 | Raises: 40 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 41 | """ 42 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/sub.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates a `sub` XInstruction. 6 | 7 | This instruction performs element-wise polynomial subtraction. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_sub.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `sub` instruction requires 7 tokens: 19 | F, , sub, , , , 20 | 21 | Returns: 22 | int: The number of tokens, which is 7. 23 | """ 24 | return 7 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "sub". 33 | """ 34 | return "sub" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `sub` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/twintt.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates a `twintt` XInstruction. 6 | 7 | This instruction performs on-die generation of twiddle factors for the next stage of iNTT. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_twintt.md. 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `twintt` instruction requires 10 tokens: 19 | F, , twintt, , , , , , , 20 | 21 | Returns: 22 | int: The number of tokens, which is 10. 23 | """ 24 | return 10 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "twintt". 33 | """ 34 | return "twintt" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `twintt` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/twntt.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates a `twntt` XInstruction. 6 | 7 | This instruction performs on-die generation of twiddle factors for the next stage of NTT. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_twntt.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `twntt` instruction requires 10 tokens: 19 | F, , twntt, , , , , , , 20 | 21 | Returns: 22 | int: The number of tokens, which is 10. 23 | """ 24 | return 10 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "twntt". 33 | """ 34 | return "twntt" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `twntt` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/xinstruction.py: -------------------------------------------------------------------------------- 1 |  2 | from linker.instructions.instruction import BaseInstruction 3 | 4 | class XInstruction(BaseInstruction): 5 | """ 6 | Represents an XInstruction, inheriting from BaseInstruction. 7 | """ 8 | 9 | @classmethod 10 | def _get_name_token_index(cls) -> int: 11 | """ 12 | Gets the index of the token containing the name of the instruction. 13 | 14 | Returns: 15 | int: The index of the name token, which is 2. 16 | """ 17 | # Name at index 2. 18 | return 2 19 | 20 | # Constructor 21 | # ----------- 22 | 23 | def __init__(self, tokens: list, comment: str = ""): 24 | """ 25 | Constructs a new XInstruction. 26 | 27 | Parameters: 28 | tokens (list): List of tokens for the instruction. 29 | comment (str): Optional comment for the instruction. 30 | 31 | Raises: 32 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 33 | """ 34 | super().__init__(tokens, comment=comment) 35 | 36 | @property 37 | def bundle(self) -> int: 38 | """ 39 | Gets the bundle index. 40 | 41 | Returns: 42 | int: The bundle index. 43 | 44 | Raises: 45 | RuntimeError: If the bundle format is invalid. 46 | """ 47 | if len(self.tokens[0]) < 2 or self.tokens[0][0] != 'F': 48 | raise RuntimeError(f'Invalid bundle format detected: "{self.tokens[0]}".') 49 | return int(self.tokens[0][1:]) 50 | 51 | @bundle.setter 52 | def bundle(self, value: int): 53 | """ 54 | Sets the bundle index. 55 | 56 | Parameters: 57 | value (int): The new bundle index. 58 | 59 | Raises: 60 | ValueError: If the value is negative. 61 | """ 62 | if value < 0: 63 | raise ValueError(f'`value`: expected non-negative bundle index, but {value} received.') 64 | self.tokens[0] = f'F{value}' -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/instructions/xinst/xstore.py: -------------------------------------------------------------------------------- 1 | from .xinstruction import XInstruction 2 | 3 | class Instruction(XInstruction): 4 | """ 5 | Encapsulates an `xstore` XInstruction. 6 | 7 | This instruction transfers data from a register into the intermediate data buffer for subsequent transfer into SPAD. 8 | 9 | For more information, check the specification: 10 | https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_xstore.md 11 | """ 12 | 13 | @classmethod 14 | def _get_num_tokens(cls) -> int: 15 | """ 16 | Gets the number of tokens required for the instruction. 17 | 18 | The `xstore` instruction requires 4 tokens: 19 | F, , xstore, 20 | 21 | Returns: 22 | int: The number of tokens, which is 4. 23 | """ 24 | return 4 25 | 26 | @classmethod 27 | def _get_name(cls) -> str: 28 | """ 29 | Gets the name of the instruction. 30 | 31 | Returns: 32 | str: The name of the instruction, which is "xstore". 33 | """ 34 | return "xstore" 35 | 36 | def __init__(self, tokens: list, comment: str = ""): 37 | """ 38 | Constructs a new `xstore` XInstruction. 39 | 40 | Args: 41 | tokens (list): A list of tokens representing the instruction. 42 | comment (str, optional): An optional comment for the instruction. Defaults to an empty string. 43 | 44 | Raises: 45 | ValueError: If the number of tokens is invalid or the instruction name is incorrect. 46 | """ 47 | super().__init__(tokens, comment=comment) -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/steps/__init__.py: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/linker/steps/variable_discovery.py: -------------------------------------------------------------------------------- 1 | from assembler.memory_model.variable import Variable 2 | from linker.instructions import minst, cinst 3 | from linker.instructions.minst.minstruction import MInstruction 4 | from linker.instructions.cinst.cinstruction import CInstruction 5 | 6 | def discoverVariablesSPAD(cinstrs: list): 7 | """ 8 | Finds Variable names used in a list of CInstructions. 9 | 10 | Attributes: 11 | cinstrs (list[CInstruction]): 12 | List of CInstructions where to find variable names. 13 | Raises: 14 | RuntimeError: 15 | Invalid Variable name detected in an CInstruction. 16 | Returns: 17 | Iterable: 18 | Yields an iterable over variable names identified in the listing 19 | of CInstructions specified. 20 | """ 21 | for idx, cinstr in enumerate(cinstrs): 22 | if not isinstance(cinstr, CInstruction): 23 | raise TypeError(f'Item {idx} in list of MInstructions is not a valid MInstruction.') 24 | retval = None 25 | # TODO: Implement variable counting for CInst 26 | ############### 27 | # Raise NotImplementedError("Implement variable counting for CInst") 28 | if isinstance(cinstr, (cinst.BLoad, cinst.CLoad, cinst.BOnes, cinst.NLoad)): 29 | retval = cinstr.source 30 | elif isinstance(cinstr, cinst.CStore): 31 | retval = cinstr.dest 32 | 33 | if retval is not None: 34 | if not Variable.validateName(retval): 35 | raise RuntimeError(f'Invalid Variable name "{retval}" detected in instruction "{idx}, {cinstr.to_line()}"') 36 | yield retval 37 | 38 | def discoverVariables(minstrs: list): 39 | """ 40 | Finds variable names used in a list of MInstructions. 41 | 42 | Parameters: 43 | minstrs (list[MInstruction]): List of MInstructions where to find variable names. 44 | 45 | Raises: 46 | TypeError: If an item in the list is not a valid MInstruction. 47 | RuntimeError: If an invalid variable name is detected in an MInstruction. 48 | 49 | Returns: 50 | Iterable: Yields an iterable over variable names identified in the listing 51 | of MInstructions specified. 52 | """ 53 | for idx, minstr in enumerate(minstrs): 54 | if not isinstance(minstr, MInstruction): 55 | raise TypeError(f'Item {idx} in list of MInstructions is not a valid MInstruction.') 56 | retval = None 57 | if isinstance(minstr, minst.MLoad): 58 | retval = minstr.source 59 | elif isinstance(minstr, minst.MStore): 60 | retval = minstr.dest 61 | 62 | if retval is not None: 63 | if not Variable.validateName(retval): 64 | raise RuntimeError(f'Invalid Variable name "{retval}" detected in instruction "{idx}, {minstr.to_line()}"') 65 | yield retval -------------------------------------------------------------------------------- /assembler_tools/hec-assembler-tools/requirements.txt: -------------------------------------------------------------------------------- 1 | contourpy==1.0.7 2 | cycler==0.11.0 3 | fonttools==4.43.0 4 | importlib-resources==5.12.0 5 | kiwisolver==1.4.4 6 | matplotlib==3.7.1 7 | networkx==3.0 8 | numpy==1.24.2 9 | packaging==23.0 10 | Pillow==10.3.0 11 | python-dateutil==2.8.2 12 | PyYAML==6.0 13 | six==1.16.0 14 | zipp==3.19.1 15 | -------------------------------------------------------------------------------- /docs/Encrypted-Computing-SDK/Overview/EncryptedComputingSDK-Polynomial_Instruction_Set_Architecture_Tools-public.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IntelLabs/encrypted-computing-sdk/57e118b3dc93b2bddc8eb90b23fbad0e56398b21/docs/Encrypted-Computing-SDK/Overview/EncryptedComputingSDK-Polynomial_Instruction_Set_Architecture_Tools-public.pdf -------------------------------------------------------------------------------- /docs/Encrypted-Computing-SDK/Overview/EncryptedComputingSDK-Polynomial_Instruction_Set_Architecture_Tools-public.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IntelLabs/encrypted-computing-sdk/57e118b3dc93b2bddc8eb90b23fbad0e56398b21/docs/Encrypted-Computing-SDK/Overview/EncryptedComputingSDK-Polynomial_Instruction_Set_Architecture_Tools-public.pptx -------------------------------------------------------------------------------- /docs/Encrypted-Computing-SDK/empty_file.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/images/SDK_Integration_3rd_party.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IntelLabs/encrypted-computing-sdk/57e118b3dc93b2bddc8eb90b23fbad0e56398b21/docs/images/SDK_Integration_3rd_party.png -------------------------------------------------------------------------------- /docs/images/SDK_Phase_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IntelLabs/encrypted-computing-sdk/57e118b3dc93b2bddc8eb90b23fbad0e56398b21/docs/images/SDK_Phase_1.png -------------------------------------------------------------------------------- /docs/images/SDK_Roadmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IntelLabs/encrypted-computing-sdk/57e118b3dc93b2bddc8eb90b23fbad0e56398b21/docs/images/SDK_Roadmap.png -------------------------------------------------------------------------------- /p-isa_tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ################################ 2 | # P-ISA Tools Main Entrypoint 3 | ################################ 4 | 5 | cmake_minimum_required(VERSION 3.22) 6 | 7 | # General Setup 8 | if(CMAKE_BUILD_TYPE) 9 | set(RELEASE_TYPES 10 | Debug 11 | Release 12 | RelWithDebInfo 13 | MinSizeRel) 14 | list(FIND RELEASE_TYPES ${CMAKE_BUILD_TYPE} INDEX_FOUND) 15 | if(${INDEX_FOUND} EQUAL -1) 16 | message( 17 | FATAL_ERROR 18 | "CMAKE_BUILD_TYPE must be one of Debug, Release, RelWithDebInfo, or MinSizeRel" 19 | ) 20 | endif() 21 | else() 22 | set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of Build" FORCE) 23 | endif() 24 | 25 | option(ENABLE_DATA_FORMATS "Enable support for the data formats library" OFF) 26 | message(ENABLE_DATA_FORMATS="${ENABLE_DATA_FORMATS}") 27 | 28 | option(ENABLE_FUNCTIONAL_MODELER "Enable building of functional modeler" ON) 29 | message(ENABLE_FUNCTIONAL_MODELER="${ENABLE_FUNCTIONAL_MODELER}") 30 | 31 | option(ENABLE_PROGRAM_MAPPER "Enable building of program mapper" OFF) 32 | message(ENABLE_PROGRAM_MAPPER="${ENABLE_PROGRAM_MAPPER}") 33 | 34 | option(ENABLE_P_ISA_UTILITIES "Enable building of p-isa utilities" OFF) 35 | message(ENABLE_P_ISA_UTILITIES="${ENABLE_P_ISA_UTILITIES}") 36 | 37 | configure_file(common/config.h.in "${CMAKE_BINARY_DIR}/p_isa_tools_config/config.h") 38 | 39 | project(p_isa_tools LANGUAGES CXX) 40 | 41 | set(CMAKE_CXX_STANDARD 17) 42 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 43 | 44 | # Define standard installation directories (GNU) 45 | include(GNUInstallDirs) 46 | 47 | # Set default output directories 48 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") 49 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") 50 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}") 51 | 52 | # Find OpenMP on system 53 | find_package(OpenMP REQUIRED) 54 | 55 | # External fetch and build dependencies 56 | include(cmake/dependencies.cmake) 57 | 58 | # Policy is explicit header locations 59 | set(INCLUDE_DIRS ${PROJECT_SOURCE_DIR} ${CMAKE_BINARY_DIR}/p_isa_tools_config/) 60 | 61 | # Include *.h files in sources so they appear in IDEs 62 | file(GLOB_RECURSE IDE_HEADERS program_mapper/*.h functional_modeler/*.h dependencies/*.h common/*.h) 63 | 64 | # Build sub-directories 65 | add_subdirectory(common) 66 | if(ENABLE_FUNCTIONAL_MODELER) 67 | add_subdirectory(functional_modeler) 68 | endif() 69 | if(ENABLE_PROGRAM_MAPPER) 70 | add_subdirectory(program_mapper) 71 | endif() 72 | if(ENABLE_P_ISA_UTILITIES) 73 | add_subdirectory(p_isa_utilities) 74 | endif() 75 | -------------------------------------------------------------------------------- /p-isa_tools/CPPLINT.cfg: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2020 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # Some of these filters can be removed once existing code permits 5 | filter=-whitespace 6 | filter=-readability/todo 7 | filter=-runtime/references 8 | filter=-runtime/explicit 9 | filter=-build/c++11 10 | filter=-build/namespaces 11 | filter=-build/include 12 | -------------------------------------------------------------------------------- /p-isa_tools/cmake/dependencies.cmake: -------------------------------------------------------------------------------- 1 | 2 | include(FetchContent) 3 | FetchContent_Declare( 4 | json_for_modern_cpp 5 | # v3.11.2 released Aug 2023 6 | URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz 7 | URL_HASH SHA256=8c4b26bf4b422252e13f332bc5e388ec0ab5c3443d24399acb675e68278d341f 8 | ) 9 | 10 | FetchContent_MakeAvailable(json_for_modern_cpp) 11 | 12 | FetchContent_Declare( 13 | argmap 14 | # TODO at the mo, grabs the latest this should change once versioned 15 | URL https://raw.githubusercontent.com/helibproject/argmap/main/argmap.h 16 | DOWNLOAD_NO_EXTRACT TRUE 17 | ) 18 | 19 | FetchContent_GetProperties(argmap) 20 | if (NOT argmap_POPULATED) 21 | FetchContent_Populate(argmap) 22 | include_directories(${argmap_SOURCE_DIR}) 23 | endif() 24 | 25 | FetchContent_Declare( 26 | snap 27 | # commit from Feb 2023 28 | GIT_REPOSITORY https://github.com/snap-stanford/snap.git 29 | GIT_TAG 6924a035aabd1ce0a547b94e995e142f29eb5040 30 | ) 31 | 32 | FetchContent_GetProperties(snap) 33 | if (NOT snap_POPULATED) 34 | FetchContent_Populate(snap) 35 | message(STATUS "Building SNAP, this may take a while ...") 36 | execute_process(COMMAND make -j 37 | WORKING_DIRECTORY ${snap_SOURCE_DIR} 38 | OUTPUT_QUIET 39 | ERROR_QUIET 40 | OUTPUT_FILE ${FETCHCONTENT_BASE_DIR}/snap.stdout 41 | ERROR_FILE ${FETCHCONTENT_BASE_DIR}/snap.stderr 42 | ) 43 | add_library(snap OBJECT IMPORTED GLOBAL) 44 | set_target_properties(snap PROPERTIES IMPORTED_OBJECTS ${snap_SOURCE_DIR}/snap-core/Snap.o) 45 | include_directories(${snap_SOURCE_DIR}/snap-core ${snap_SOURCE_DIR}/glib-core) 46 | message(STATUS "Finished building SNAP") 47 | endif() 48 | 49 | if(ENABLE_DATA_FORMATS) 50 | find_package(HERACLES_DATA_FORMATS CONFIG) 51 | if(NOT HERACLES_DATA_FORMATS_FOUND) 52 | FetchContent_Declare( 53 | heracles_data_formats 54 | GIT_REPOSITORY git@github.com:IntelLabs/HERACLES-data-formats.git 55 | GIT_TAG main 56 | ) 57 | FetchContent_MakeAvailable(heracles_data_formats) 58 | endif() 59 | endif() 60 | -------------------------------------------------------------------------------- /p-isa_tools/common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ################## 2 | # HERACLES Utils 3 | ################## 4 | 5 | project(common) 6 | 7 | set(SRCS 8 | p_isa/p_isa_instruction.cpp 9 | p_isa/parser/p_isa_parser.cpp 10 | p_isa/p_isa_performance_modeler.h 11 | p_isa/p_isa_performance_modeler.cpp 12 | ) 13 | 14 | add_library(common OBJECT ${SRCS}) 15 | target_include_directories(common PRIVATE ${INCLUDE_DIRS}) 16 | -------------------------------------------------------------------------------- /p-isa_tools/common/config.h.in: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #cmakedefine01 ENABLE_DATA_FORMATS 5 | -------------------------------------------------------------------------------- /p-isa_tools/common/p_isa/isa_instruction.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #pragma once 5 | 6 | /** 7 | * @brief The ISAInstruction class used to represent an generic ISA instruction 8 | * 9 | */ 10 | class ISAInstruction 11 | { 12 | public: 13 | ISAInstruction() = default; 14 | }; 15 | -------------------------------------------------------------------------------- /p-isa_tools/common/p_isa/p_isa.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #pragma once 5 | 6 | #include "p_isa_instructions.h" 7 | #include 8 | 9 | namespace pisa { 10 | 11 | ///** InstructionMap provides a mapping from OP name to implementation of that instruction. 12 | // * 13 | // **/ 14 | 15 | static const std::map InstructionMap = { 16 | { instruction::Add::baseName, new instruction::Add() }, 17 | { instruction::Sub::baseName, new instruction::Sub() }, 18 | { instruction::Mul::baseName, new instruction::Mul() }, 19 | { instruction::Mac::baseName, new instruction::Mac() }, 20 | { instruction::Maci::baseName, new instruction::Maci() }, 21 | { instruction::Intt::baseName, new instruction::Intt() }, 22 | { instruction::Ntt::baseName, new instruction::Ntt() }, 23 | { instruction::Muli::baseName, new instruction::Muli() }, 24 | { instruction::Copy::baseName, new instruction::Copy() } 25 | }; 26 | 27 | } // namespace pisa 28 | -------------------------------------------------------------------------------- /p-isa_tools/common/p_isa/parser/p_isa_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | namespace pisa { 12 | 13 | class PISAParser 14 | { 15 | public: 16 | PISAParser() = delete; 17 | static std::vector parse(const std::string &filename); 18 | 19 | private: 20 | static constexpr int OP_CODE_LOCATION = 1; 21 | 22 | static PISAInstruction *parseInstruction(const std::vector &components); 23 | 24 | static void parseInstruction(const std::string &, pisa::PARAM_TYPE, pisa::PISAInstruction *instr); 25 | 26 | static void parseComponent(const std::string &component, pisa::PARAM_TYPE type, pisa::PISAInstruction *instr); 27 | static void parse_OP_NAME(const std::string &component, pisa::PISAInstruction *instr); 28 | static void parse_INPUT_OPERAND(const std::string &component, pisa::PISAInstruction *instr); 29 | static void parse_IMMEDIATE(const std::string &component, pisa::PISAInstruction *instr); 30 | static void parse_OUTPUT_OPERAND(const std::string &component, pisa::PISAInstruction *instr); 31 | static void parse_INPUT_OUTPUT_OPERAND(const std::string &component, pisa::PISAInstruction *instr); 32 | static void parse_POLYMOD_DEG_LOG2(const std::string &component, pisa::PISAInstruction *instr); 33 | static void parse_RESIDUAL(const std::string &component, pisa::PISAInstruction *instr); 34 | static void parse_ADDITIONAL_PARAMS(const std::string &component, pisa::PISAInstruction *instr); 35 | static void parse_W_PARAM(const std::string &component, pisa::PISAInstruction *instr); 36 | static void parse_GALOIS_ELEMENT(const std::string &component, pisa::PISAInstruction *instr); 37 | static void parse_GROUP_ID(const std::string &component, pisa::PISAInstruction *instr); 38 | static void parse_STAGE(const std::string &component, pisa::PISAInstruction *instr); 39 | static void parse_BLOCK(const std::string &component, pisa::PISAInstruction *instr); 40 | }; 41 | } // namespace pisa 42 | -------------------------------------------------------------------------------- /p-isa_tools/common/string.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (C) 2024 Intel Corporation 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | inline std::string whiteSpaceRemoved(const std::string &str) 11 | { 12 | auto str_copy = str; 13 | auto trimmed = std::remove(str_copy.begin(), str_copy.end(), ' '); 14 | str_copy.erase(trimmed, str_copy.end()); 15 | return str_copy; 16 | } 17 | -------------------------------------------------------------------------------- /p-isa_tools/functional_modeler/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################## 2 | # HERACLES Functional Modeler 3 | ############################## 4 | 5 | project(functional_modeler LANGUAGES CXX) 6 | 7 | set(${PROJECT_NAME}_SOURCES 8 | "main.cpp" 9 | ) 10 | 11 | add_executable(functional_modeler ${${PROJECT_NAME}_SOURCES} ${IDE_HEADERS}) 12 | target_include_directories(functional_modeler PRIVATE ${INCLUDE_DIRS}) 13 | target_link_libraries(functional_modeler PUBLIC nlohmann_json::nlohmann_json snap OpenMP::OpenMP_CXX common) 14 | if(ENABLE_DATA_FORMATS) 15 | target_link_libraries(functional_modeler PUBLIC HERACLES_DATA_FORMATS::heracles_data_formats) 16 | endif() 17 | -------------------------------------------------------------------------------- /p-isa_tools/functional_modeler/functional_models/utility_functions.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (C) 2024 Intel Corporation 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | namespace pisa::utility { 8 | 9 | /** 10 | * @brief reverseBits is a utility function to reverse the order of bits of a number mod some value 11 | * @param i The number to reverse 12 | * @param mod The number of bits in i to reverse 13 | * @return 14 | */ 15 | template 16 | static T reverseBits(T i, int mod) 17 | { 18 | unsigned int s = sizeof(i) * 8; 19 | unsigned int mask = ~0; 20 | while ((s >>= 1) > 0) 21 | { 22 | mask ^= (mask << s); 23 | i = ((i >> s) & mask) | ((i << s) & ~mask); 24 | } 25 | 26 | T shifted = i >> (sizeof(i) * 8 - mod); 27 | return shifted; 28 | } 29 | 30 | } // namespace pisa::utility 31 | -------------------------------------------------------------------------------- /p-isa_tools/functional_modeler/pisa_runtime/p_isa_instruction_trace.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #pragma once 5 | 6 | #include "common/p_isa/p_isa_instruction.h" 7 | #include "functional_modeler/functional_models/multiregister.h" 8 | 9 | namespace pisa { 10 | template 11 | class PISAInstructionTrace 12 | { 13 | public: 14 | PISAInstructionTrace() {} 15 | PISAInstructionTrace(std::shared_ptr instr, std::vector> inputs, std::vector> outputs); 16 | const std::vector> &executionResult() const; 17 | void setExecutionResult(const std::vector> &newExecution_result) 18 | { 19 | m_execution_result = newExecution_result; 20 | } 21 | 22 | const std::vector> &executionInputs() const; 23 | void setExecutionInputs(const std::vector> &newExecution_inputs) 24 | { 25 | m_execution_inputs = newExecution_inputs; 26 | } 27 | 28 | std::string outLabel() 29 | { 30 | std::ostringstream label_stream; 31 | auto inputs = executionInputs(); 32 | for (auto &v : inputs) 33 | { 34 | label_stream << v.toString() << " , "; 35 | } 36 | label_stream << '\n'; 37 | auto results = executionResult(); 38 | for (auto &v : results) 39 | { 40 | label_stream << v.toString() << " , "; 41 | } 42 | return label_stream.str(); 43 | } 44 | 45 | void printInstructionTrace(int max_values = 10) 46 | { 47 | std::cout << "Instruction label: " << m_instruction->Name() << std::endl; 48 | std::cout << "Inputs:" << std::endl; 49 | for (int x = 0; x < m_instruction->numInputOperands(); x++) 50 | { 51 | std::cout << m_instruction->getInputOperand(x).location() << " : "; 52 | for (int i = 0; x < m_execution_inputs.size() && i < m_execution_inputs[x].size() && i < max_values; i++) 53 | { 54 | std::cout << m_execution_inputs[x][i] << ", "; 55 | } 56 | std::cout << std::endl; 57 | } 58 | std::cout << "Outputs: " << std::endl; 59 | for (int x = 0; x < m_instruction->numOutputOperands(); x++) 60 | { 61 | std::cout << m_instruction->getOutputOperand(x).location() << " :"; 62 | for (int i = 0; i < x < m_execution_result.size() && m_execution_result[x].size() && i < max_values; i++) 63 | { 64 | std::cout << m_execution_result[x][i] << ", "; 65 | } 66 | std::cout << std::endl; 67 | } 68 | std::cout << std::endl 69 | << std::endl; 70 | } 71 | 72 | const std::shared_ptr &instruction() const 73 | { 74 | return m_instruction; 75 | } 76 | void setInstruction(const std::shared_ptr &newInstruction) 77 | { 78 | m_instruction = newInstruction; 79 | } 80 | void setInstruction(pisa::PISAInstruction *instr) 81 | { 82 | setInstruction(std::make_shared(*instr)); 83 | } 84 | 85 | private: 86 | std::shared_ptr m_instruction; 87 | std::vector> m_execution_inputs; 88 | std::vector> m_execution_result; 89 | }; 90 | } // namespace pisa 91 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/.gitignore: -------------------------------------------------------------------------------- 1 | # Input files 2 | **.high 3 | data/ 4 | 5 | # Vim artefacts 6 | **.sw? 7 | 8 | # Python artefacts 9 | **/__pycache__/ 10 | 11 | # Playground 12 | zz_playground/ 13 | 14 | # vs code local config 15 | .vscode -------------------------------------------------------------------------------- /p-isa_tools/kerngen/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/high_parser/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | 3 | """Imports commonly used when using this package""" 4 | 5 | from high_parser.types import ( 6 | Context, 7 | Immediate, 8 | HighOp, 9 | expand_ios, 10 | Polys, 11 | KernelContext, 12 | KeyPolys, 13 | ) 14 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/high_parser/config.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | """Module for configuring the kernel generator""" 5 | 6 | 7 | class Config: 8 | """Class representing the configuration options""" 9 | 10 | legacy_mode: bool 11 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/high_parser/generators.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | """Module providing an interface to pisa generators""" 5 | 6 | import json 7 | from importlib import import_module 8 | from pathlib import Path 9 | 10 | 11 | class GeneratorError(Exception): 12 | """Class representing errors raised by the Generators class""" 13 | 14 | 15 | class Generators: 16 | """Class responsible for obtaining pisa ops from the pisa generators""" 17 | 18 | def __init__(self, dirpath: str, class_map: dict[str, list[str]]): 19 | """Initializer. Expects a path to a manifest JSON file and dictionary 20 | `{op : [classname, filename]}`""" 21 | self.map = class_map 22 | self.directory = dirpath 23 | 24 | @classmethod 25 | def from_manifest(cls, filepath: str, scheme: str): 26 | """Creates a `Generators` object given a manifest JSON file selected 27 | from the `scheme`. Parses the manifest file as a python dictionary and 28 | stores it in `self.map`""" 29 | filepath_p = Path(filepath) 30 | dirpath = str(filepath_p.parent) 31 | with open(filepath, encoding="utf-8") as manifest_file: 32 | manifest = json.load(manifest_file) 33 | try: 34 | return cls(dirpath, manifest[scheme.upper()]) 35 | except KeyError as e: 36 | raise GeneratorError( 37 | f"Scheme `{scheme.upper()}` not found in manifest file" 38 | ) from e 39 | 40 | def available_kernels(self) -> str: 41 | """Returns a list of available pisa ops.""" 42 | return "\n".join(f"{op}" for op in self.map.keys()) 43 | 44 | def get_kernel(self, opname: str): 45 | """Returns the kernel generator given a valid op name""" 46 | try: 47 | # Capitalize the opname because it is the name of the class! 48 | class_name, module_file = self.map[opname.upper()] 49 | filepath = Path(self.directory).stem + "/" + Path(module_file).stem 50 | module_path = filepath.replace("/", ".") 51 | 52 | # Actual import happens here 53 | module = import_module(module_path) 54 | return getattr(module, class_name) 55 | except KeyError as e: 56 | raise GeneratorError(f"Op not found in available pisa ops: {opname}") from e 57 | except AttributeError as e: 58 | raise GeneratorError( 59 | f"Class for op `{opname}` name not found: {class_name}" 60 | ) from e 61 | except ImportError as e: 62 | raise GeneratorError(f"Unable to import module: {module_path}") from e 63 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/kerngen.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | # Copyright (C) 2024 Intel Corporation 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | """Module for generating p-isa kernels""" 7 | 8 | import argparse 9 | import sys 10 | from typing import Iterable 11 | 12 | from high_parser.parser import Parser 13 | from high_parser.config import Config 14 | 15 | 16 | def parse_args(): 17 | """Parse arguments from the commandline""" 18 | parser = argparse.ArgumentParser(description="Kernel Generator") 19 | parser.add_argument( 20 | "-q", "--quiet", action="store_true", help="disable comments in output" 21 | ) 22 | parser.add_argument( 23 | "-l", "--legacy", action="store_true", help="enable legacy mode" 24 | ) 25 | return parser.parse_args() 26 | 27 | 28 | def to_string_block(iterable: Iterable[str], *, ignore_comments: bool) -> str: 29 | """helper to string block""" 30 | strs = map(str, iterable) 31 | if ignore_comments is True: 32 | return "\n".join(i for i in strs if not i.rstrip().startswith("#")) 33 | return "\n".join(strs) 34 | 35 | 36 | def main(args) -> None: 37 | """Main entrypoint. Load available p-isa ops and parse isa instructions.""" 38 | 39 | parse_results = Parser().parse_inputs(sys.stdin.readlines()) 40 | Config.legacy_mode = args.legacy 41 | 42 | # String blocks of the p-isa instructions (forward the Nones) 43 | pisa_ops: list[str | None] = list( 44 | to_string_block(op, ignore_comments=args.quiet) if op is not None else None 45 | for op in parse_results.get_pisa_ops() 46 | ) 47 | 48 | filtered = (t for t in zip(pisa_ops, parse_results.commands) if t[0] is not None) 49 | 50 | if args.quiet is True: 51 | for pisa_op, _ in filtered: 52 | print(pisa_op) 53 | return 54 | 55 | hashes = "#" * 3 56 | context = parse_results.context 57 | print(hashes, "Context:", context, hashes) 58 | for kernel_no, (pisa_op, command) in enumerate(filtered): 59 | print(hashes, f"Kernel ({kernel_no}):", command, hashes) 60 | print(pisa_op) 61 | 62 | 63 | if __name__ == "__main__": 64 | cmdline_args = parse_args() 65 | main(cmdline_args) 66 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/pisa_generators/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/pisa_generators/decomp.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | """Module containing digit decomposition/base extend""" 4 | 5 | from string import ascii_letters 6 | import itertools as it 7 | 8 | from dataclasses import dataclass 9 | import high_parser.pisa_operations as pisa_op 10 | from high_parser.pisa_operations import PIsaOp 11 | from high_parser import KernelContext, HighOp, Immediate, Polys 12 | 13 | from .basic import Muli, mixed_to_pisa_ops 14 | from .ntt import INTT, NTT 15 | 16 | 17 | @dataclass 18 | class DigitDecompExtend(HighOp): 19 | """Class representing Digit decomposition and base extension""" 20 | 21 | context: KernelContext 22 | output: Polys 23 | input0: Polys 24 | 25 | def to_pisa(self) -> list[PIsaOp]: 26 | """Return the p-isa code performing Digit decomposition followed by 27 | base extension""" 28 | 29 | rns_poly = Polys.from_polys(self.input0) 30 | rns_poly.name = "ct" 31 | 32 | one = Immediate(name="one") 33 | r2 = Immediate(name="R2", rns=self.context.key_rns) 34 | 35 | ls: list[pisa_op] = [] 36 | for input_rns_index in range(self.input0.start_rns, self.input0.rns): 37 | # muli for 0-current_rns 38 | ls.extend( 39 | pisa_op.Muli( 40 | self.context.label, 41 | self.output(part, pq, unit), 42 | rns_poly(part, input_rns_index, unit), 43 | r2(part, pq, unit), 44 | pq, 45 | ) 46 | for part, pq, unit in it.product( 47 | range(self.input0.start_parts, self.input0.parts), 48 | range(self.context.current_rns), 49 | range(self.context.units), 50 | ) 51 | ) 52 | # muli for krns 53 | ls.extend( 54 | pisa_op.Muli( 55 | self.context.label, 56 | self.output(part, pq, unit), 57 | rns_poly(part, input_rns_index, unit), 58 | r2(part, pq, unit), 59 | pq, 60 | ) 61 | for part, pq, unit in it.product( 62 | range(self.input0.start_parts, self.input0.parts), 63 | range(self.context.max_rns, self.context.key_rns), 64 | range(self.context.units), 65 | ) 66 | ) 67 | 68 | output_tmp = Polys.from_polys(self.output) 69 | output_tmp.name += "_" + ascii_letters[input_rns_index] 70 | output_split = Polys.from_polys(self.output) 71 | output_split.rns = self.context.current_rns 72 | # ntt for 0-current_rns 73 | ls.extend(NTT(self.context, output_tmp, output_split).to_pisa()) 74 | 75 | output_split = Polys.from_polys(self.output) 76 | output_split.rns = self.context.key_rns 77 | output_split.start_rns = self.context.max_rns 78 | # ntt for krns 79 | ls.extend(NTT(self.context, output_tmp, output_split).to_pisa()) 80 | 81 | return mixed_to_pisa_ops( 82 | INTT(self.context, rns_poly, self.input0), 83 | Muli(self.context, rns_poly, rns_poly, one), 84 | ls, 85 | ) 86 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/pisa_generators/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "BGV": { 3 | "ADD": ["Add", "basic.py"], 4 | "MUL": ["Mul", "basic.py"], 5 | "MULI": ["Muli", "basic.py"], 6 | "COPY": ["Copy", "basic.py"], 7 | "SUB": ["Sub", "basic.py"], 8 | "SQUARE": ["Square", "square.py"], 9 | "NTT": ["NTT", "ntt.py"], 10 | "INTT": ["INTT", "ntt.py"], 11 | "MOD": ["Mod", "mod.py"], 12 | "MODUP": ["ModUp", "mod.py"], 13 | "RELIN": ["Relin", "relin.py"], 14 | "ROTATE": ["Rotate", "rotate.py"] 15 | }, 16 | "CKKS": { 17 | "ADD": ["Add", "basic.py"], 18 | "MUL": ["Mul", "basic.py"], 19 | "MULI": ["Muli", "basic.py"], 20 | "COPY": ["Copy", "basic.py"], 21 | "SUB": ["Sub", "basic.py"], 22 | "SQUARE": ["Square", "square.py"], 23 | "NTT": ["NTT", "ntt.py"], 24 | "INTT": ["INTT", "ntt.py"], 25 | "MOD": ["Mod", "mod.py"], 26 | "MODUP": ["Modup", "mod.py"], 27 | "RELIN": ["Relin", "relin.py"], 28 | "RESCALE": ["Rescale", "rescale.py"], 29 | "ROTATE": ["Rotate", "rotate.py"] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/pisa_generators/relin.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | """Module containing relin.""" 5 | from dataclasses import dataclass 6 | from high_parser.pisa_operations import PIsaOp, Comment 7 | from high_parser import KernelContext, HighOp, KeyPolys, Polys 8 | from .basic import Add, KeyMul, mixed_to_pisa_ops, extract_last_part_polys 9 | 10 | from .mod import Mod 11 | from .decomp import DigitDecompExtend 12 | 13 | 14 | @dataclass 15 | class Relin(HighOp): 16 | """Class representing relinearization operation""" 17 | 18 | context: KernelContext 19 | output: Polys 20 | input0: Polys 21 | 22 | def to_pisa(self) -> list[PIsaOp]: 23 | """Return the p-isa code to perform a relinearization (relin). Note: 24 | currently only supports polynomials with two parts. Currently only 25 | supports number of digits equal to the RNS size""" 26 | self.output.parts = 2 27 | self.input0.parts = 3 28 | relin_key = KeyPolys( 29 | "rlk", parts=2, rns=self.context.key_rns, digits=self.input0.rns 30 | ) 31 | 32 | mul_by_rlk = Polys("c2_rlk", parts=2, rns=self.context.key_rns) 33 | 34 | mul_by_rlk_modded_down = Polys.from_polys(mul_by_rlk) 35 | mul_by_rlk_modded_down.rns = self.input0.rns 36 | 37 | input_last_part, last_coeff, upto_last_coeffs = extract_last_part_polys( 38 | self.input0, self.context.key_rns 39 | ) 40 | 41 | add_original = Polys.from_polys(mul_by_rlk_modded_down) 42 | add_original.name = self.input0.name 43 | return mixed_to_pisa_ops( 44 | Comment("Start of relin kernel"), 45 | Comment("Digit decomposition and extend base from Q to PQ"), 46 | DigitDecompExtend(self.context, last_coeff, input_last_part), 47 | Comment("Multiply by relin key"), 48 | KeyMul(self.context, mul_by_rlk, upto_last_coeffs, relin_key, 2), 49 | Comment("Mod switch down to Q"), 50 | Mod(self.context, mul_by_rlk_modded_down, mul_by_rlk, Mod.MOD_P), 51 | Comment("Add to original poly"), 52 | Add(self.context, self.output, mul_by_rlk_modded_down, add_original), 53 | Comment("End of relin kernel"), 54 | ) 55 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/pisa_generators/rotate.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | """Module containing implementation for rotate kernel.""" 5 | 6 | from dataclasses import dataclass 7 | 8 | from high_parser.pisa_operations import PIsaOp, Comment 9 | from high_parser import KernelContext, HighOp, Polys, KeyPolys 10 | 11 | from .basic import Add, KeyMul, mixed_to_pisa_ops, extract_last_part_polys 12 | from .decomp import DigitDecompExtend 13 | from .mod import Mod 14 | from .ntt import INTT, NTT 15 | 16 | 17 | @dataclass 18 | class Rotate(HighOp): 19 | """Class representing rotate operation""" 20 | 21 | context: KernelContext 22 | output: Polys 23 | input0: Polys 24 | 25 | def to_pisa(self) -> list[PIsaOp]: 26 | """Return the p-isa code to perform a rotate. Note: 27 | currently only supports polynomials with two parts. Currently only 28 | supports number of digits equal to the RNS size""" 29 | self.output.parts = 2 30 | self.input0.parts = 2 31 | 32 | relin_key = KeyPolys( 33 | "gk", parts=2, rns=self.context.key_rns, digits=self.input0.rns 34 | ) 35 | mul_by_rlk = Polys("c2_gk", parts=2, rns=self.context.key_rns) 36 | mul_by_rlk_modded_down = Polys.from_polys(mul_by_rlk) 37 | mul_by_rlk_modded_down.rns = self.input0.rns 38 | mul_by_rlk_modded_down.name = self.output.name 39 | 40 | input_last_part, last_coeff, upto_last_coeffs = extract_last_part_polys( 41 | self.input0, self.context.key_rns 42 | ) 43 | 44 | cd = Polys.from_polys(self.input0) 45 | cd.name = "cd" 46 | cd.parts = 1 47 | cd.start_parts = 0 48 | 49 | start_input = Polys.from_polys(self.input0) 50 | start_input.parts = 1 51 | start_input.start_parts = 0 52 | 53 | first_part_rlk = Polys.from_polys(mul_by_rlk_modded_down) 54 | first_part_rlk.parts = 1 55 | first_part_rlk.start_parts = 0 56 | 57 | return mixed_to_pisa_ops( 58 | Comment("Start of rotate kernel"), 59 | Comment("Digit Decomp"), 60 | DigitDecompExtend(self.context, last_coeff, input_last_part), 61 | Comment("Multiply by rotate key"), 62 | KeyMul(self.context, mul_by_rlk, upto_last_coeffs, relin_key, 1), 63 | Comment("Mod switch down to Q"), 64 | Mod(self.context, mul_by_rlk_modded_down, mul_by_rlk, Mod.MOD_P), 65 | INTT(self.context, cd, start_input), 66 | NTT(self.context, cd, cd), 67 | Add(self.context, self.output, cd, first_part_rlk), 68 | Comment("End of rotate kernel"), 69 | ) 70 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/pisa_generators/square.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Intel Corporation 2 | 3 | """Module containing conversions or operations from isa to p-isa.""" 4 | 5 | from dataclasses import dataclass 6 | 7 | from high_parser.pisa_operations import PIsaOp 8 | from high_parser import Context, HighOp, Polys 9 | 10 | from .basic import Copy, Mul, mixed_to_pisa_ops 11 | 12 | 13 | @dataclass 14 | class Square(HighOp): 15 | """Class representing the high-level squaring operation""" 16 | 17 | context: Context 18 | output: Polys 19 | input0: Polys 20 | 21 | def to_pisa(self) -> list[PIsaOp]: 22 | """Return the p-isa equivalent of an Add""" 23 | intermediate = Polys(name="inter", parts=self.input0.parts, rns=self.input0.rns) 24 | 25 | return mixed_to_pisa_ops( 26 | Copy(self.context, intermediate, self.input0), 27 | Mul(self.context, self.output, intermediate, self.input0), 28 | ) 29 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/requirements.txt: -------------------------------------------------------------------------------- 1 | # NOTE pytest requires pydantic to be (1.10, 2.11) 2 | # CVE-2024-3772 (Vulnerability GHSA-mr82-8j83-vxmv) requires ~=1.10.13 0r ~=2.4.0 3 | pydantic ~= 1.10.22 4 | 5 | # for dev / commits 6 | black ~= 25.1 7 | pylint ~= 3.3 8 | 9 | # for testing 10 | pytest ~= 8.3 11 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/vsc_kerlang_extension/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | .gitignore 4 | -------------------------------------------------------------------------------- /p-isa_tools/kerngen/vsc_kerlang_extension/README.md: -------------------------------------------------------------------------------- 1 | # HERACLES Kernel Language extension for VS Code 2 | 3 | This is an experimental first attempt at creating a VS Code extension that 4 | understands the grammar of the HERACLES Kernel Language. 5 | 6 | 7 | This is experimental code. Use it at your own risk. 8 | 9 | 10 | ## Installation 11 | 12 | A pre-packaged version of this extension '.vsix' file is avialble in the 13 | current folder. 14 | You can manually install using the Install from VSIX command in the Extensions 15 | view command dropdown. For an alternative way to install a local VS Code 16 | extensions, please check the 17 | [VS Code documentaiton](https://code.visualstudio.com/docs/editor/extension-marketplace#_install-from-a-vsix). 18 | 19 | ## Features 20 | 21 | The only available feature is the toggle comments on a line 22 | 23 | ## Known Issues 24 | 25 | The actual grammar is not yet working. 26 | 27 | ## Release Notes 28 | 29 | None at the moment. -------------------------------------------------------------------------------- /p-isa_tools/kerngen/vsc_kerlang_extension/grammars/kerlang.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "scopeName": "source.kerlang", 3 | "fileTypes": ["kerlang"], 4 | "patterns": [ 5 | { 6 | "name": "comment.line.number-sign.kerlang", 7 | "match": "# .*$" 8 | }, 9 | { 10 | "name": "keyword.other.kerlang", 11 | "match": "\b(COPY|ADD|MUL|MULI|RELIN|NTT|INTT|MOD|MODUP|SQUARE)\b" 12 | } 13 | ], 14 | "repository": {} 15 | } -------------------------------------------------------------------------------- /p-isa_tools/kerngen/vsc_kerlang_extension/heracles-kerlang-syntax-0.0.1.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IntelLabs/encrypted-computing-sdk/57e118b3dc93b2bddc8eb90b23fbad0e56398b21/p-isa_tools/kerngen/vsc_kerlang_extension/heracles-kerlang-syntax-0.0.1.vsix -------------------------------------------------------------------------------- /p-isa_tools/kerngen/vsc_kerlang_extension/language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "# " 4 | } 5 | } -------------------------------------------------------------------------------- /p-isa_tools/kerngen/vsc_kerlang_extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "heracles-kerlang-syntax", 3 | "displayName": "HERACLES Kernel Language Syntax Extension", 4 | "description": "Syntax Extension for HERACLES kernel-language", 5 | "version": "0.0.1", 6 | "publisher": "Intel", 7 | "private": true, 8 | "license": "Apache-2.0", 9 | "engines": { 10 | "vscode": "^1.92.0" 11 | }, 12 | "categories": ["Programming Languages"], 13 | "contributes": { 14 | "languages": [ 15 | { 16 | "id": "kerlang", 17 | "aliases": ["KerLang", "kerlang"], 18 | "extensions": [".ker"], 19 | "configuration": "./language-configuration.json" 20 | } 21 | ], 22 | "grammars": [ 23 | { 24 | "language": "kerlang", 25 | "scopeName": "source.kerlang", 26 | "path": "./grammars/kerlang.tmLanguage.json" 27 | } 28 | ] 29 | }, 30 | "repository": {} 31 | } -------------------------------------------------------------------------------- /p-isa_tools/kerngen/vsc_kerlang_extension/themes/kerlang.tmTheme.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokenColors": [ 3 | { 4 | "scope": "comment", 5 | "settings": { 6 | "foreground": "#d4922f", 7 | "fontStyle": "italic" 8 | } 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | pythonpath = kerngen 3 | -------------------------------------------------------------------------------- /tutorials/kerngen/SimpleExamples/ADD_16K1rns.ker: -------------------------------------------------------------------------------- 1 | CONTEXT BGV 16384 2 1 2 | DATA a 1 3 | DATA b 1 4 | DATA c 1 5 | ADD c a b 6 | -------------------------------------------------------------------------------- /tutorials/kerngen/SimpleExamples/ADD_16K4rns.ker: -------------------------------------------------------------------------------- 1 | CONTEXT BGV 16384 5 4 2 | DATA a 1 3 | DATA b 1 4 | DATA c 1 5 | ADD c a b 6 | -------------------------------------------------------------------------------- /tutorials/kerngen/SimpleExamples/ADD_C16K1rns_pyramid.ker: -------------------------------------------------------------------------------- 1 | CONTEXT BGV 16384 2 1 2 | # inputs 3 | DATA a 2 4 | DATA b 2 5 | DATA c 2 6 | DATA d 2 7 | DATA e 2 8 | DATA f 2 9 | # temp variables 10 | DATA temp1 2 11 | DATA temp2 2 12 | DATA temp3 2 13 | DATA temp4 2 14 | # output 15 | DATA g 2 16 | # Code 17 | ADD temp1 a b 18 | ADD temp2 c d 19 | ADD temp3 e f 20 | ADD temp4 temp1 temp2 21 | ADD f temp3 temp4 22 | -------------------------------------------------------------------------------- /tutorials/kerngen/SimpleExamples/ADD_C16K4rns.ker: -------------------------------------------------------------------------------- 1 | CONTEXT BGV 16384 5 4 2 | DATA a 2 3 | DATA b 2 4 | DATA c 2 5 | ADD c a b 6 | -------------------------------------------------------------------------------- /tutorials/kerngen/SimpleExamples/MUL_C16K1rns.ker: -------------------------------------------------------------------------------- 1 | CONTEXT BGV 16384 2 1 2 | DATA a 2 3 | DATA b 2 4 | DATA c 3 5 | MUL c a b 6 | -------------------------------------------------------------------------------- /tutorials/kerngen/SimpleExamples/RELIN_C16K1rns.ker: -------------------------------------------------------------------------------- 1 | CONTEXT BGV 16384 2 1 2 | DATA a 3 3 | DATA b 2 4 | RELIN b a 5 | --------------------------------------------------------------------------------