pax_global_header00006660000000000000000000000064143640436430014521gustar00rootroot0000000000000052 comment=4ae745cfa65b694e8af014b3787d9185cc7a7d0d zDNN-1.0.1/000077500000000000000000000000001436404364300123315ustar00rootroot00000000000000zDNN-1.0.1/.github/000077500000000000000000000000001436404364300136715ustar00rootroot00000000000000zDNN-1.0.1/.github/ISSUE_TEMPLATE/000077500000000000000000000000001436404364300160545ustar00rootroot00000000000000zDNN-1.0.1/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000007611436404364300205520ustar00rootroot00000000000000--- name: Bug about: File a bug/issue title: '[BUG] ' labels: Bug, Needs Triage assignees: '' --- <!-- Note: Please use the search to see if a similar issue already exists. --> ### Current Observation: <!-- what kind of issue did you discover? --> ### Expected: <!-- A concise description of what you expected to see. --> ### Location: <!-- Provide some details to the location. --> ### Anything else: <!-- Links? References? Anything that will give more context about the issue! --> ���������������zDNN-1.0.1/.github/ISSUE_TEMPLATE/feature_request.md������������������������������������������������0000664�0000000�0000000�00000001135�14364043643�0021601�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution or source you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/CONTRIBUTING.md��������������������������������������������������������������������������0000664�0000000�0000000�00000017062�14364043643�0014570�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Contributing to zDNN ========================== License ------- All contributions have to be submitted under the Apache 2.0 license. See also the [LICENSE](LICENSE) file. Developer's Certificate of Origin and Signed-off-by --------------------------------------------------- The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch. With the Signed-off-by line you certify the below: ``` Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ``` If you can certify the above, just add a line stating the following at the bottom of each of your commit messages: ``` Signed-off-by: Random Developer <random@developer.example.org> ``` Please use your real name and a valid e-mail address (no pseudonyms or anonymous contributions). Submitting code --------------- The preferred way is to create GitHub pull requests for your code contributions. Please create separate pull requests for each logical enhancement, new feature, or fix. GitHub workflow for contributions --------------------------------- In the examples below we use this fictive identity: - Name: Random Developer - E-mail: random@developer.example.org - GitHub ID: random-developer ### Setup GitHub and local git 1. Create a fork of this repository by clicking the `Fork` button on the top right of the [zDNN](https://github.com/IBM/zDNN) main page 2. Clone your forked repository to your local development system ``` $ git clone https://github.com/random-developer/zDNN.git ``` 3. Configure a remote called "upstream" pointing to the official zDNN repository on GitHub ``` $ cd zDNN ~/zDNN $ git remote add upstream https://github.com/IBM/zDNN.git ``` 4. Verify your remotes ``` ~/zDNN $ git remote -v origin https://github.com/random-developer/zDNN.git (fetch) origin https://github.com/random-developer/zDNN.git (push) upstream https://github.com/IBM/zDNN.git (fetch) upstream https://github.com/IBM/zDNN.git (push) ``` You now have two remotes: The "origin" remote points to your fork and the "upstream" remote to the official zDNN repository. 5. Configure your git user name and e-mail ``` ~/zDNN $ git config user.name "Random Developer" ~/zDNN $ git config user.email "random@developer.example.com" ``` ### Create a pull request 1. Create and checkout a new branch for your contribution ``` ~/zDNN $ git checkout -b contrib-doc-pr ``` 2. Make your changes to the code ``` ~/zDNN $ vim CONTRIBUTING.md ``` 3. Build and test your contribution, recommended on NNPA enabled machine. ``` ~/zDNN $ make clean all ``` 4. Commit your changes ``` ~/zDNN $ git add CONTRIBUTING.md ~/zDNN $ git commit -s ``` Provide a meaningful commit message including your "Signed-off-by" line to each commit: ``` CONTRIBUTING: Outline steps to submit code Explain in more detail how to submit zDNN contributions as GitHub pull requests. Signed-off-by: Random Developer <random@developer.example.com> ``` 5. Push the changes to your fork of the repository ``` ~/zDNN $ git push origin contrib-doc-pr ``` 6. Go to the GitHub website of your zDNN fork and create a pull request for your branch "contrib-doc-pr" ### Update a pull request during review If there are changes requested during the review process, you have to update your code in the pull request. To retain the existing review comments, add commits on top of your pull request branch. Depending on the size and number of changes, a rebase of the pull request might be required. This will be communicated during the review. 1. Update your code with new commits ``` ~/zDNN $ vi CONTRIBUTING.md ~/zDNN $ git add CONTRIBUTING.md ~/zDNN $ git commit -s -m "CONTRIBUTING: Add update PR info" ``` 2. Update your pull request by pushing changes ``` ~/zDNN $ git push origin contrib-doc-pr ``` ### Finalize a pull request After the review process is finished or if you are explicitly asked for it, you have to create a clean commit series. 1. Save branch to "contrib-doc-pr.v1" ``` $ cd zDNN ~/zDNN $ git branch contrib-doc-pr.v1 ``` 2. Use interactive git rebase to merge commits, adjust commit messages, and rebase onto your local main branch ``` ~/zDNN $ git rebase -i main ``` An editor is started and shows the following: ``` pick 2c73b9fc CONTRIBUTING: Outline steps to submit code pick fcfb0412 CONTRIBUTING: Add update PR info ``` To merge the update into the original commit, replace "pick fcfb0412" with "squash fcfb0412". ``` pick 2c73b9fc CONTRIBUTING: Outline steps to submit code squash fcfb0412 CONTRIBUTING: Add update PR info ``` Save the document and exit the editor to finish the merge. Another editor window is presented to modify the commit message. You now could change the commit message as follows: ``` CONTRIBUTING: Outline steps to submit code Explain in more detail how to submit zDNN contributions as GitHub pull requests and how to update already submitted pull requests. Signed-off-by: Random Developer <random@developer.example.com> ``` With interactive rebasing you can also change the order of commits and modify commit messages with "reword". 3. Use `git push` with the force option to replace the existing pull request with your locally modified commits ``` ~/zDNN $ git push --force origin contrib-doc-pr ``` ### Rebase a pull request If changes are made to the main branch in the official zDNN repository you may be asked to rebase your branch with your contribution onto it. This can be required to prevent any merge conflicts that might arise when integrating your contribution. 1. Fetch all upstream changes from the official zDNN repository, rebase your local main branch and update the main branch on your fork ``` ~/zDNN $ git fetch upstream ~/zDNN $ git checkout main ~/zDNN $ git rebase upstream/main ~/zDNN $ git push origin main ``` 2. Rebase your branch with your contribution onto the main branch of the official zDNN repository ``` ~/zDNN $ git checkout contrib-doc-pr ~/zDNN $ git rebase main ``` 3. Use `git push` with the force option to replace the existing pull request with your locally modified commits ``` ~/zDNN $ git push --force origin contrib-doc-pr ``` ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/LICENSE����������������������������������������������������������������������������������0000664�0000000�0000000�00000026136�14364043643�0013346�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/Makefile���������������������������������������������������������������������������������0000664�0000000�0000000�00000002477�14364043643�0014003�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # #     http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. .DEFAULT_GOAL := all .PHONY: all all: config.make $(MAKE) all -C zdnn $(MAKE) all -C tests .PHONY: help help: @echo "Available targets:" @egrep '^[a-z]+:' Makefile | cut -d: -f1 | sort | xargs -n 1 echo " " .PHONY: build build: config.make $(MAKE) all -C zdnn .PHONY: test test: config.make $(MAKE) all -C tests .PHONY: clean clean: config.make $(MAKE) clean -C tests $(MAKE) clean -C zdnn .PHONY: distclean distclean: clean rm -f config.log config.status config.make config.h .PHONY: install install: build $(MAKE) install -C zdnn config.make: # Use this additional check to allow make invocation "make -B build" in jenkins. ifeq ($(wildcard config.make),) $(error "Please use configure first") endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/README.md��������������������������������������������������������������������������������0000664�0000000�0000000�00000527370�14364043643�0013626�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# zDNN API Reference ## Contacts - Nicholas Marion (nmarion@us.ibm.com) - Andreas Krebbel (krebbel@linux.ibm.com) ## Version 1.0.1 ## Table of Contents <a id="TOC"></a> 1. [Overview](#overview) 2. [Environment](#environment) 3. [Common Data Types and Structs](#common-types-and-structs) - [Version Information](#common-version-info) - [zDNN zTensor](#common-ztensor) - [General zTensor Requirements](#gen-zten-reqs) - [Concatenated zTensor Requirements](#concat-zten-reqs) - [zDNN Tensor Descriptors](#common-descriptors) - [zDNN Data Layouts](#common-layouts) - [zDNN Data Formats](#common-formats) - [zDNN Data Types](#common-types) - [zDNN Statuses](#common-statuses) 4. [Runtime Environment Variables](#env-vars) 5. [API Reference](#api-reference) - [Support Functions](#support-functions) - [Data Transformation](#data-transformation) - [Operations](#operations) - [Element-wise](#elwise-ops) - [Activation](#act-ops) - [Normalization](#norm-ops) - [Matmul with Operation](#zdnn_matmul_op) - [Matmul Broadcast with Operation](#zdnn_matmul_bcast_op) - [LSTM](#zdnn_lstm) - [GRU](#zdnn_gru) - [Average Pool 2D](#zdnn_avgpool2d) - [Max Pool 2D](#zdnn_maxpool2d) - [Convolution 2D](#zdnn_conv2d) - [Convenience Functions](#convenience-functions) 6. [Usage Examples](#usage-examples) ## Overview **Deep Learning Library** - the deep learning library support (zDNN) is the SW enablement technology provided by IBM to meet the following requirements: - Specialized-function-assist instructions are intended to provide performance improvements for specific operations used in software libraries, utilities, and operating system (OS) services. The facilities and instructions described as specialized-function-assist instructions may be replaced or removed in the future. As such, the IBM recommendation for these instructions is that a software library or operating system function be used instead of directly accessing the instructions. This is the function provided by zDNN. - zAIU has very complex data layout requirements; these requirements arrange the tensor to enhance the performance characteristics of the operations. zDNN will format the tensor appropriately on behalf of the caller, and it will do so using an optimized approach. - For deep learning operations, zAIU requires the use of an internal data type (DLFLOAT16). This is a 2-byte data type, similar in concept to Brain float (BFLOAT); that is, it is an AI optimized format that is used to speed up training and inference (from 4-byte formats) while minimizing the loss of accuracy at inference time. The zDNN library will provide a set of APIs that an exploiter will utilize to drive the desired request. zDNN will be available on both z/OS and Linux on Z; the inclusion of Linux on Z provides particular benefit, as it will allow us to enable acceleration in frameworks for z/OS via z/OS Container Extensions (zCX). --- ## Environment z/OS: - Problem state - AMODE64 - XPLINK ### Alignment requirements #### AIU Op Limits _This implies a zDNN limitation as well at this point._ - For all ops: - Number of elements in any dimension must not exceed the value returned by `zdnn_get_nnpa_max_dim_idx_size()` - Total number of bytes required for storing a transformed tensor must not exceed the value returned by `zdnn_get_nnpa_max_tensor_size()` ### Application interfaces for zAIU Enterprise Neural Network Inference #### zDNN General The zDNN deep learning library provides the standard IBM Z software interface to the zAIU. This IBM-provided C library provides a set of functions that handle the data transformation requirements of the AIU and provide wrapper functions for the NNPA instruction primitives. The zDNN functions use the following criteria to determine if zAIU can be used to accelerate a deep learning primitive: - Neural Network Processing Assist (NNPA) facility indicator in the system STFLE output. - Output of the NNPA-QAF (Query Available Functions) request. #### Using zDNN To use the IBM-provided zDNN C library for the NNPA instruction, follow these steps: 1. Link or re-link applications to use the IBM-provided zDNN. The IBM-provided zDNN is a library file in the z/OS UNIX System Services file system and can be statically or dynamically linked into your applications. The paths for the zDNN archive file and the zDNN header files are: **z/OS (LE required):** Path for 64-bit dynamic library files: - `/lib/libzdnn.so` - `/lib/libzdnn.x` Path for the zDNN header files: - `/usr/include/` The XL C/C++ compiler and the z/OS Language Environment provide various environment variables to control processing, in addition to the variables provided by the zDNN library itself. 1. Use the environment variable `_CEE_RUNOPTS` to specify invocation Language Environment runtime options. For more information about using the environment variable `_CEE_RUNOPTS` and other C and LE variables, see z/OS XL C/C++ Programming Guide. 2. For environment variables accepted by the zDNN library, see [Runtime Environment Variables](#env-vars). **Linux on Z:** On Linux on Z we expect to ship source as well a package-installable library and header. The library installation will conform to the standards of the packaging method chosen. --- ## Common Types and Structs Include Files: `zdnn.h` ### Version Information <a id="common-version-info"></a> [Back to Table of Contents](#TOC) ``` #define ZDNN_VERSION "1.0.1" #define ZDNN_VERNUM 0x010001 // 0x[major][minor][patch] #define ZDNN_VER_MAJOR 1 #define ZDNN_VER_MINOR 0 #define ZDNN_VER_PATCH 1 ``` 1. zDNN major version (_ZDNN_VER_MAJOR_) will be incremented if any backwards incompatible changes are introduced to the API. It may also include minor and patch level changes. Patch and minor version will be reset to 0 when major version is incremented. 2. zDNN minor version (_ZDNN_VER_MINOR_) will be incremented if new, backwards compatible functionalities are introduced to the API or if any API functionalities are marked as deprecated. It may also include patch level changes. Patch version will be reset to 0 when minor version is incremented. 3. zDNN patch version (_ZDNN_VER_PATCH_) will be incremented if only backwards compatible bug fixes are introduced. A bug fix being defined as an internal change that fixes incorrect behavior. Functions for checking version incompatibility with the zDNN load library are provided and described in the [Support Functions](#support-functions) section. ### zDNN zTensor <a id="common-ztensor"></a> [Back to Table of Contents](#TOC) ``` typedef struct zdnn_ztensor { zdnn_tensor_desc *pre_transformed_desc; // tensor's shape information before transformation zdnn_tensor_desc *transformed_desc; // transformed tensor's shape information uint64_t buffer_size; // tensor size in bytes void *buffer; // pointer to the tensor in memory bool is_transformed; // indicator if data in buffer has been transformed char reserved[31]; // not currently used, should contain zeros. } zdnn_ztensor; ``` #### General zTensor Requirements <a id="gen-zten-reqs"></a> [Back to Table of Contents](#TOC) - `buffer` requirements: - Calling [zdnn_init_ztensor_with_malloc](#zdnn_init_ztensor_with_malloc) automatically allocates and sets a valid `buffer` for a tensor. - `buffer` field must point to storage allocated of sufficient size to contain the transformed tensor data described by the its `transformed_desc` field. - Calling [zdnn_getsize_ztensor](#zdnn_getsize_ztensor) with the tensor's `transformed_desc` returns the required size. - Start of `buffer` field must be 4k aligned. - `reserved` should contain zeros, otherwise the program may not operate compatibly in the future. - Calling [zdnn_init_ztensor](#zdnn_init_ztensor) or [zdnn_init_ztensor_with_malloc](#zdnn_init_ztensor_with_malloc) will set `reserved` to zeros. #### Concatenated zTensor Requirements <a id="concat-zten-reqs"></a> [Back to Table of Contents](#TOC) - For use with weights/biases/hidden-weights/hidden-biases RNN-gates tensors. - You must use [zdnn_generate_transformed_desc_concatenated](#zdnn_generate_transformed_desc_concatenated) with the appropriate concatenation info - Do not use `zdnn_generate_transformed_desc` with concatenated tensors - The pre-transformed shape dimensions should not include the concatenation. - Thus, the pre-transformed shape should be that of a single gate, not the shape of the combined gates - Afterward transform with [zdnn_transform_ztensor](#zdnn_transform_ztensor) as normal - Must follow [general tensor requirements](#gen-zten-reqs) ### zDNN Tensor Descriptors <a id="common-descriptors"></a> [Back to Table of Contents](#TOC) ``` typedef struct zdnn_tensor_desc { zdnn_data_layouts layout; // data layout zdnn_data_formats format; // internal use only zdnn_data_types type; // data type uint32_t dim4; // number of elements in outermost dimension uint32_t dim3; // ... outer dimension uint32_t dim2; // ... inner dimension uint32_t dim1; // number of elements in innermost dimension } zdnn_tensor_desc; ``` #### Programming Notes - Helper methods [zdnn_init_pre_transformed_desc](#zdnn_init_pre_transformed_desc) and [zdnn_generate_transformed_desc](#zdnn_generate_transformed_desc) or [zdnn_generate_transformed_desc_concatenated](#zdnn_generate_transformed_desc_concatenated) will set the correct dims based on the layout and format. - The [layout](#common-layouts) of the tensor descriptor affects the expected order of the dims. For example: - For tensors with less than 4 dimensions, unspecified dims: - In the [pre_transformed_desc](#common-ztensor) are ignored. For example a [ZDNN_3D](#common-layouts) expects values in dim4, dim3, and dim2. - In the [transformed_desc](#common-ztensor) "unused" dims must be 1. - A [ZDNN_NCHW](#common-layouts) expects dims such that dim4 = N, dim3 = H, dim2 = W, dim1 = C - A [ZDNN_HWCK](#common-layouts) expects dims such that dim4 = W, dim3 = W, dim2 = C, dim1 = K - The [format](#common-formats) changes the expected dims order for [ZDNN_4D](#common-layouts) tensors layouts - [ZDNN_FORMAT_4DFEATURE](#common-formats) expects dims such that dim4 = N, dim3 = H, dim2 = W, dim1 = C - [ZDNN_FORMAT_4DKERNEL](#common-formats) expects dims such that dim4 = H, dim3 = W, dim2 = C, dim1 = K ### zDNN Data Layouts <a id="common-layouts"></a> [Back to Table of Contents](#TOC) The following are layouts for zDNN ztensor descriptors. These indicate the number and order of dimensions to expect for the ztensor data. ``` typedef enum zdnn_data_layouts { ZDNN_1D, // 1d tensor ZDNN_2D, // 2d tensor ZDNN_2DS, // represents special 2D tensors required by LSTM/GRU ZDNN_3D, // 3d tensor ZDNN_3DS, // represents special 3D tensors required by // LSTM/GRU/Softmax/Matmul ZDNN_ZRH, // represents (update, reset, hidden) used by GRU ZDNN_4D, // 4d tensor ZDNN_4DS, // represents special 4D tensors required by LSTM/GRU output ZDNN_NHWC, // 4d feature tensor in NHWC ZDNN_NCHW, // 4d feature tensor in NCHW ZDNN_FICO, // represents (forget, input, cell, output) used by LSTM ZDNN_HWCK, // 4d kernel CNN tensor ZDNN_BIDIR_ZRH, // ZRH variant to work with bidirectional LSTM/GRU output ZDNN_BIDIR_FICO // FICO variant to work with bidirectional LSTM/GRU output } zdnn_data_layouts; ``` Some layouts also indicate special re-arrangement of the data during ztensor transformation. - `ZDNN_2DS` - The outermost dimension of the original shape is promoted to dim4 during transformation. For example, a shape of (a, b) becomes [a, 1, 1, b] (dim4, dim3, dim2, dim1) in the `transformed_desc` - `ZDNN_3DS` - The outermost dimension of the original shape is promoted to dim4 during transformation. For example, a shape of (a, b, c) becomes [a, 1, b, c] (dim4, dim3, dim2, dim1) in the `transformed_desc` - `ZDNN_4DS` - Arrangement for RNN output tensor The followings are set automatically in `transformed_desc` based on `info` when calling `zdnn_generate_transformed_desc_concatenated()`: - `ZDNN_ZRH/FICO` - During transformation, the RNN input gates data are concatenated on the innermost dimension. Supported with `pre_transformed_layout` of `ZDNN_2DS` or `ZDNN_3DS`. - `ZDNN_BIDIR_ZRH/FICO` - Similar to `ZDNN_ZRH/FICO`, used when: 1. transforming RNN input weight gate data, and 2. the input tensor for the current RNN layer is a bidirectional RNN output from a previous RNN layer ### zDNN Data Formats <a id="common-formats"></a> [Back to Table of Contents](#TOC) ``` typedef enum zdnn_data_formats { ZDNN_FORMAT_4DFEATURE, // tensor in AIU data layout format 0 ZDNN_FORMAT_4DKERNEL, // tensor in AIU data layout format 1 } zdnn_data_formats; ``` ### zDNN Data Types <a id="common-types"></a> [Back to Table of Contents](#TOC) ``` typedef enum zdnn_data_types { ZDNN_DLFLOAT16, // 16-bit deep learning format BFLOAT, // Brain floating point format FP16, // 16-bit IEEE-754 floating point format FP32, // 32-bit IEEE-754 floating point format } zdnn_data_types; ``` ### zDNN Statuses <a id="common-statuses"></a> [Back to Table of Contents](#TOC) <!-- prettier-ignore --> | Mnemonic Constant | Value | Meaning | | -------------------------------- | ---------- | ------------------------------ | | ZDNN_OK | 0x00000000 | Success. | #### Warning Statuses <a id="warning-statuses"></a> <!-- prettier-ignore --> | Mnemonic Constant | Value | Meaning | | -------------------------------- | ---------- | ------------------------------ | | ZDNN_ELEMENT_RANGE_VIOLATION | 0x00020001 | AIU operation resulted in data that was out of the normal range. | _Note: ZDNN_ELEMENT_RANGE_VIOLATION indicates a **range violation** occurred for the AIU operation based on the data in the tensors. This usually indicates an overflow of the NNPA internal data type, but can also be associated with operation specific errors, such as "divide by zero". See the "z/Architecture Principles of Operation" for information about range violation on the operation that encountered the violation._ #### General Failing Statuses <a id="failing-statuses"></a> <!-- prettier-ignore --> | Mnemonic Constant | Value | Meaning | | -------------------------------- | ---------- | ------------------------------ | | ZDNN_INVALID_SHAPE\* | 0x00040001 | Invalid shape information in one (or more) of the input/output tensor(s). | | ZDNN_INVALID_LAYOUT | 0x00040002 | Invalid layout information in one (or more) of the input/output tensor(s). | | ZDNN_INVALID_TYPE\* | 0x00040003 | Invalid type information in one (or more) of the input/output tensor(s). | | ZDNN_INVALID_FORMAT\* | 0x00040004 | Invalid format information in one (or more) of the input/output tensor(s). | | ZDNN_INVALID_DIRECTION | 0x00040005 | Invalid RNN direction. | | ZDNN_INVALID_CONCAT_INFO | 0x00040006 | Invalid concatenation info. | | ZDNN_INVALID_STRIDE_PADDING\* | 0x00040007 | Invalid padding type parameter for current strides. | | ZDNN_INVALID_STRIDES\* | 0x00040008 | Invalid stride height or width parameter. | | ZDNN_MISALIGNED_PARMBLOCK\* | 0x00040009 | NNPA parameter block is not on double word boundary. | | ZDNN_INVALID_CLIPPING_VALUE | 0x0004000A | Invalid clipping for the specified operation. | | ZDNN_ALLOCATION_FAILURE | 0x00100001 | Can not allocate storage. | | ZDNN_INVALID_BUFFER | 0x00100002 | Buffer address is NULL or not on 4K-byte boundary or insufficient buffer size. | | ZDNN_CONVERT_FAILURE | 0x00100003 | Floating point data conversion failure. | | ZDNN_INVALID_STATE | 0x00100004 | Invalid zTensor state. | | ZDNN_UNSUPPORTED_AIU_EXCEPTION | 0x00100005 | AIU operation returned an unexpected exception. | _Note: \*In certain scenarios, these statuses are returned only if [ZDNN_ENABLE_PRECHECK](#env-vars) is enabled. When not enabled, these scenarios will lead to abnormal program termination._ #### Hardware Statuses <a id="hw-statuses"></a> The following statuses indicate issues returned from the hardware. <!-- prettier-ignore --> | Mnemonic Constant | Value | Meaning | | -------------------------------- | ---------- | ------------------------------ | | ZDNN_UNSUPPORTED_PARMBLOCK | 0x000C0001 | NNPA parameter block format is not supported by the model. | | ZDNN_UNAVAILABLE_FUNCTION | 0x000C0002 | Specified NNPA function is not defined or installed on the machine. | | ZDNN_UNSUPPORTED_FORMAT | 0x000C0010 | Specified tensor data layout format is not supported. | | ZDNN_UNSUPPORTED_TYPE | 0x000C0011 | Specified tensor data type is not supported. | | ZDNN_EXCEEDS_MDIS | 0x000C0012 | Tensor dimension exceeds maximum dimension index size (MDIS). | | ZDNN_EXCEEDS_MTS | 0x000C0013 | Total number of bytes in tensor exceeds maximum tensor size. (MTS). | | ZDNN_MISALIGNED_TENSOR | 0x000C0014 | Tensor address is not on 4K-byte boundary. | | ZDNN_MISALIGNED_SAVEAREA | 0x000C0015 | Function specific save area address is not on 4K-byte boundary. | The meaning of the following hardware statuses vary based on operation. See the operation that returned the status for the specific meaning. <!-- prettier-ignore --> | Mnemonic Constant | Value | Meaning | | -------------------------------- | ---------- | ------------------------------ | | ZDNN_FUNC_RC_F000 | 0x000CF000 | Function specific response code (F000). | | ZDNN_FUNC_RC_F001 | 0x000CF001 | Function specific response code (F001). | | ZDNN_FUNC_RC_F002 | 0x000CF002 | Function specific response code (F002). | | ZDNN_FUNC_RC_F003 | 0x000CF003 | Function specific response code (F003). | | ZDNN_FUNC_RC_F004 | 0x000CF004 | Function specific response code (F004). | | ZDNN_FUNC_RC_F005 | 0x000CF005 | Function specific response code (F005). | | ZDNN_FUNC_RC_F006 | 0x000CF006 | Function specific response code (F006). | | ZDNN_FUNC_RC_F007 | 0x000CF007 | Function specific response code (F007). | | ZDNN_FUNC_RC_F008 | 0x000CF008 | Function specific response code (F008). | | ZDNN_FUNC_RC_F009 | 0x000CF009 | Function specific response code (F009). | --- ## Runtime Environment Variables <a id="env-vars"></a> [Back to Table of Contents](#TOC) - `ZDNN_ENABLE_PRECHECK`: true/false - If set to `true`, tensor integrity prechecks are run before issuing NNPA operations. - Enabling precheck may impact performance. - Enable to debug issues which cause hardware exceptions that otherwise would result in abnormal program termination. - `ZDNN_STATUS_DIAG`: nnnnnnnn (decimal) or 0xnnnnnnnn (hexadecimal) - Prints or produces diagnostic information whenever zDNN status code is equal to the specified value. Only one status value can be specified. _The following are only available when the zDNN library was built with `ZDNN_CONFIG_DEBUG` enabled._ - `ZDNN_LOGLEVEL`: off/fatal/error/warn/info/debug/trace - Sets logging facility's output level - `ZDNN_LOGMODULE`: module name(s) - Produces log output only when the issuer's module name is in the list. You may specify multiple module names by separating them with either commas or spaces. ### Programming Notes - Environment variables settings are checked during initial library load by [zdnn_init](#zdnn_init). - To change environment variable settings afterward, [zdnn_init](#zdnn_init) must be called again manually. --- ## API Reference [Back to Table of Contents](#TOC) - [Support Functions](#support-functions) - [Data Transformation](#data-transformation) - [Operations](#operations) - [Convenience Functions](#convenience-functions) --- ## Support Functions [Back to Table of Contents](#TOC) - [Initialization](#zdnn_init) - [Query](#zdnn_get_nnpa_max_dim_idx_size) - [Get Size](#zdnn_getsize_ztensor) - [Initialize pre-transformed tensor descriptor](#zdnn_init_pre_transformed_desc) - [Generate transformed tensor descriptor](#zdnn_generate_transformed_desc) - [Generate concatenated transformed tensor descriptor](#zdnn_generate_transformed_desc_concatenated) - [Initialize zTensor](#zdnn_init_ztensor) - [Initialize zTensor with memory allocate](#zdnn_init_ztensor_with_malloc) - [Reset zTensor](#zdnn_reset_ztensor) - [Allocate memory for zTensor](#zdnn_allochelper_ztensor) - [De-allocate memory for zTensor](#zdnn_free_ztensor_buffer) - [Retrieve status message of the status code](#zdnn_get_status_message) - [Reshape zTensor](#zdnn_reshape_ztensor) - [Check if version is runnable](#zdnn_is_version_runnable) - [Get maximum runnable version](#zdnn_get_max_runnable_version) --- ### zdnn_init #### Description Initialize the zDNN library. This sends an NNPA_QAF to query the NNPA and loads the current environment variable settings. This needs to be invoked at least once if zDNN library is statically-linked. It is automatically invoked if zDNN library is dynamically loaded. #### Format ``` void zdnn_init(); ``` #### Parameters None #### Returns None --- ### zdnn_get_nnpa_max_dim_idx_size #### Description Retrieve the maximum dimension index size value currently supported by the AIU from zDNN's internal memory. #### Format ``` uint32_t zdnn_get_nnpa_max_dim_idx_size(); ``` #### Parameters None #### Returns Maximum dimension index size supported by the AIU --- ### zdnn_get_nnpa_max_tensor_size #### Description Retrieve the maximum tensor size value (number of bytes required for storing a transformed tensor) currently supported by the AIU from zDNN's internal memory. #### Format ``` uint64_t zdnn_get_nnpa_max_tensor_size(); ``` #### Parameters None #### Returns Maximum tensor size supported by the AIU --- ### zdnn_is_nnpa_installed #### Description Interrogates the hardware to determine if the NNPA and NNP-internal data type (DLFLOAT16) conversion instructions are installed. Use this function during application initialization to determine whether the AIU hardware is available. #### Format ``` bool zdnn_is_nnpa_installed(); ``` #### Parameters - None. #### Returns `true` if NNPA and zdnn conversion instructions are installed, `false` otherwise. --- ### zdnn_is_nnpa_function_installed #### Description Query, from zDNN internal memory, if requested NNPA functions are available. #### Format ``` bool zdnn_is_nnpa_function_installed(int count, ...); ``` #### Parameters - `int count` - number of NNPA functions to check - `... (additional arguments)` - Function names separated by commas, e.g., _NNPA_MUL, NNPA_MIN_ ``` NNPA_QAF NNPA_ADD NNPA_SUB NNPA_MUL NNPA_DIV NNPA_MIN NNPA_MAX NNPA_LOG NNPA_EXP NNPA_RELU NNPA_TANH NNPA_SIGMOID NNPA_SOFTMAX NNPA_BATCHNORMALIZATION NNPA_MAXPOOL2D NNPA_AVGPOOL2D NNPA_LSTMACT NNPA_GRUACT NNPA_CONVOLUTION NNPA_MATMUL_OP NNPA_MATMUL_OP_BCAST23 ``` #### Returns `true` if all queried formats are installed or if `count` is zero, `false` otherwise. --- ### zdnn_is_nnpa_parmblk_fmt_installed #### Description Query, from zDNN internal memory, if requested parameter block formats are installed. #### Format ``` bool zdnn_is_nnpa_parmblk_fmt_installed(int count, ...); ``` #### Parameters - `int count` - number of NNPA parameter block formats to check - `... (additional arguments)` - NNPA parameter block formats separated by commas ``` NNPA_PARMBLKFORMAT_0 ``` #### Returns `true` if all queried formats are installed or if `count` is zero, `false` otherwise. --- ### zdnn_is_nnpa_datatype_installed #### Description Query, from zDNN internal memory, if requested NNPA data type are installed. #### Format ``` bool zdnn_is_nnpa_datatype_installed(uint16_t types_bitmask); ``` #### Parameters - `uint16_t types_bitmask` - OR'd type bitmasks as defined in zdnn_query_datatypes enum ``` QUERY_DATATYPE_INTERNAL1 ``` #### Returns `true` if all queried data types are installed, `false` otherwise. --- ### zdnn_is_nnpa_layout_fmt_installed #### Description Query, from zDNN internal memory, if requested NNPA data layout format are installed. #### Format ``` bool zdnn_is_nnpa_layout_fmt_installed(uint32_t layout_bitmask); ``` #### Parameters - `uint32_t layout_bitmask` - OR'd layout bitmasks as defined in zdnn_query_layoutfmts enum ``` QUERY_LAYOUTFMT_4DFEATURE QUERY_LAYOUTFMT_4DKERNEL ``` #### Returns `true` if all queried data layouts are installed, `false` otherwise. --- ### zdnn_is_nnpa_conversion_installed #### Description Query, from zDNN internal memory, if requested NNPA data-type to/from BFP format conversions are installed. #### Format ``` bool zdnn_is_nnpa_conversion_installed(nnpa_data_type type, uint16_t format_bitmask); ``` #### Parameters - `nnpa_data_type type` - NNPA data-type number as defined in nnpa_data_type enum ``` NNPA_DATATYPE_1 ``` - `uint16_t format_bitmask` - OR'd BFP format bitmasks as defined in zdnn_query_bfpfmts enum ``` QUERY_BFPFMT_TINY (FP16) QUERY_BFPFMT_SHORT (FP32/BFLOAT) ``` #### Returns `true` if all queried conversions are installed, `false` otherwise. --- ### zdnn_get_library_version #### Description Retrieve library version number as a 32-bit hex value (`0x00[major][minor][patch]`). #### Format ``` uint32_t zdnn_get_library_version(); ``` #### Returns Library version number in `0x00[major][minor][patch]` format. --- ### zdnn_get_library_version_str #### Description Retrieve the library version number and build information as a string. #### Format ``` char *zdnn_get_library_version_str(); ``` #### Returns Library version number and build information as a string. --- ### zdnn_refresh_nnpa_query_result #### Description Refresh zDNN in-memory query result from zAIU. #### Format ``` zdnn_status zdnn_refresh_nnpa_query_result(); ``` #### Parameters None ##### Programming Notes This is called automatically as a part of `zdnn_init` and should not need to be called directly. Manually refreshing query results before making other `zdnn_query_*` calls may noticeably impact performance. #### Returns zdnn_status indications - `ZDNN_OK` - `ZDNN_UNAVAILABLE_FUNCTION` --- ### zdnn_getsize_ztensor #### Description Used to determine the buffer size required for the transformed tensor (including concatenated) in zDNN transformed format. Requires tensor descriptor (`zdnn_tensor_desc`) with transformed shape information. #### Format ``` uint64_t zdnn_getsize_ztensor(const zdnn_tensor_desc *tfrmd_desc); ``` #### Parameters - `zdnn_tensor_desc *tfrmd_desc` - Contains transformed information about the shape, layout and data type. #### Returns zdnn_status indications - required buffer size in bytes --- ### zdnn_init_pre_transformed_desc #### Description Initialize tensor descriptor (`zdnn_tensor_desc`) struct with pre-transformed (original) shape information. #### Format ``` void zdnn_init_pre_transformed_desc(zdnn_data_layouts layout, zdnn_data_types type, zdnn_tensor_desc *pre_tfrmd_desc, ...); ``` #### Parameters - `zdnn_data_layouts layout` - data layout - `zdnn_data_types type` - data type - `zdnn_tensor_desc *pre_tfrmd_desc` - output zdnn_tensor_desc struct - `... (additional arguments)` - Variadic: number of elements in each dimension in accordance to the layout, in outermost to innermost order #### Returns - None --- ### zdnn_generate_transformed_desc #### Description Generate transformed tensor descriptor information based on supplied pre-transformed tensor descriptor. #### Format ``` zdnn_status zdnn_generate_transformed_desc( const zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc); ``` #### Parameters - `zdnn_tensor_desc *pre_tfrmd_desc` - input tensor descriptor with pre-transformed shape information - `zdnn_tensor_desc *tfrmd_desc` - output `zdnn_tensor_desc` struct #### zdnn_status indications - `ZDNN_OK` - `ZDNN_INVALID_LAYOUT` - pre-transformed `layout` is not recognized or is a layout only used for concatenated tensors. --- ### zdnn_generate_transformed_desc_concatenated #### Description Generate concatenated transformed tensor descriptor information for RNN input-gates tensors based on a supplied pre-transformed tensor descriptor. #### Format ``` zdnn_status zdnn_generate_transformed_desc_concatenated( const zdnn_tensor_desc *pre_tfrmd_desc, zdnn_concat_info info, zdnn_tensor_desc *tfrmd_desc); ``` #### Parameters - `zdnn_tensor_desc *pre_tfrmd_desc` - input tensor descriptor with pre-transformed shape information - `zdnn_concat_info info` - Information about how the tensors will be concatenated, consists of the RNN_TYPE, PREV_LAYER and USAGE flags OR'd together: RNN_TYPE flags: - RNN_TYPE_LSTM - For LSTM - RNN_TYPE_GRU - For GRU PREV_LAYER flags: - PREV_LAYER_UNI - Previous RNN layer is uni-directional - PREV_LAYER_NONE - Previous layer is not a RNN layer - PREV_LAYER_BIDIR - Previous RNN layer is bi-directional USAGE flags: - USAGE_WEIGHTS - Concatenate as input weights - USAGE_HIDDEN_WEIGHTS - Concatenate as input hidden-weights - USAGE_BIASES - Concatenate as input biases - USAGE_HIDDEN_BIASES - Concatenate as input hidden-biases - `zdnn_tensor_desc *tfrmd_desc` - output `zdnn_tensor_desc` struct #### zdnn_status indications - `ZDNN_OK` - `ZDNN_INVALID_LAYOUT` - pre-transformed `layout` is not recognized or is not supported for concatenated tensors. - `ZDNN_INVALID_CONCAT_INFO` - invalid concatenation information. --- ### zdnn_init_ztensor #### Description Initialize a `zdnn_ztensor` struct using the pre-transformed and transformed tensor shape information #### Format ``` void zdnn_init_ztensor(zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc, zdnn_ztensor *output); ``` #### Parameters - `zdnn_tensor_desc *pre_tfrmd_desc` - input tensor descriptor with pre-transformed shape information - `zdnn_tensor_desc *tfrmd_desc` - input tensor descriptor with transformed shape information - `zdnn_ztensor *output` - The `zdnn_ztensor` struct being initialized. #### Returns - None --- ### zdnn_init_ztensor_with_malloc #### Description Same functionality as `zdnn_init_ztensor`, and computes the size required for the tensor in the zDNN transformed format and allocates the storage for it. Sets `buffer` and `buffer_size` fields within `output`. #### Format ``` zdnn_status zdnn_init_ztensor_with_malloc(zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc, zdnn_ztensor *output); ``` #### Parameters - `zdnn_tensor_desc *pre_tfrmd_desc` - input tensor descriptor with pre-transformed shape information - `zdnn_tensor_desc *tfrmd_desc` - input tensor descriptor with transformed shape information - `zdnn_ztensor *output` - The `zdnn_ztensor` struct being initialized. #### Returns zdnn_status indications - `ZDNN_OK` - `ZDNN_INVALID_FORMAT` - `tfrmd_desc->format` is not recognized. - `ZDNN_INVALID_TYPE` - `tfrmd_desc->type` is not recognized or is a pre_tfrmd_desc type. - `ZDNN_INVALID_SHAPE` - (if any of the following are true) - One of `tfrmd_desc->dim*` dimensions is 0. - One of `tfrmd_desc->dim*` dimensions is greater than `zdnn_get_nnpa_max_dim_idx_size`. - Note: concatenation dimensions have a smaller maximum size. See [LSTM](#lstm-hid_sz) or [GRU](#gru-hid_sz). - The total number of tfrmd_desc elements is larger than `zdnn_get_nnpa_max_tensor_size`. - `ZDNN_ALLOCATION_FAILURE` - Unable to allocate required memory on a 4K boundary. --- ### zdnn_reset_ztensor #### Description Reset a `zdnn_ztensor` struct for reuse. _Note this operation does not set or reset the `buffer` and `buffer_size` fields nor free the transformed area storage._ #### Format ``` void zdnn_reset_ztensor(zdnn_ztensor *ztensor); ``` #### Parameters - `zdnn_ztensor *output` - The `zdnn_ztensor` struct being reset. #### Returns - None --- ### zdnn_allochelper_ztensor #### Description Calculate the size required for the tensor in the zDNN transformed format and allocate the needed storage, satisfying alignment requirements. Sets `buffer` and `buffer_size` fields within `ztensor`. _Note that the calling application assumes ownership of this storage and is responsible for freeing it._ #### Format ``` zdnn_status zdnn_allochelper_ztensor(zdnn_ztensor *ztensor); ``` #### Parameters - `zdnn_ztensor *ztensor` - A `zdnn_ztensor` struct that contains the transformed shape information in the `transformed_desc` field. #### Returns zdnn_status indications - `ZDNN_OK` - `ZDNN_INVALID_FORMAT` - `ztensor->transformed_desc->format` is not recognized. - `ZDNN_INVALID_TYPE` - `ztensor->transformed_desc->type` is not recognized or is a pre_transformed_desc type. - `ZDNN_INVALID_SHAPE` - (if any of the following are true) - One of `ztensor->transformed_desc->dim*` dimensions is 0. - One of `ztensor->transformed_desc->dim*` dimensions is greater than `zdnn_get_nnpa_max_dim_idx_size`. - Note: concatenation dimensions have a smaller maximum size. See [LSTM](#lstm-hid_sz) or [GRU](#gru-hid_sz). - The total number of transformed_desc elements is larger than `zdnn_get_nnpa_max_tensor_size`. - `ZDNN_ALLOCATION_FAILURE` - Unable to allocate required memory on a 4K boundary. --- ### zdnn_free_ztensor_buffer #### Description Given an input zdnn_ztensor, zdnn_free_ztensor_buffer will free the transformed area storage associated with it. _Note that the routine does not free the storage allocated for the zdnn_ztensor struct itself._ #### Format ``` zdnn_status zdnn_free_ztensor_buffer(const zdnn_ztensor *ztensor); ``` #### Parameters - `zdnn_ztensor *tensor` - A `zdnn_ztensor` struct with field buffer pointing to storage allocated. #### Returns zdnn_status indications - `ZDNN_OK` - `ZDNN_INVALID_BUFFER` - `tensor->buffer` is `NULL` --- ### zdnn_get_status_message #### Description Retrieve status message of the status code #### Format ``` const char *zdnn_get_status_message(zdnn_status status); ``` #### Parameters - `zdnn_status status` - Status code #### Returns Pointer to the description string or "(Status string is not defined.)" if `status` is not defined. --- ### zdnn_reshape_ztensor #### Description Reshape and copy buffer content from source zTensor's buffer to destination zTensor's in accordance to destination zTensor's shape. The following conditions must be satisfied: - Both tensor's transformed_desc must be fully initialized - `dest->buffer` must be pre-allocated - `src` must be transformed - `dest` must be not already transformed - Both `transformed_desc->layout` must be the same and either NHWC or HWCK - Both zTensors must contain equal number of elements #### Format ``` zdnn_status zdnn_reshape_ztensor(const zdnn_ztensor *src, zdnn_ztensor *dest); ``` #### Parameters - `src` - Source zTensor to copy from - `dest` - Destination zTensor to copy to #### Programming Notes - If `src` and `dest` have the same `transformed_desc->dim1` dimension size, the transformed data is directly copied to the destination without untransformation. - If `src` and `dest` have different `transformed_desc->dim1` dimension sizes, reshaping will internally un-transform the source and then re-transform the values into the destination. #### Returns - `ZDNN_OK` - `ZDNN_INVALID_SHAPE` - (if any of the following are true) - `src`'s and `dest`'s `transformed_desc->dim*` total to different numbers of elements. - One of `dest->transformed_desc->dim*` dimensions is 0. - One of `dest->transformed_desc->dim*` dimensions is greater than `zdnn_get_nnpa_max_dim_idx_size`. - Note: concatenation dimensions have a smaller maximum size. See [LSTM](#lstm-hid_sz) or [GRU](#gru-hid_sz). - The total number of `dest->transformed_desc-dim*` elements is larger than `zdnn_get_nnpa_max_tensor_size`. - `ZDNN_INVALID_LAYOUT` - (if any of the following are true) - `src`'s and `dest`'s `transformed_desc->layout` are not the same. - `transformed_desc->layout` is not `ZDNN_NHWC` nor `ZDNN_HWCK`. - `src->pre_transformed_desc->layout` is not recognized or is not a valid pre_transformed_desc layout. - `dest->pre_transformed_desc->layout` is not recognized or is not a valid pre_transformed_desc layout. - `ZDNN_INVALID_STATE` - (if any of the following are true) - `src` is not already transformed. - `dest` is already transformed. - `ZDNN_INVALID_FORMAT` - `src->transformed_desc->format` is not `ZDNN_FORMAT_4DFEATURE`. - `ZDNN_INVALID_TYPE` (if any of the following are true) - `src->pre_transformed_desc->type` is not recognized or is a transformed_desc type. - `dest->pre_transformed_desc->type` is not recognized or is a transformed_desc type. - `dest->transformed_desc->type` is not recognized or is a pre_transformed_desc type. - `ZDNN_INVALID_BUFFER` (if any of the following are true) - `src->buffer` is `NULL`. - `src->buffer` is not on a 4K boundary. - `dest->buffer` is `NULL`. - `dest->buffer` is not on a 4K boundary. - `dest->buffer_size` is too small to hold transformed values. - `ZDNN_CONVERT_FAILURE` - Values failed to un-transform or transform. --- ### zdnn_is_version_runnable #### Description Check if application built for zDNN version `ver_num` can be run on the current AIU hardware with the installed zDNN library #### Format ``` bool zdnn_is_version_runnable(uint32_t ver_num); ``` #### Parameters - `ver_num` - zDNN version number from the application in 0x00[major][minor][patch] form. Typically this is ZDNN_VERNUM used to compile the application #### Returns - true/false --- ### zdnn_get_max_runnable_version #### Description Returns the maximum zDNN version number that the current hardware and installed zDNN library can run together. The returned value means the current runtime environment fully supports zDNN APIs set of that `major`.`minor` version and below. #### Format ``` uint32_t zdnn_get_max_runnable_version(); ``` #### Parameters - None #### Returns - A 32-bit zDNN version number in 0x00[major][minor]FF form. --- ## Data Transformation [Back to Table of Contents](#TOC) - [Transform to zTensor](#zdnn_transform_ztensor) - [Transform to Original](#zdnn_transform_origtensor) --- zAIU requires the tensor data to be arranged in a format that enhances the performance characteristics of the operations. In this documentation, it is referred to as "transformed format". In addition, data conversions are necessary from the common formats (FP32, FP16, BFLOAT) to the internal format (DLFLOAT16) supported by the AIU. Two functions are provided: - '`zdnn_transform_ztensor` - zdnn_transform_ztensor will transform the input tensor and convert the input data to the format required by the AIU. The resulting transformed ztensor can be reused as many times as necessary. - See [zdnn_transform_ztensor](#zdnn_transform_ztensor) for details on transforming an input tensor to the internal format. - `zdnn_transform_origtensor` - zdnn_transform_origtensor transforms a ztensor (usually output from an operation or network) to the format and data types that are usable by the application. - See [zdnn_transform_origtensor](#zdnn_transform_origtensor) for details on transforming an input tensor to the internal format. --- ### zdnn_transform_ztensor #### Description Converts the input tensor to the supported transformed format for execution by zdnn operations. If transformation is successful the `is_transformed` field within `ztensor` will be set to `true` otherwise it is set to `false`. Transformation will fail if `is_transformed` was already `true`. _Note that the tensor layout in memory, once in transformed format, is dependent on the content of the input tensor's descriptors (`zdnn_tensor_desc` fields). Once converted, a `zdnn_ztensor` should only be manipulated by zDNN API functions._ #### Format ``` zdnn_status zdnn_transform_ztensor(zdnn_ztensor *ztensor, ...); ``` #### Parameters - `zdnn_ztensor *tensor` - The input `zdnn_ztensor` struct. `pre_transformed_desc` and `transformed_desc` must be set, `is_transformed` must be `false`. A 4k-aligned tensor storage must be pre-allocated by the caller (directly or by calling the zDNN allocation helper function) and field `buffer` must point to the storage. - `... (additional arguments)` - Variadic: list of pointers for input data to be transformed: - Non-concatenated: 1 data pointer - LSTM concatenated: 4 data pointers, one for each input gate in Forget, Input, Cell, Output (FICO) order - GRU concatenated: 3 data pointers, one for each input gate in (Z)update, Reset, Hidden, (ZRH) gate order #### Programming Notes - This function clears the pre-thread floating-point exception flags at entry, and may set `FE_UNDERFLOW` / `FE_INVALID` / `FE_INEXACT` / `FE_OVERFLOW` when it encounters errors during data conversion. #### Returns zdnn_status indications - `ZDNN_OK` - `ZDNN_INVALID_FORMAT` - `zdnn_ztensor->transformed_desc->format` is not recognized. - `ZDNN_INVALID_LAYOUT` - (if any of the following are true) - `zdnn_ztensor->pre_transformed_desc->layout` is not recognized or is not a valid pre_transformed_desc layout. - `zdnn_ztensor->transformed_desc->layout` is not recognized or is not a valid transformed_desc layout. - `ZDNN_INVALID_TYPE` - (if any of the following are true) - `zdnn_ztensor->pre_transformed_desc->type` is not recognized or is a transformed_desc type. - `zdnn_ztensor->transformed_desc->type` is not recognized or is a pre_transformed_desc type. - `ZDNN_INVALID_BUFFER` (if any of the following are true) - `buffer` is `NULL`. - `buffer` is not on a 4K boundary. - `buffer_size` is too small to hold transformed values. - `ZDNN_INVALID_SHAPE` - (if any of the following are true) - One of `zdnn_ztensor->transformed_desc->dim*` dimensions is 0. - One of `zdnn_ztensor->transformed_desc->dim*` dimensions is greater than `zdnn_get_nnpa_max_dim_idx_size`. - Note: concatenation dimensions have a smaller maximum size. See [LSTM](#lstm-hid_sz) or [GRU](#gru-hid_sz). - The total number of transformed_desc elements is larger than `zdnn_get_nnpa_max_tensor_size`. - `ZDNN_INVALID_STATE` - Tensor is already transformed. - `ZDNN_CONVERT_FAILURE` - Values failed to transform. --- ### zdnn_transform_origtensor #### Description Converts the input tensor from the zDNN transformed format back to a standard non-transformed layout. The `is_transformed` field within `ztensor` must be `true`. All stick format tensors are supported, except: - Kernel tensors - Concatenated RNN input-gates tensors #### Format ``` zdnn_status zdnn_transform_origtensor(const zdnn_ztensor *ztensor, void *out_buf); ``` #### Parameters - `zdnn_ztensor *ztensor` - The input `zdnn_ztensor` struct. `pre_transformed_desc`, `transformed_desc` and `buffer` must be set, `is_transformed` must be `true`. - `void *out_buf` - The buffer for storing the standard non-transformed tensor data. Must be pre-allocated by the caller. #### Programming Notes - This function clears the pre-thread floating-point exception flags at entry, and may set `FE_UNDERFLOW` / `FE_INVALID` / `FE_INEXACT` / `FE_OVERFLOW` when it encounters errors during data conversion. #### Returns zdnn_status indications - `ZDNN_OK` - `ZDNN_INVALID_FORMAT` - `ztensor->transformed_desc->format` is not `ZDNN_FORMAT_4DFEATURE`. - `ZDNN_INVALID_LAYOUT` - (if any of the following are true) - `zdnn_ztensor->pre_transformed_desc->layout` is not recognized or is not a valid pre_transformed_desc layout. - `zdnn_ztensor->transformed_desc->layout` is not recognized or is not a valid transformed_desc layout required by this function. - `ZDNN_INVALID_TYPE` - `ztensor->pre_transformed_desc->type` is not recognized or is a transformed_desc type. - `ztensor->transformed_desc->type` is not recognized or is a pre_transformed_desc type. - `ZDNN_INVALID_BUFFER` (if any of the following are true) - `ztensor->buffer` is `NULL`. - `ztensor->buffer` is not on a 4K boundary. - `ZDNN_INVALID_STATE` - `ztensor` is not transformed. - `ZDNN_CONVERT_FAILURE` - Values failed to un-transform. --- ## Operations See [Table of Contents](#TOC) for operations list --- ## Element-wise Operations <a id="elwise-ops"></a> [Back to Table of Contents](#TOC) - [Addition](#zdnn_add) - [Subtraction](#zdnn_sub) - [Multiplication](#zdnn_mul) - [Division](#zdnn_div) - [Minimum](#zdnn_min) - [Maximum](#zdnn_max) - [Natural Logarithm](#zdnn_log) - [Exponential](#zdnn_exp) --- ### zdnn_add - [Back to Table of Contents](#TOC) - [Back to Element-wise Operations](#elwise-ops) #### Description Given two input tensors in zDNN transformed format, performs element-wise addition and stores the result into the provided output zDNN tensor. _Note that for zDNN use, broadcasting of the input tensor(s) must be performed by the caller. As such, the input tensors must be of the same shape._ #### Format ``` zdnn_status zdnn_add(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input_a` - Tensor with addends to add to `input_b` tensor - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *input_b` - Tensor with addends to add to `input_a` tensor - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor to hold the result of the addition - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Addition] [tensorflow addition]: https://www.tensorflow.org/api_docs/python/tf/math/add [ONNX Addition] [onnx addition]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#Add --- ### zdnn_sub - [Back to Table of Contents](#TOC) - [Back to Element-wise Operations](#elwise-ops) #### Description Given two input tensors in zDNN transformed format, performs element-wise subtraction and stores the result into the provided output zDNN tensor. _Note that for zDNN use, broadcasting of the input tensor(s) must be performed by the caller. As such, the input tensors must be of the same shape._ #### Format ``` zdnn_status zdnn_sub(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input_a` - Tensor with minuends that will be subtracted by `input_b` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *input_b` - Tensor with subtrahends to subtract from `input_a` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor to hold the result of the subtraction - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Subtraction] [tensorflow subtraction]: https://www.tensorflow.org/api_docs/python/tf/math/subtract [ONNX Subtraction] [onnx subtraction]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#sub --- ### zdnn_mul - [Back to Table of Contents](#TOC) - [Back to Element-wise Operations](#elwise-ops) #### Description Given two input tensors in zDNN transformed format, performs element-wise multiplication and stores the result into the provided output zDNN tensor. _Note that for zDNN use, broadcasting of the input tensor(s) must be performed by the caller. As such, the input tensors must be of the same shape._ #### Format ``` zdnn_status zdnn_mul(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input_a` - Tensor with multiplicands that will be multiplied by `input_b` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *input_b` - Tensor with multipliers for `input_a` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor to hold the result of the multiplication. - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Multiplication] [tensorflow multiplication]: https://www.tensorflow.org/api_docs/python/tf/math/multiply [ONNX Multiplication] [onnx multiplication]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#Mul --- ### zdnn_div - [Back to Table of Contents](#TOC) - [Back to Element-wise Operations](#elwise-ops) #### Description Given two input tensors in zDNN transformed format, performs element-wise division and stores the result into the provided output zDNN tensor. _Note that for zDNN use, broadcasting of the input tensor(s) must be performed by the caller. As such, the input tensors must be of the same shape._ #### Format ``` zdnn_status zdnn_div(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input_a` - Tensor with dividends that will be divided by `input_b` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *input_b` - Tensor with divisors for `input_a` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor to hold the result of the division. - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Division] [tensorflow division]: https://www.tensorflow.org/api_docs/python/tf/math/divide [ONNX Division] [onnx division]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#Div --- ### zdnn_min - [Back to Table of Contents](#TOC) - [Back to Element-wise Operations](#elwise-ops) #### Description Given two input tensors in zDNN transformed format, computes the element-wise minimum and stores the result into the provided output zDNN tensor. _Note that for zDNN use, broadcasting of the input tensor(s) must be performed by the caller. As such, the input tensors must be of the same shape._ #### Format ``` zdnn_status zdnn_min(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input_a` - Tensor with values that will be compared with `input_b` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *input_b` - Tensor with values that will be compared with `input_a` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor that holds the smaller value from each comparison of the inputs. - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Minimum] [tensorflow minimum]: https://www.tensorflow.org/api_docs/python/tf/math/minimum [ONNX Minimum] [onnx minimum]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#min --- ### zdnn_max - [Back to Table of Contents](#TOC) - [Back to Element-wise Operations](#elwise-ops) #### Description Given two input tensors in zDNN transformed format, computes the element-wise maximum and stores the result into the provided output zDNN tensor. _Note that for zDNN use, broadcasting of the input tensor(s) must be performed by the caller. As such, the input tensors must be of the same shape._ #### Format ``` zdnn_status zdnn_max(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input_a` - Tensor with values that will be compared with `input_b` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *input_b` - Tensor with values that will be compared with `input_a` tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor that holds the larger value from each comparison of the inputs. - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions)s - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Maximum] [tensorflow maximum]: https://www.tensorflow.org/api_docs/python/tf/math/maximum [ONNX Maximum] [onnx maximum]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#max --- ### zdnn_log - [Back to Table of Contents](#TOC) - [Back to Element-wise Operations](#elwise-ops) #### Description Given an input tensor in zDNN transformed format, computes the natural logarithm element-wise and stores the result into the provided output zDNN tensor. #### Format ``` zdnn_status zdnn_log(const zdnn_ztensor *input, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - Tensor with values to evaluate. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor that holds the calculated natural logarithm of each value from `input_a` - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Natural Logarithm] [tensorflow natural logarithm]: https://www.tensorflow.org/api_docs/python/tf/math/log [ONNX Natural Logarithm] [onnx natural logarithm]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#Log --- ### zdnn_exp - [Back to Table of Contents](#TOC) - [Back to Element-wise Operations](#elwise-ops) #### Description Given an input tensor in zDNN transformed format, computes the exponential element-wise and stores the result into the provided output zDNN tensor. #### Format ``` zdnn_status zdnn_exp(const zdnn_ztensor *input, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - Tensor with values to evaluate. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor that holds the calculated exponential of each value from `input` - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Exponential] [tensorflow exponential]: https://www.tensorflow.org/api_docs/python/tf/math/exp [ONNX Exponential] [onnx exponential]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#Exp --- ## Activation Operations <a id="act-ops"></a> [Back to Table of Contents](#TOC) - [Rectified Linear](#zdnn_relu) - [Hyperbolic Tangent](#zdnn_tanh) - [Sigmoid](#zdnn_sigmoid) - [Softmax](#zdnn_softmax) --- ### zdnn_relu - [Back to Table of Contents](#TOC) - [Back to Activation Operations](#act-ops) #### Description Given an input tensor in zDNN transformed format produce an output tensor where the rectified linear function, y = max(0, x) is applied to the input element-wise. If an optional clipping_value is provided, clipping is performed against the intermediate output where z = min(y, clipping_value). #### Format ``` zdnn_status zdnn_relu(const zdnn_ztensor *input, const void *clipping_value, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - Tensor with values to evaluate. - Must follow [general tensor requirements](#gen-zten-reqs) - `void *clipping_value` - A pointer to an FP32 value, used to clip input tensor's elements. - If set to NULL or 0, no clipping will occur. - Must not be a negative value. - `zdnn_ztensor *output` - Tensor that holds the rectified linear function result of each value from `input` - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - `ZDNN_INVALID_CLIPPING_VALUE` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Rectified Linear] [tensorflow rectified linear]: https://www.tensorflow.org/api_docs/python/tf/nn/relu [ONNX Rectified Linear] [onnx rectified linear]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#relu --- ### zdnn_tanh - [Back to Table of Contents](#TOC) - [Back to Activation Operations](#act-ops) #### Description Given an input tensor in zDNN transformed format, produces an output tensor where the hyperbolic tangent is applied to the input element-wise. #### Format ``` zdnn_status zdnn_tanh(const zdnn_ztensor *input, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - Tensor with values to evaluate. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor that holds the hyperbolic tangent result of each value from `input` - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Hyperbolic Tangent] [tensorflow hyperbolic tangent]: https://www.tensorflow.org/api_docs/python/tf/math/tanh [ONNX Hyperbolic Tangent] [onnx hyperbolic tangent]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#Tanh --- ### zdnn_sigmoid - [Back to Table of Contents](#TOC) - [Back to Activation Operations](#act-ops) #### Description Given an input tensor in zDNN transformed format, produces an output tensor where the sigmoid function is applied to the input element-wise. #### Format ``` zdnn_status zdnn_sigmoid(const zdnn_ztensor *input, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - Tensor with values to evaluate. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - Tensor that holds the sigmoid result of each value from `input` - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Sigmoid] [tensorflow sigmoid]: https://www.tensorflow.org/api_docs/python/tf/math/sigmoid [ONNX Sigmoid] [onnx sigmoid]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#Sigmoid --- ### zdnn_softmax - [Back to Table of Contents](#TOC) - [Back to Activation Operations](#act-ops) #### Description Given an input tensor in zDNN transformed format, computes the softmax (normalized exponential) for each vector formed in dimension-1, then if `act_func` is not `SOFTMAX_ACT_NONE`, the activation function is applied to the results. Finally stores the results into the provided output zDNN tensor. _Note: Other parameters, such as axis, are not supported._ #### Format ``` zdnn_status zdnn_softmax(const zdnn_ztensor *input, void *save_area, zdnn_softmax_act act_func, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - [ZDNN_3DS](#common-layouts) tensor with pre-transformed shape [batch size, batch size, vector dimension size] or output from another operation that is of the correct shape. - Must follow [general tensor requirements](#gen-zten-reqs) - `void *save_area` - A preallocated memory address to use for temporary storage during internal operation processing. - The preallocate memory must be at least 8K bytes in size, aligned on a 4k boundary. - If set to NULL, the operation will determine, allocate and free storage automatically. - `zdnn_softmax_act act_func` - Activation function to apply to the results. - `SOFTMAX_ACT_NONE` or `SOFTMAX_ACT_LOG` - `zdnn_ztensor *output` - [ZDNN_3DS](#common-layouts) tensor with the same shape as `input_a` that holds the softmax result of each value from `input_a`. - Must follow [general tensor requirements](#gen-zten-reqs) #### Programming Notes - If all elements of a dimension 1 vector are the largest magnitude negative number possible for the transformed data type, accuracy may be reduced. - A `ZDNN_3DS` tensor is expected, where the `transformed_desc` dim1 describes the vector, and dim2 and dim4 are used to batch multiple vector requests together. Dim3 must always be 1. The `zdnn_softmax` operation is performed against the vector in dim1 repeating for each dim1 vector in the dim4 and dim2 dimensions. - Tensors that cannot be processed as vectors in dim1 or as batches of dim1 vectors must be coerced or reshaped by the caller. - When the entire tensor is to be processed by softmax, it can be coerced by simply creating an alternate descriptor prior to zDNN transformation. For example: - A 4D tensor with `pre_transformed_desc` dimensions 2x2x2x2 and a data array of 16 FP32 entries could have an alternate `ZDNN_3DS` layout `pre_transformed_desc` using dimensions 1x1x16 and use the same original data array prior to `zdnn_transform_ztensor`. After transformation, such a tensor would be valid for `zdnn_softmax`. - In another example, the 4D 2x2x2x2 tensor could be processed as 2 batches of 8 vectors using a `ZDNN_3DS` layout `pre_transformed_desc` with dimensions 1x2x8. #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - `ZDNN_ALLOCATION_FAILURE` - A preallocated `save_area` was not specified and internal allocation for the required memory failed. - [hardware statuses](#hw-statuses) - `ZDNN_FUNC_RC_F000` - input tensor `input->transformed_desc->dim3` was not 1. - `ZDNN_FUNC_RC_F001` - Invalid `act_func` #### Framework Examples [TensorFlow Softmax] [tensorflow softmax]: https://www.tensorflow.org/api_docs/python/tf/nn/softmax [ONNX Softmax] [onnx softmax]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#Softmax --- ## Normalization Operations <a id="norm-ops"></a> [Back to Table of Contents](#TOC) - [Mean Reduce](#zdnn_meanreduce2d) - [Batch Norm](#zdnn_batchnorm) --- ### zdnn_meanreduce2d - [Back to Table of Contents](#TOC) - [Back to Normalization Operations](#norm-ops) #### Description Given an input tensor in zDNN transformed format, produces a downsampled tensor reducing the middle dimensions to a size of 1 based on the mean of the original values and stores the result to the provided output zDNN tensor. #### Format ``` zdnn_status zdnn_meanreduce2d(const zdnn_ztensor *input, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - Must be a [ZDNN_NHWC](#common-layouts) tensor with pre_transformed shape [batch_Num, Height, Width, Channel]. - Height and Width dimension must be less than or equal to 1024. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - The result tensor which will hold the result of the pooling operation in its buffer. - Shape: - `output` dimensions batch_Num and Channel must be the same as the respective input dimensions. - `output` dimensions Height and Width must be 1. - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - `ZDNN_INVALID_SHAPE` - Shape of input or output tensor is invalid based on given kernel and stride parameters - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) - `ZDNN_FUNC_RC_F001` - `input` tensor has a Height or Width dimension greater than allowed for `zdnn_meanreduce2d`. #### Framework Examples [TensorFlow Reduce Mean] with `axis` set for the Height and Width axes and `keepdims` set to True. [tensorflow reduce mean]: https://www.tensorflow.org/api_docs/python/tf/math/reduce_mean [ONNX Reduce Mean] [onnx reduce mean]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#ReduceMean --- ### zdnn_batchnorm - [Back to Table of Contents](#TOC) - [Back to Normalization Operations](#norm-ops) #### Description Given three input zDNN tensors `input_a`, `input_b`, and `input_c`, computes the batch-normalized result for each vector formed in dimension-1 as follows: output = input_b \* input_a + input_c where `input_b` is a precomputed elementwise divide of scale and variance tensors, and `input_c` is a precomputed elementwise multiply of (-1) \* mean and 'input_b' + input bias tensors. #### Format ``` zdnn_status zdnn_batchnorm(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input_a` - Must be a 4D [ZDNN_NHWC](#common-layouts) tensor - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *input_b` - Must be a 1D [ZDNN_1D](#common-layouts) tensor - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *input_c` - Must be a 1D [ZDNN_1D](#common-layouts) tensor - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *output` - A zdnn_ztensor of the same size as `input_a` representing the computed value of the above formula - Must follow [general tensor requirements](#gen-zten-reqs) #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow Batchnorm] [tensorflow batchnorm]: https://www.tensorflow.org/api_docs/python/tf/keras/layers/BatchNormalization [ONNX Batchnorm] [onnx batchnorm]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#BatchNormalization --- ### zdnn_matmul_op [Back to Table of Contents](#TOC) #### Description Given three input zDNN tensors `input_a`, `input_b`, and `input_c`, determine the matrix multiplication of `input_a` \* `input_b` then perform one of the following operations, using `input_c` against the dot product, storing the result into the specified `output` zDNN tensor: - Addition - Compare - If dot product is greater than element. - Compare - If dot product is greater or equal to element. - Compare - If dot product is equal to element. - Compare - If dot product is not equal to element. - Compare - If dot product is less than or equal to element. - Compare - If dot product is less than element. For an operation type of addition, `input_c` is added to the intermediate dot product. For operation types of comparison, the intermediate dot product is compared to `input_c` and if the comparison is true, the result is set to a value of 1; otherwise it is set to a value of 0. The outermost dimension can optionally indicate that the inputs are stacks of matrices. The results for each matrix stack is independent of other stacks but all stacks are calculated in a single call. #### Format ``` zdnn_status zdnn_matmul_op(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, zdnn_matmul_ops op_type, zdnn_ztensor *output); ``` #### Input / Output matmul tensor requirements <a id="matmul-io-table"></a> - See table in this section for `pre_transformed_desc` and shape requirements for each tensor. - All tensors must either be stacked or unstacked. - Must follow [general tensor requirements](#gen-zten-reqs) | type | input_a | input_b | input_c | result | | --------- | -------------------- | -------------------- | ----------------- | -------------------- | | unstacked | `ZDNN_2D` (m, n) | `ZDNN_2D` (n, p) | `ZDNN_1D` (p) | `ZDNN_2D` (m, p) | | stacked | `ZDNN_3DS` (s, m, n) | `ZDNN_3DS` (s, n, p) | `ZDNN_2DS` (s, p) | `ZDNN_3DS` (s, m, p) | #### Parameters - `zdnn_ztensor *input_a` - Input tensor with the first matrix for multiplication - pre_transformed shape and layout must match [matmul tensor requirements](#matmul-io-table) - `zdnn_ztensor *input_b` - Input tensor with the second matrix for multiplication - pre_transformed shape and layout must match [matmul tensor requirements](#matmul-io-table) - `zdnn_ztensor *input_c` - Input tensor that will have the requested operation performed against the intermediate dot product of `input_a` and `input_b`. - pre_transformed shape and layout must match [matmul tensor requirements](#matmul-io-table) - `zdnn_matmul_ops op_type` - Operation to perform on dot product. - `MATMUL_OP_ADDITION` - `MATMUL_OP_GREATER` - `MATMUL_OP_GREATER_EQUAL` - `MATMUL_OP_EQUAL` - `MATMUL_OP_NOT_EQUAL` - `MATMUL_OP_LESSER_EQUAL` - `MATMUL_OP_LESSER` - `zdnn_ztensor *output` - The output tensor which will hold the result of the operation in its buffer. - pre_transformed shape and layout must match [matmul tensor requirements](#matmul-io-table) #### Programming Notes - Care must be exercised when comparing values for equality or inequality since the order of operations and rounding may produce, what appear to be, slightly different values when they are essentially the same value. #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) - `ZDNN_FUNC_RC_F000` - Invalid `op_type`. #### Framework Examples [TensorFlow MatMul] [tensorflow matmul]: https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/mat-mul [ONNX MatMul] [onnx matmul]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#MatMul --- ### zdnn_matmul_bcast_op [Back to Table of Contents](#TOC) #### Description Given three input zDNN tensors `input_a`, `input_b`, and `input_c`, determine the matrix multiplication of `input_a` \* `input_b`, then perform one of the following operations, using `input_c` against the dot product, storing the result into the specified `output` zDNN tensor: - Addition The outermost dimension for `input_a` can optionally indicate that the input is a stack of matrices. Each stack of `input_a` is then multiplied by the same `input_b` matrix and `input_c` which are broadcast over each stack of `input_a`. Results for each stack are returned in the corresponding stack index of `output`. #### Format ``` zdnn_status zdnn_matmul_bcast_op(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, zdnn_matmul_bcast_ops op_type, zdnn_ztensor *output); ``` #### Input / Output matmul broadcast tensor requirements <a id="matmul-bcast-io-table"></a> - See table in this section for `pre_transformed_desc` and shape requirements for each tensor. - Must follow [general tensor requirements](#gen-zten-reqs) | input_a | input_b | input_c | result | | -------------------- | ---------------- | ------------- | -------------------- | | `ZDNN_3DS` (s, m, n) | `ZDNN_2D` (n, p) | `ZDNN_1D` (p) | `ZDNN_3DS` (s, m, p) | #### Parameters - `zdnn_ztensor *input_a` - Input tensor with the first matrix for multiplication. - pre_transformed shape and layout must match [matmul broadcast tensor requirements](#matmul-bcast-io-table) - `zdnn_ztensor *input_b` - Input tensor with the second matrix for multiplication. - The same single `input_b` matrix is broadcast and used as the multiplier for each stack dimension of `input_a` - pre_transformed shape and layout must match [matmul broadcast tensor requirements](#matmul-bcast-io-table) - `zdnn_ztensor *input_c` - Input tensor that will have the requested operation performed against the intermediate dot product for each "m" dimension in `output`. - pre_transformed shape and layout must match [matmul broadcast tensor requirements](#matmul-bcast-io-table) - `zdnn_matmul_bcast_ops op_type` - Operation to perform on dot product. - `MATMUL_BCAST_OP_ADDITION` - `zdnn_ztensor *output` - The output tensor which will hold the result of the operation in its buffer. - pre_transformed shape and layout must match [matmul broadcast tensor requirements](#matmul-bcast-io-table) #### Programming Notes - `zdnn_matmul_bcast_ops` only supports `MATMUL_BCAST_OP_ADDITION` op_type, any other op_types will be ignored and may not operate compatibly in the future. #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - `ZDNN_INVALID_SHAPE` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow MatMul] [tensorflow matmul]: https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/mat-mul [ONNX MatMul] [onnx matmul]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#MatMul --- ### zdnn_lstm [Back to Table of Contents](#TOC) #### Description Implements Long-Short Term Memory layer (LSTM - Hochreiter 1997). The following formula is computed for the input tensor input(t) for all time steps: (Default: f=Sigmoid, g=Tanh, h=Tanh): ``` - it = f(Xt*(Wi^T) + Ht-1*(Ri^T) + Wbi + Rbi) - ft = f(Xt*(Wf^T) + Ht-1*(Rf^T) + Wbf + Rbf) - ct = g(Xt*(Wc^T) + Ht-1*(Rc^T) + Wbc + Rbc) - Ct = ft (.) Ct-1 + it (.) ct - ot = f(Xt*(Wo^T) + Ht-1*(Ro^T) + Wbo + Rbo) - Ht = ot (.) h(Ct) ``` #### Format ``` zdnn_status zdnn_lstm(const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *c0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, void *work_area, zdnn_ztensor *hn_output, zdnn_ztensor *cf_output); ``` Also see an [example](#example-of-an-application-calling-the-zdnn_lstm-api) in the usage example section. #### LSTM Input / Output requirements - `num_hidden` dimensions: <a id="lstm-hid_sz"></a> - Any num_hidden dimension must be less than or equal to 8192 elements. #### Parameters - `zdnn_ztensor *input` - Input must be a tensor with the shape (num_timesteps, num_batches, num_features) prior to transformation with the `zdnn_transform_ztensor` API. - Expects `pre_transformed_desc->layout` to be `ZDNN_3DS`. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *h0` - Tensor containing the initial hidden state with shape (num_dirs, num_batches, num_hidden) prior to transformation with the `zdnn_transform_ztensor` API. - Expects `pre_transformed_desc->layout` to be `ZDNN_3DS`. - Must follow [general tensor requirements](#gen-zten-reqs) - Must follow [num_hidden requirements](#lstm-hid_sz) - `zdnn_ztensor *c0` - Tensor containing the initial cell state with shape (num_dirs, num_batches, num_hidden) prior to transformation with the `zdnn_transform_ztensor` API. - Expects `pre_transformed_desc->layout` to be `ZDNN_3DS`. - Must follow [general tensor requirements](#gen-zten-reqs) - Must follow [num_hidden requirements](#lstm-hid_sz) - `zdnn_ztensor *weights` - Tensor containing the concatenated input connection weights in Forget, Input, Cell, Output (FICO) order. - Prior to transformation, each gate needs to be transposed to shape (num_dirs, num_features, num_hidden) by the caller. - Expects `pre_transformed_desc->layout` to be `ZDNN_3DS`. - Expects `zdnn_concat_info` having the following flags turned on: - `RNN_TYPE_LSTM` - `USAGE_WEIGHTS` - Appropriate `PREV_LAYER` flag: - `PREV_LAYER_NONE` if `input` tensor is not from a previous RNN layer - `PREV_LAYER_UNI` if `input` tensor is uni-directional output from a previous RNN layer - `PREV_LAYER_BIDIR` if `input` tensor is bi-directional output from a previous RNN layer - Must follow [concatenated tensor requirements](#concat-zten-reqs) - Must follow [num_hidden requirements](#lstm-hid_sz) - `zdnn_ztensor *biases` - Tensor containing the concatenated input connection bias in Forget, Input, Cell, Output (FICO) order. - Prior to transformation, expects each gate needs to be shape (num_dirs, num_hidden). - Expects `pre_transformed_desc->layout` to be `ZDNN_2DS`. - Expects `zdnn_concat_info` having the following flags turned on: - `RNN_TYPE_LSTM` - `USAGE_BIASES` - Appropriate `PREV_LAYER` flag: - `PREV_LAYER_NONE` if `input` tensor is not from a previous RNN layer - `PREV_LAYER_UNI` if `input` tensor is uni-directional output from a previous RNN layer - `PREV_LAYER_BIDIR` if `input` tensor is bi-directional output from a previous RNN layer - Must follow [concatenated tensor requirements](#concat-zten-reqs) - Must follow [num_hidden requirements](#lstm-hid_sz) - `zdnn_ztensor *hidden_weights` - Tensor containing the concatenated hidden connection weights in Forget, Input, Cell, Output (FICO) order. - Prior to transformation, each gate needs to be transposed to shape (num_dirs, num_hidden, num_hidden) by the caller. - Expects `pre_transformed_desc->layout` to be `ZDNN_3DS`. - Expects `zdnn_concat_info` having the following flags turned on: - `RNN_TYPE_LSTM` - `USAGE_HIDDEN_WEIGHTS` - Appropriate `PREV_LAYER` flag: - `PREV_LAYER_NONE` if `input` tensor is not from a previous RNN layer - `PREV_LAYER_UNI` if `input` tensor is uni-directional output from a previous RNN layer - `PREV_LAYER_BIDIR` if `input` tensor is bi-directional output from a previous RNN layer - Must follow [concatenated tensor requirements](#concat-zten-reqs) - Must follow [num_hidden requirements](#lstm-hid_sz) - `zdnn_ztensor *hidden_biases` - Tensor containing the concatenated hidden connection bias in Forget, Input, Cell, Output (FICO) order. - Prior to transformation, expects each gate needs to be shape (num_dirs, num_hidden). - Expects `pre_transformed_desc->layout` to be `ZDNN_2DS`. - Expects `zdnn_concat_info` having the following flags turned on: - `RNN_TYPE_LSTM` - `USAGE_HIDDEN_BIASES` - Appropriate `PREV_LAYER` flag: - `PREV_LAYER_NONE` if `input` tensor is not from a previous RNN layer - `PREV_LAYER_UNI` if `input` tensor is uni-directional output from a previous RNN layer - `PREV_LAYER_BIDIR` if `input` tensor is bi-directional output from a previous RNN layer - Must follow [concatenated tensor requirements](#concat-zten-reqs) - Must follow [num_hidden requirements](#lstm-hid_sz) - `lstm_gru_direction direction` - Direction indicator of `lstm_gru_direction direction` type. Valid values: - `FWD` (forward) - `BWD` (backward) - `BIDIR` (bi-directional). - For input and output shapes, the num_dirs dimension should be: - `1` for unidirectional calls such as FWD or BWD - `2` for bidirectional calls such that: - dimension 0 contains FWD values. - dimension 1 contains BWD values. - `void *work_area` - A preallocated memory address to use for temporary storage during internal operation processing. - If set to NULL, the operation will determine, allocate and free storage automatically. - Amount of required storage can be determined given the LSTM timestep, batch, and num_hidden values. - The sample code below creates a ztensor descriptor that is an equivalent size of the required `work_area`. To use this sample code yourself, replace the `num_timesteps`, `num_batches`, and `num_hidden` variables with your own values. ``` zdnn_tensor_desc desc; desc.dim4 = (4 * num_timesteps) + 6; desc.dim3 = 1; desc.dim2 = num_batches; desc.dim1 = num_hidden; uint64_t work_area_size = zdnn_getsize_ztensor(&desc); ``` - For bidirectional, twice the amount of contiguous storage is required. - The start of the buffer must be 4k aligned. - `zdnn_ztensor *hn_output` - Output results of the hidden states - Expects pre_transformed_desc->layout to be `ZDNN_4DS`. - Must follow [general tensor requirements](#gen-zten-reqs) - Must follow [num_hidden requirements](#lstm-hid_sz) - Output pre-transformed shapes: - all timesteps: (num_timesteps, num_dirs, num_batches, num_hidden) - final timestep only: (1, num_dirs, num_batches, num_hidden) - For bidirectional (`BIDIR`) output: - Forward and backward results are concatenated on the innermost dimension. - Can be used directly as input for subsequent RNN layers without needing untransformation. - Can not be used directly as input for other non-RNN zDNN ops. - Untransformation is supported. - Note that for `BWD` and the backward component of `BIDIR` directions, the output order matches the order of the input, not the processing order. For example, the first input timestep is the last to be processed and its result is the first timestep of the output. - `zdnn_ztensor *cf_output` - Output results of the cell state for the last processed timestep - Expects pre_transformed_desc->layout to be `ZDNN_4DS`. - Must follow [general tensor requirements](#gen-zten-reqs) - Must follow [num_hidden requirements](#lstm-hid_sz) - Output pre-transformed shapes: - (1, num_dirs, num_batches, num_hidden) - For bidirectional (`BIDIR`): - Forward and backward results are concatenated on the innermost dimension. - Can not be used directly as input for other non-RNN zDNN ops. - Untransformation is supported. #### Summary | | pre-transformed layout | pre-transformed shape | | -------------- | ---------------------- | --------------------------------------------------------------------------------------------------- | | input | `ZDNN_3DS` | (num_timesteps, num_batches, num_features) | | h0 | `ZDNN_3DS` | (num_dirs, num_batches, num_hidden) | | c0 | `ZDNN_3DS` | (num_dirs, num_batches, num_hidden) | | weights | `ZDNN_3DS` | (num_dirs, num_features, num_hidden) | | bias | `ZDNN_2DS` | (num_dirs, num_hidden) | | hidden_weights | `ZDNN_3DS` | (num_dirs, num_hidden, num_hidden) | | hidden_biases | `ZDNN_2DS` | (num_dirs, num_hidden) | | hn_output | `ZDNN_4DS` | (num_timesteps, num_dirs, num_batches, num_hidden)<br>(last timestep only when `num_timesteps` = 1) | | cf_output | `ZDNN_4DS` | (1, num_dirs, num_batches, num_hidden) | | | create transformed descriptor via | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | input | `zdnn_generate_transformed_desc` | | h0 | `zdnn_generate_transformed_desc` | | c0 | `zdnn_generate_transformed_desc` | | weights | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_WEIGHTS` + one of the following:<br>`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` | | bias | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_BIASES` + one of the following:<br>`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` | | hidden_weights | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_HIDDEN_WEIGHTS` + one of the following:<br>`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` | | hidden_biases | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_HIDDEN_BIASES` + one of the following:<br>`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` | | hn_output | `zdnn_generate_transformed_desc` | | cf_output | `zdnn_generate_transformed_desc` | #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - `ZDNN_INVALID_SHAPE` - (if any of the following are not true) - `hn_output` timesteps dimension must be 1 or the same size as `input` timestep dimension. - All tensors with a direction dimension have the same direction dimension size. - `input` timestep dimension must be greater than or equal to 1. - Other general shape violations (exceeds MDIS, etc.) - `ZDNN_INVALID_DIRECTION` - `direction` parameter was not a recognized `lstm_gru_direction`. - `ZDNN_ALLOCATION_FAILURE` - A preallocated `work_area` was not specified and internal allocation for the required memory failed. - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow LSTM] [tensorflow lstm]: https://www.tensorflow.org/api_docs/python/tf/keras/layers/LSTMCell [ONNX LSTM] [onnx lstm]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#LSTM --- ### zdnn_gru [Back to Table of Contents](#TOC) #### Description Implements Gated Recurrent Unit (Kyunghyun Cho 2014). Supports only reset after linear. The following formula is computed for the input tensor input(t) for all time steps: ``` (Default: f=Sigmoid, g=Tanh): - zt = f(Xt*(Wz^T) + Ht-1*(Rz^T) + Wbz + Rbz) - rt = f(Xt*(Wr^T) + Ht-1*(Rr^T) + Wbr + Rbr) - ht = g(Xt*(Wh^T) + (rt (.) (Ht-1*(Rh^T) + Rbh)) + Wbh) - Ht = (1 - zt) (.) ht + zt (.) Ht-1 ``` #### Format ``` zdnn_status zdnn_gru(const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, void *work_area, zdnn_ztensor *hn_output); ``` Also see an [example](#example-of-an-application-calling-the-zdnn_gru-api) in the usage example section. #### GRU Input / Output requirements - `num_hidden` dimensions: <a id="gru-hid_sz"></a> - Any num_hidden dimension must be less than or equal to 10880 elements. #### Parameters - `zdnn_ztensor *input` - Input must be a tensor with the shape (num_timesteps, num_batches, num_features) prior to transformation with the `zdnn_transform_ztensor` API. - Expects `pre_transformed_desc->layout` to be `ZDNN_3DS`. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *h0` - Tensor containing the initial hidden state with shape (num_dirs, num_batches, num_hidden) prior to transformation with the `zdnn_transform_ztensor` API. - Expects `pre_transformed_desc->layout` to be `ZDNN_3DS`. - Must follow [general tensor requirements](#gen-zten-reqs) - Must follow [num_hidden requirements](#gru-hid_sz) - `zdnn_ztensor *weights` - Tensor containing the concatenated input connection weights in (Z)update, Reset, Hidden, (ZRH) order. - Prior to transformation, each gate needs to be transposed to shape (num_dirs, num_features, num_hidden) by the caller. - Expects `pre_transformed_desc->layout` to be `ZDNN_3DS`. - Expects `zdnn_concat_info` having the following flags turned on: - `RNN_TYPE_GRU` - `USAGE_WEIGHTS` - Appropriate `PREV_LAYER` flag: - `PREV_LAYER_NONE` if `input` tensor is not from a previous RNN layer - `PREV_LAYER_UNI` if `input` tensor is uni-directional output from a previous RNN layer - `PREV_LAYER_BIDIR` if `input` tensor is bi-directional output from a previous RNN layer - Must follow [concatenated tensor requirements](#concat-zten-reqs) - Must follow [num_hidden requirements](#gru-hid_sz) - `zdnn_ztensor *biases` - Tensor containing the concatenated input connection bias in (Z)update, Reset, Hidden, (ZRH) order. - Prior to transformation, expects each gate needs to be shape (num_dirs, num_hidden). - Expects `pre_transformed_desc->layout` to be `ZDNN_2DS`. - Expects `zdnn_concat_info` having the following flags turned on: - `RNN_TYPE_GRU` - `USAGE_BIASES` - Appropriate `PREV_LAYER` flag: - `PREV_LAYER_NONE` if `input` tensor is not from a previous RNN layer - `PREV_LAYER_UNI` if `input` tensor is uni-directional output from a previous RNN layer - `PREV_LAYER_BIDIR` if `input` tensor is bi-directional output from a previous RNN layer - Must follow [concatenated tensor requirements](#concat-zten-reqs) - Must follow [num_hidden requirements](#gru-hid_sz) - `zdnn_ztensor *hidden_weights` - Tensor containing the concatenated hidden connection weights in (Z)update, Reset, Hidden, (ZRH) order. - Prior to transformation, each gate needs to be transposed to shape (num_dirs, num_hidden, num_hidden) by the caller. - Expects `pre_transformed_desc->layout` to be `ZDNN_3DS`. - Expects `zdnn_concat_info` having the following flags turned on: - `RNN_TYPE_GRU` - `USAGE_HIDDEN_WEIGHTS` - Appropriate `PREV_LAYER` flag: - `PREV_LAYER_NONE` if `input` tensor is not from a previous RNN layer - `PREV_LAYER_UNI` if `input` tensor is uni-directional output from a previous RNN layer - `PREV_LAYER_BIDIR` if `input` tensor is bi-directional output from a previous RNN layer - Must follow [concatenated tensor requirements](#concat-zten-reqs) - Must follow [num_hidden requirements](#gru-hid_sz) - `zdnn_ztensor *hidden_biases` - Tensor containing the concatenated hidden connection bias in (Z)update, Reset, Hidden, (ZRH) order. - Prior to transformation, expects each gate needs to be shape (num_dirs, num_hidden). - Expects `pre_transformed_desc->layout` to be `ZDNN_2DS`. - Expects `zdnn_concat_info` having the following flags turned on: - `RNN_TYPE_GRU` - `USAGE_HIDDEN_BIASES` - Appropriate `PREV_LAYER` flag: - `PREV_LAYER_NONE` if `input` tensor is not from a previous RNN layer - `PREV_LAYER_UNI` if `input` tensor is uni-directional output from a previous RNN layer - `PREV_LAYER_BIDIR` if `input` tensor is bi-directional output from a previous RNN layer - Must follow [concatenated tensor requirements](#concat-zten-reqs) - Must follow [num_hidden requirements](#gru-hid_sz) - `lstm_gru_direction direction` - Direction indicator of `lstm_gru_direction direction` type. Valid values: - `FWD` (forward) - `BWD` (backward) - `BIDIR` (bi-directional). - For input shapes, the num_dirs dimension should be: - `1` for unidirectional calls such as FWD or BWD - `2` for bidirectional calls such that: - dimension 0 contains FWD values. - dimension 1 contains BWD values. - `void *work_area` - A preallocated memory address to use for temporary storage during internal operation processing. - If set to NULL, the operation will determine, allocate and free storage automatically. - Amount of required storage can be determined given the GRU timestep, batch, and num_hidden values. - The sample code below creates a ztensor descriptor that is an equivalent size of the required `work_area`. To use this sample code yourself, replace the `num_timesteps`, `num_batches`, and `num_hidden` variables with your own values. ``` zdnn_tensor_desc desc; desc.dim4 = (3 * num_timesteps) + 5; desc.dim3 = 1; desc.dim2 = num_batches; desc.dim1 = num_hidden; uint64_t work_area_size = zdnn_getsize_ztensor(&desc); ``` - For bidirectional, twice the amount of contiguous storage is required. - The start of the buffer must be 4k aligned. - `zdnn_ztensor *hn_output` - Output results of the hidden states - Expects pre_transformed_desc->layout to be `ZDNN_4DS`. - Must follow [general tensor requirements](#gen-zten-reqs) - Must follow [num_hidden requirements](#lstm-hid_sz) - Output pre-transformed shapes: - all timesteps: (num_timesteps, num_dirs, num_batches, num_hidden) - final timestep only: (1, num_dirs, num_batches, num_hidden) - For bidirectional (`BIDIR`) output: - Forward and backward results are concatenated on the innermost dimension. - Can be used directly as input for subsequent RNN layers without needing untransformation. - Can not be used directly as input for other non-RNN zDNN ops. - Untransformation is supported. - Note that for `BWD` and the backward component of `BIDIR` directions, the output order matches the order of the input, not the processing order. For example, the first input timestep is the last to be processed and its result is the first timestep of the output. #### Summary | | pre-transformed layout | pre-transformed shape | | -------------- | ---------------------- | --------------------------------------------------------------------------------------------------- | | input | `ZDNN_3DS` | (num_timesteps, num_batches, num_features) | | h0 | `ZDNN_3DS` | (num_dirs, num_batches, num_hidden) | | c0 | `ZDNN_3DS` | (num_dirs, num_batches, num_hidden) | | weights | `ZDNN_3DS` | (num_dirs, num_features, num_hidden) | | bias | `ZDNN_2DS` | (num_dirs, num_hidden) | | hidden_weights | `ZDNN_3DS` | (num_dirs, num_hidden, num_hidden) | | hidden_biases | `ZDNN_2DS` | (num_dirs, num_hidden) | | hn_output | `ZDNN_4DS` | (num_timesteps, num_dirs, num_batches, num_hidden)<br>(last timestep only when `num_timesteps` = 1) | | | create transformed descriptor via | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | input | `zdnn_generate_transformed_desc` | | h0 | `zdnn_generate_transformed_desc` | | c0 | `zdnn_generate_transformed_desc` | | weights | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_WEIGHTS` + one of the following:<br>`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` | | bias | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_BIASES` + one of the following:<br>`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` | | hidden_weights | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_HIDDEN_WEIGHTS` + one of the following:<br>`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` | | hidden_biases | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_HIDDEN_BIASES` + one of the following:<br>`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` | | hn_output | `zdnn_generate_transformed_desc` | #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - `ZDNN_INVALID_SHAPE` - (if any of the following are not true) - `hn_output` timesteps dimension must be 1 or the same size as `input` timestep dimension. - All tensors with a direction dimension have the same direction dimension size. - `input` timestep dimension must be greater than or equal to 1. - Other general shape violations (exceeds MDIS, etc.) - `ZDNN_INVALID_DIRECTION` - `direction` parameter was not a recognized `lstm_gru_direction`. - `ZDNN_ALLOCATION_FAILURE` - A preallocated `work_area` was not specified and internal allocation for the required memory failed. - [hardware statuses](#hw-statuses) #### Framework Examples [TensorFlow GRU] [tensorflow gru]: https://www.tensorflow.org/api_docs/python/tf/keras/layers/GRUCell [ONNX GRU] [onnx gru]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#GRU --- ### zdnn_avgpool2d [Back to Table of Contents](#TOC) #### Description Given an input tensor in zDNN transformed format, padding type, kernel size and kernel stride, produces a downsampled tensor reducing the middle dimensions based on the mean values within the kernel window at each step and stores the results into the provided output zDNN tensor. #### Format ``` zdnn_status zdnn_avgpool2d(const zdnn_ztensor *input, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - Tensor with original values to be downsampled in the output tensor. - Must be a [ZDNN_NHWC](#common-layouts) tensor with pre_transformed shape [batch_Num, Height, Width, Channel]. - See [Parameter Restrictions](#avgpool2d-parm-restrictions) below for information on the expected shape of the input tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `padding_type` - The type of padding to use for the pooling operations. - Valid values: are `SAME_PADDING` or `VALID_PADDING`. - See [Parameter Restrictions](#avgpool2d-parm-restrictions) below for information on the expected value of padding_type. - For information on "same" vs "valid" padding see: <https://www.pico.net/kb/what-is-the-difference-between-same-and-valid-padding-in-tf-nn-max-pool-of-tensorflow>. - `kernel_height` - Size of the kernel window that passes over the input's height dimension. - See [Parameter Restrictions](#avgpool2d-parm-restrictions) below for information on the expected value of kerneL_height. - `kernel_width` - Size of the kernel window that passes over the input's width dimension. - See [Parameter Restrictions](#avgpool2d-parm-restrictions) below for information on the expected value of kerneL_width. - `stride_height` - Number of positions the kernel moves over input's height dimension at each step. - If `stride_height` is 0 then `stride_width` must also be 0. - If strides are greater than 0 then `stride_height` must be less than or equal to 30. - `stride_width` - Number of positions the kernel moves over the input's width dimension at each step. - If `stride_height` is 0 then `stride_width` must also be 0. - If strides are greater than 0 then `stride_width` must be less than or equal to 30. - `zdnn_ztensor *output` - The result tensor which will hold the result of the pooling operation its buffer. - Must be a [ZDNN_NHWC](#common-layouts) tensor with pre_transformed shape [batch_Num, Height, Width, Channel]. - See [Parameter Restrictions](#avgpool2d-parm-restrictions) below for information on the expected shape of the output tensor. - Must follow [general tensor requirements](#gen-zten-reqs) #### AvgPool2D Parameter Restrictions <a id="avgpool2d-parm-restrictions"></a> Parameter restrictions may vary based on provided strides and padding_type. - Input tensor batch_Num and Channel dimensions must always match the output tensor's respective dimensions. - If strides are 0: - Both input tensor's Height dimension and the kernel_height must match and be less than or equal to 1024. - Both input tensor's Width dimension and the kernel_width must match and be less than or equal to 1024. - Output tensor's height and width dimensions must be 1. - padding_type must be `VALID_PADDING`. - If strides are greater than zero: - kernel_width and kernel_height must be less than or equal to 64. - input tensor's height or weight dimension must not be greater than 1024. - If padding_type is `SAME_PADDING`: - Output tensor's height dimension must equal `ceil((float)input's height / stride_height)`. - Output tensor's width dimension must equal `ceil((float)input's width / stride_width)`. - If padding_type is `VALID_PADDING`: - Output tensor's height dimension must equal `ceil((float)(input's height - kernel_height + 1) / stride_height)`. - Output tensor's width dimension must equal `ceil((float)(input's width - kernel_width + 1) / stride_width)`. #### Programming Notes - If the magnitude of difference between elements of `input` is large (greater than 10), accuracy may be reduced. #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - `ZDNN_INVALID_SHAPE` - Shape of input or output tensor is invalid based on given kernel and stride parameters - Other general shape violations (exceeds MDIS, etc.) - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - `ZDNN_INVALID_STRIDE_PADDING` - `ZDNN_INVALID_STRIDES` - One stride was non-zero, but not the other. - [hardware statuses](#hw-statuses) - `ZDNN_EXCEEDS_MDIS` will also occur if any of the following conditions occur: - stride_height is larger than `zdnn_get_nnpa_max_dim_idx_size`. - stride_width is larger than `zdnn_get_nnpa_max_dim_idx_size`. - kernel_height is 0 or is larger than `zdnn_get_nnpa_max_dim_idx_size`. - kernel_width is 0 or is larger than `zdnn_get_nnpa_max_dim_idx_size`. - `ZDNN_FUNC_RC_F000` - Invalid `padding_type` - `ZDNN_FUNC_RC_F001` - `stride_height` = 0 and `stride_width` = 0, but a kernel parameter is greater than allowed (see `kernel_height` or `kernel_width` above) - `ZDNN_FUNC_RC_F002` - `stride_height` > 0 and `stride_width` > 0, but a kernel parameter is greater than allowed (see `kernel_height` or `kernel_width` above) - `ZDNN_FUNC_RC_F003` - `stride_height` > 0 and `stride_width` > 0, but a stride parameter is greater than allowed (see `stride_height` or `stride_width` above) - `ZDNN_FUNC_RC_F004` - `stride_height` > 0 and `stride_width` > 0, but either input tensor's height or weight dimension is greater than 1024. #### Framework Examples [TensorFlow AvgPool] [tensorflow avgpool]: https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/avg-pool [ONNX AvgPool] [onnx avgpool]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#AveragePool --- ### zdnn_maxpool2d [Back to Table of Contents](#TOC) #### Description Given an input tensor in zDNN transformed format, padding type, kernel size and kernel stride, produces a downsampled tensor reducing the middle dimensions based on the maximum values within the kernel window at each step and stores the results into the provided output zDNN tensor. #### Format ``` zdnn_status zdnn_maxpool2d(const zdnn_ztensor *input, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - Tensor with original values to be downsampled in the output tensor. - Must be a [ZDNN_NHWC](#common-layouts) tensor with pre_transformed shape [batch_Num, Height, Width, Channel]. - See [Parameter Restrictions](#maxpool2d-parm-restrictions) below for information on the expected shape of the input tensor. - Must follow [general tensor requirements](#gen-zten-reqs) - `padding_type` - The type of padding to use for the pooling operations. - Valid values: are `SAME_PADDING` or `VALID_PADDING`. - See [Parameter Restrictions](#maxpool2d-parm-restrictions) below for information on the expected value of padding_type. - For information on "same" vs "valid" padding see: <https://www.pico.net/kb/what-is-the-difference-between-same-and-valid-padding-in-tf-nn-max-pool-of-tensorflow>. - `kernel_height` - Size of the kernel window that passes over the input's height dimension. - See [Parameter Restrictions](#maxpool2d-parm-restrictions) below for information on the expected value of kerneL_height. - `kernel_width` - Size of the kernel window that passes over the input's width dimension. - See [Parameter Restrictions](#maxpool2d-parm-restrictions) below for information on the expected value of kerneL_width. - `stride_height` - Number of positions the kernel moves over input's height dimension at each step. - If `stride_height` is 0 then `stride_width` must also be 0. - If strides are greater than 0 then `stride_height` must be less than or equal to 30. - `stride_width` - Number of positions the kernel moves over the input's width dimension at each step. - If `stride_height` is 0 then `stride_width` must also be 0. - If strides are greater than 0 then `stride_width` must be less than or equal to 30. - `zdnn_ztensor *output` - The result tensor which will hold the result of the pooling operation its buffer. - Must be a [ZDNN_NHWC](#common-layouts) tensor with pre_transformed shape [batch_Num, Height, Width, Channel]. - See [Parameter Restrictions](#maxpool2d-parm-restrictions) below for information on the expected shape of the output tensor. - Must follow [general tensor requirements](#gen-zten-reqs) #### MaxPool2D Parameter Restrictions <a id="maxpool2d-parm-restrictions"></a> Parameter restrictions may vary based on provided strides and padding_type. - Input tensor batch_Num and Channel dimensions must always match the output tensor's respective dimensions. - If strides are 0: - Both input tensor's Height dimension and the kernel_height must match and be less than or equal to 1024. - Both input tensor's Width dimension and the kernel_width must match and be less than or equal to 1024. - Output tensor's height and width dimensions must be 1. - padding_type must be `VALID_PADDING`. - If strides are greater than zero: - kernel_width and kernel_height must be less than or equal to 64. - input tensor's height or weight dimension must not be greater than 1024. - If padding_type is `SAME_PADDING`: - Output tensor's height dimension must equal `ceil((float)input's height / stride_height)`. - Output tensor's width dimension must equal `ceil((float)input's width / stride_width)`. - If padding_type is `VALID_PADDING`: - Output tensor's height dimension must equal `ceil((float)(input's height - kernel_height + 1) / stride_height)`. - Output tensor's width dimension must equal `ceil((float)(input's width - kernel_width + 1) / stride_width)`. #### Programming Notes - If the magnitude of difference between elements of `input` is large (greater than 10), accuracy may be reduced. #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - `ZDNN_INVALID_SHAPE` - Shape of input or output tensor is invalid based on given kernel and stride parameters - Other general shape violations (exceeds MDIS, etc.) - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - `ZDNN_INVALID_STRIDE_PADDING` - `ZDNN_INVALID_STRIDES` - One stride was non-zero, but not the other. - [hardware statuses](#hw-statuses) - `ZDNN_EXCEEDS_MDIS` will also occur if any of the following conditions occur: - stride_height is larger than `zdnn_get_nnpa_max_dim_idx_size`. - stride_width is larger than `zdnn_get_nnpa_max_dim_idx_size`. - kernel_height is 0 or is larger than `zdnn_get_nnpa_max_dim_idx_size`. - kernel_width is 0 or is larger than `zdnn_get_nnpa_max_dim_idx_size`. - `ZDNN_FUNC_RC_F000` - Invalid `padding_type` - `ZDNN_FUNC_RC_F001` - `stride_height` = 0 and `stride_width` = 0, but a kernel parameter is greater than allowed (see `kernel_height` or `kernel_width` above) - `ZDNN_FUNC_RC_F002` - `stride_height` > 0 and `stride_width` > 0, but a kernel parameter is greater than allowed (see `kernel_height` or `kernel_width` above) - `ZDNN_FUNC_RC_F003` - `stride_height` > 0 and `stride_width` > 0, but a stride parameter is greater than allowed (see `stride_height` or `stride_width` above) - `ZDNN_FUNC_RC_F004` - `stride_height` > 0 and `stride_width` > 0, but either input tensor's height or weight dimension is greater than 1024. #### Framework Examples [TensorFlow MaxPool] [tensorflow maxpool]: https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/max-pool [ONNX MaxPool] [onnx maxpool]: https://github.com/onnx/onnx/blob/master/docs/Operators.md#MaxPool --- ### zdnn_conv2d [Back to Table of Contents](#TOC) #### Description Perform 2D convolution over an input tensor in zDNN transformed format. First the `input` tensor is convolved with the `kernel` tensor. Then the `bias` tensor is added to the results. Then if `act_func` is not `CONV2D_ACT_NONE`, the activation function is applied to the results. Then if `act_func` is set to `CONV2D_ACT_RELU`, and clipping_value is not `NULL` or `0`, clipping is performed against the intermediate result where z = min(intermediate_result, clipping_value). Finally the results are stored into the provided output zDNN tensor. #### Format ``` zdnn_status zdnn_conv2d(const zdnn_ztensor *input, const zdnn_ztensor *kernel, const zdnn_ztensor *bias, zdnn_pool_padding padding_type, uint32_t stride_height, uint32_t stride_width, zdnn_conv2d_act act_func, const void *clipping_value, zdnn_ztensor *output); ``` #### Parameters - `zdnn_ztensor *input` - Tensor with original values to be downsampled in the output tensor. - Must be a [ZDNN_NHWC](#common-layouts) tensor with pre_transformed shape [num_batches, height_in, width_in, channels_in]. - See [Convolution 2D Requirements](#convolution-2d-requirements) for requirements. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *kernel` - The kernel tensor to convolute with the input tensor. - Must be a [ZDNN_HWCK](#common-layouts) tensor with pre_transformed shape [kernel_height, kernel_width, channels_in, channels_out]. - See [Convolution 2D Requirements](#convolution-2d-requirements) for requirements. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_ztensor *bias` - The bias tensor to add to the convoluted results. - Must be a [ZDNN_1D](#common-layouts) tensor with pre_transformed shape [channels_out]. - See [Convolution 2D Requirements](#convolution-2d-requirements) for requirements. - Must follow [general tensor requirements](#gen-zten-reqs) - `zdnn_pool_padding padding_type` - The type of padding to use for the pooling operations. - Valid values: are `SAME_PADDING` or `VALID_PADDING`. - For information on "same" vs "valid" padding see: <https://www.pico.net/kb/what-is-the-difference-between-same-and-valid-padding-in-tf-nn-max-pool-of-tensorflow>. - `uint32_t stride_height` - Number of positions the kernel moves over the input's `dim3` dimension at each step. - See [Convolution 2D Requirements](#convolution-2d-requirements) for requirements. - `uint32_t stride_width` - Number of positions the kernel moves over the input's `dim2` dimension at each step. - See [Convolution 2D Requirements](#convolution-2d-requirements) for requirements. - `zdnn_conv2d_act act_func` - Activation function to apply to the results. - `CONV2D_ACT_NONE` or `CONV2D_ACT_RELU` - `void *clipping_value` - A pointer to an FP32 value, used to clip input tensor's elements. - If set to NULL or 0, no clipping will occur. - Must not be a negative value. - Value is ignored if `act_func` is not set to `CONV2D_ACT_RELU`. - `zdnn_ztensor *output` - The result tensor which will hold the results. - Must be a [ZDNN_NHWC](#common-layouts) tensor with pre_transformed shape [num_batches, height_out, width_out, channels_out]. - See [Convolution 2D Requirements](#convolution-2d-requirements) for requirements. - Must follow [general tensor requirements](#gen-zten-reqs) #### Convolution 2D Requirements | strides and padding | input (num_batches, height_in, width_in, channels_in) | kernel (kernel_height, kernel_width, channels_in, channels_out) | bias (channels_out) | output (num_batches, height_out, width_out, channels_out) | | ----------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | both strides > 0 and =< 13, SAME padding | | both kernel_height and kernel_width must be =< 64 | | height_out = ceil(height_in/stride_height)<br>width_out = ceil(width_in/stride_width) | | both strides > 0 and =< 13, VALID padding | height_in must be >= kernel_height<br>width_in must be >= kernel_width | both kernel_height and kernel_width must be =< 64 | | height_out = ceil((height_in - kernel_height + 1)/stride_height)<br>width_out = ceil((width_in - kernel_width + 1)/stride_width) | | both strides = 0, VALID padding | height_in must be = kernel_height<br>width_in must be = kernel_width | both kernel_height and kernel_width must be =< 448 | | both height_out and width_out must be 1 | #### Returns (see [zDNN Statuses](#common-statuses) for descriptions) - `ZDNN_OK` - [warning statuses](#warning-statuses) - `ZDNN_INVALID_SHAPE` - Shape of input or output tensor is invalid based on given kernel and stride parameters - Other general shape violations (exceeds MDIS, etc.) - `ZDNN_INVALID_TYPE` - `ZDNN_INVALID_FORMAT` - `ZDNN_INVALID_STRIDE_PADDING` - `ZDNN_INVALID_STRIDES` - `ZDNN_INVALID_CLIPPING_VALUE` - [hardware statuses](#hw-statuses) - `ZDNN_FUNC_RC_F000` - Invalid `padding_type` - `ZDNN_FUNC_RC_F001` - Invalid `act_func` - `ZDNN_FUNC_RC_F002` - `stride_height` = 0 and `stride_width` = 0, but either `kernel_height` or `kernel_width` > 448 - `ZDNN_FUNC_RC_F003` - `stride_height` > 0 and `stride_width` > 0, but either `kernel_height` or `kernel_width` > 64 - `ZDNN_FUNC_RC_F004` - Either `stride_height` or `stride_width` > 13 #### Framework Examples [TensorFlow Conv2D] [tensorflow conv2d]: https://www.tensorflow.org/api_docs/python/tf/keras/layers/Conv2D [ONNX Conv2D] [onnx conv2d]: https://github.com/onnx/onnx/blob/master/docs/Operators.md ## Convenience Functions [Back to Table of Contents](#TOC) - None --- ## Usage Examples ### Example flow of an application calling the zDNN APIs [Back to Table of Contents](#TOC) ``` #include <assert.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // *************************************************************************** // Sample: // // Create 2 zTensors a and b, and add them together via zdnn_add() // *************************************************************************** int main(int argc, char *argv[]) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor_a; zdnn_ztensor ztensor_b; zdnn_ztensor ztensor_out; zdnn_status status; uint32_t dim_n = 1, dim_h = 32, dim_w = 32, dim_c = 3; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes uint64_t num_elements = dim_n * dim_h * dim_w * dim_c; // allocate tensor data storage void *data1 = malloc(num_elements * element_size); void *data2 = malloc(num_elements * element_size); void *data_out = malloc(num_elements * element_size); // read input_data // check status for AIU availability, supported ops, etc. here // status = zdnn_query(…); // set input tensor data to 0 to 127 sequentially and repeat for (uint64_t i = 0; i < num_elements; i++) { ((float *)data1)[i] = (float)(i & 0x7f); ((float *)data2)[i] = (float)(i & 0x7f); } zdnn_init_pre_transformed_desc(ZDNN_NHWC, type, &pre_tfrmd_desc, dim_n, dim_h, dim_w, dim_c); // generate transformed shape information status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); assert(status == ZDNN_OK); // initialize zTensors and allocate 4k-aligned storage via helper function status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor_a); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor_b); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor_out); assert(status == ZDNN_OK); // transform the feature tensor status = zdnn_transform_ztensor(&ztensor_a, data1); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&ztensor_b, data2); assert(status == ZDNN_OK); // perform element-wise add between the two input tensors status = zdnn_add(&ztensor_a, &ztensor_b, &ztensor_out); assert(status == ZDNN_OK); // transform resultant zTensor back to original data format status = zdnn_transform_origtensor(&ztensor_out, data_out); assert(status == ZDNN_OK); for (uint64_t i = 0; i < num_elements; i++) { printf("out element %" PRIu64 " %f\n", i, ((float *)data_out)[i]); } // Free zTensors status = zdnn_free_ztensor_buffer(&ztensor_a); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&ztensor_b); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&ztensor_out); assert(status == ZDNN_OK); free(data1); free(data2); free(data_out); } ``` --- ### Example of an application calling the zdnn_lstm API (forward) [Back to Table of Contents](#TOC) ``` // SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // Sample: LSTM int main(int argc, char *argv[]) { zdnn_status status; #ifdef STATIC_LIB zdnn_init(); #endif /*********************************************************************** * * LSTM (FWD/BWD): * * INPUTS -------------------------------------------------------------- * input | ZDNN_3DS | (num_timesteps, num_batches, num_features) * h0 | ZDNN_3DS | (1, num_batches, num_hidden) * c0 | ZDNN_3DS | (1, num_batches, num_hidden) * weights | ZDNN_3DS | (1, num_features, num_hidden) * biases | ZDNN_2DS | (1, num_hidden) * hidden_weights | ZDNN_3DS | (1, num_hidden, num_hidden) * hidden_biases | ZDNN_2DS | (1, num_hidden) * * OUTPUTS ------------------------------------------------------------- * hn_output | ZDNN_4DS | (num_timesteps, 1, num_batches, num_hidden) * | | or (1, 1, num_batches, num_hidden) * cf_output | ZDNN_4DS | (1, 1, num_batches, num_hidden) ***********************************************************************/ /*********************************************************************** * Create input zTensor ***********************************************************************/ zdnn_tensor_desc input_pre_tfrmd_desc, input_tfrmd_desc; zdnn_ztensor input; uint32_t num_timesteps = 5; uint32_t num_batches = 3; uint32_t num_features = 32; uint32_t num_hidden = 5; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes lstm_gru_direction dir = FWD; uint8_t num_dirs = 1; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &input_pre_tfrmd_desc, num_timesteps, num_batches, num_features); status = zdnn_generate_transformed_desc(&input_pre_tfrmd_desc, &input_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&input_pre_tfrmd_desc, &input_tfrmd_desc, &input); assert(status == ZDNN_OK); uint64_t input_data_size = num_timesteps * num_batches * num_features * element_size; void *input_data = malloc(input_data_size); status = zdnn_transform_ztensor(&input, input_data); assert(status == ZDNN_OK); /*********************************************************************** * Create initial hidden and cell state zTensors ***********************************************************************/ zdnn_tensor_desc h0c0_pre_tfrmd_desc, h0c0_tfrmd_desc; zdnn_ztensor h0, c0; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &h0c0_pre_tfrmd_desc, num_dirs, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &h0); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &c0); assert(status == ZDNN_OK); uint64_t h0c0_data_size = num_batches * num_hidden * element_size; void *hidden_state_data = malloc(h0c0_data_size); void *cell_state_data = malloc(h0c0_data_size); status = zdnn_transform_ztensor(&h0, hidden_state_data); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&c0, cell_state_data); assert(status == ZDNN_OK); /*********************************************************************** * Create input weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc weights_pre_tfrmd_desc, weights_tfrmd_desc; zdnn_ztensor weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &weights_pre_tfrmd_desc, num_dirs, num_features, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_NONE, &weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&weights_pre_tfrmd_desc, &weights_tfrmd_desc, &weights); assert(status == ZDNN_OK); uint64_t weights_data_size = num_features * num_hidden * element_size; void *weights_data_f = malloc(weights_data_size); void *weights_data_i = malloc(weights_data_size); void *weights_data_c = malloc(weights_data_size); void *weights_data_o = malloc(weights_data_size); status = zdnn_transform_ztensor(&weights, weights_data_f, weights_data_i, weights_data_c, weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc biases_pre_tfrmd_desc, biases_tfrmd_desc; zdnn_ztensor biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_BIASES | PREV_LAYER_NONE, &biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&biases_pre_tfrmd_desc, &biases_tfrmd_desc, &biases); assert(status == ZDNN_OK); uint64_t biases_data_size = num_hidden * element_size; void *biases_data_f = malloc(biases_data_size); void *biases_data_i = malloc(biases_data_size); void *biases_data_c = malloc(biases_data_size); void *biases_data_o = malloc(biases_data_size); status = zdnn_transform_ztensor(&biases, biases_data_f, biases_data_i, biases_data_c, biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc hidden_weights_pre_tfrmd_desc, hidden_weights_tfrmd_desc; zdnn_ztensor hidden_weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &hidden_weights_pre_tfrmd_desc, num_dirs, num_hidden, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_WEIGHTS | PREV_LAYER_NONE, &hidden_weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hidden_weights_pre_tfrmd_desc, &hidden_weights_tfrmd_desc, &hidden_weights); assert(status == ZDNN_OK); uint64_t hidden_weights_data_size = num_hidden * num_hidden * element_size; void *hidden_weights_data_f = malloc(hidden_weights_data_size); void *hidden_weights_data_i = malloc(hidden_weights_data_size); void *hidden_weights_data_c = malloc(hidden_weights_data_size); void *hidden_weights_data_o = malloc(hidden_weights_data_size); status = zdnn_transform_ztensor(&hidden_weights, hidden_weights_data_f, hidden_weights_data_i, hidden_weights_data_c, hidden_weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc hidden_biases_pre_tfrmd_desc, hidden_biases_tfrmd_desc; zdnn_ztensor hidden_biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &hidden_biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_BIASES | PREV_LAYER_NONE, &hidden_biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc( &hidden_biases_pre_tfrmd_desc, &hidden_biases_tfrmd_desc, &hidden_biases); assert(status == ZDNN_OK); uint64_t hidden_biases_data_size = num_hidden * element_size; void *hidden_biases_data_f = malloc(hidden_biases_data_size); void *hidden_biases_data_i = malloc(hidden_biases_data_size); void *hidden_biases_data_c = malloc(hidden_biases_data_size); void *hidden_biases_data_o = malloc(hidden_biases_data_size); status = zdnn_transform_ztensor(&hidden_biases, hidden_biases_data_f, hidden_biases_data_i, hidden_biases_data_c, hidden_biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create output zTensor ***********************************************************************/ // get only the last timestep, thus hn and cf can share descriptor zdnn_tensor_desc hncf_pre_tfrmd_desc, hncf_tfrmd_desc; zdnn_ztensor hn_output_ztensor, cf_output_ztensor; zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &hncf_pre_tfrmd_desc, 1, 1, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&hncf_pre_tfrmd_desc, &hncf_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hncf_pre_tfrmd_desc, &hncf_tfrmd_desc, &hn_output_ztensor); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hncf_pre_tfrmd_desc, &hncf_tfrmd_desc, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Call the AIU ***********************************************************************/ void *work_area = NULL; status = zdnn_lstm(&input, &h0, &c0, &weights, &biases, &hidden_weights, &hidden_biases, dir, work_area, &hn_output_ztensor, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Output and Cleanup ***********************************************************************/ uint64_t hncf_data_size = num_batches * num_hidden * element_size; void *hn_output_data = malloc(hncf_data_size); void *cf_output_data = malloc(hncf_data_size); status = zdnn_transform_origtensor(&hn_output_ztensor, hn_output_data); assert(status == ZDNN_OK); status = zdnn_transform_origtensor(&cf_output_ztensor, cf_output_data); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&input); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&h0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&c0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output_ztensor); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&cf_output_ztensor); assert(status == ZDNN_OK); free(input_data); free(hidden_state_data); free(cell_state_data); free(weights_data_f); free(weights_data_i); free(weights_data_c); free(weights_data_o); free(hidden_weights_data_f); free(hidden_weights_data_i); free(hidden_weights_data_c); free(hidden_weights_data_o); free(biases_data_f); free(biases_data_i); free(biases_data_c); free(biases_data_o); free(hidden_biases_data_f); free(hidden_biases_data_i); free(hidden_biases_data_c); free(hidden_biases_data_o); free(hn_output_data); free(cf_output_data); } ``` --- ### Example of an application calling the zdnn_lstm API (bi-directional) [Back to Table of Contents](#TOC) ``` // SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // Sample: LSTM BI-DIR int main(int argc, char *argv[]) { zdnn_status status; #ifdef STATIC_LIB zdnn_init(); #endif /*********************************************************************** * * LSTM (BI-DIR): * * INPUTS -------------------------------------------------------------- * input | ZDNN_3DS | (num_timesteps, num_batches, num_features) * h0 | ZDNN_3DS | (2, num_batches, num_hidden) * c0 | ZDNN_3DS | (2, num_batches, num_hidden) * weights | ZDNN_3DS | (2, num_features, num_hidden) * biases | ZDNN_2DS | (2, num_hidden) * hidden_weights | ZDNN_3DS | (2, num_hidden, num_hidden) * hidden_biases | ZDNN_2DS | (2, num_hidden) * * OUTPUTS ------------------------------------------------------------- * hn_output | ZDNN_4DS | (num_timesteps, 2, num_batches, num_hidden) * | | or (1, 2, num_batches, num_hidden) * cf_output | ZDNN_4DS | (1, 2, num_batches, num_hidden) ***********************************************************************/ /*********************************************************************** * Create input zTensor ***********************************************************************/ zdnn_tensor_desc input_pre_tfrmd_desc, input_tfrmd_desc; zdnn_ztensor input; uint32_t num_timesteps = 5; uint32_t num_batches = 3; uint32_t num_features = 32; uint32_t num_hidden = 5; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes lstm_gru_direction dir = BIDIR; uint8_t num_dirs = 2; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &input_pre_tfrmd_desc, num_timesteps, num_batches, num_features); status = zdnn_generate_transformed_desc(&input_pre_tfrmd_desc, &input_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&input_pre_tfrmd_desc, &input_tfrmd_desc, &input); assert(status == ZDNN_OK); uint64_t input_data_size = num_timesteps * num_batches * num_features * element_size; void *input_data = malloc(input_data_size); status = zdnn_transform_ztensor(&input, input_data); assert(status == ZDNN_OK); /*********************************************************************** * Create initial hidden and cell state zTensors ***********************************************************************/ zdnn_tensor_desc h0c0_pre_tfrmd_desc, h0c0_tfrmd_desc; zdnn_ztensor h0, c0; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &h0c0_pre_tfrmd_desc, num_dirs, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &h0); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &c0); assert(status == ZDNN_OK); uint64_t h0c0_data_size = num_batches * num_hidden * element_size; void *hidden_state_data = malloc(h0c0_data_size); void *cell_state_data = malloc(h0c0_data_size); status = zdnn_transform_ztensor(&h0, hidden_state_data); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&c0, cell_state_data); assert(status == ZDNN_OK); /*********************************************************************** * Create input weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc weights_pre_tfrmd_desc, weights_tfrmd_desc; zdnn_ztensor weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &weights_pre_tfrmd_desc, num_dirs, num_features, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_NONE, &weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&weights_pre_tfrmd_desc, &weights_tfrmd_desc, &weights); assert(status == ZDNN_OK); uint64_t weights_data_size = num_features * num_hidden * element_size; void *weights_data_f = malloc(weights_data_size); void *weights_data_i = malloc(weights_data_size); void *weights_data_c = malloc(weights_data_size); void *weights_data_o = malloc(weights_data_size); status = zdnn_transform_ztensor(&weights, weights_data_f, weights_data_i, weights_data_c, weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc biases_pre_tfrmd_desc, biases_tfrmd_desc; zdnn_ztensor biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_BIASES | PREV_LAYER_NONE, &biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&biases_pre_tfrmd_desc, &biases_tfrmd_desc, &biases); assert(status == ZDNN_OK); uint64_t biases_data_size = num_hidden * element_size; void *biases_data_f = malloc(biases_data_size); void *biases_data_i = malloc(biases_data_size); void *biases_data_c = malloc(biases_data_size); void *biases_data_o = malloc(biases_data_size); status = zdnn_transform_ztensor(&biases, biases_data_f, biases_data_i, biases_data_c, biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc hidden_weights_pre_tfrmd_desc, hidden_weights_tfrmd_desc; zdnn_ztensor hidden_weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &hidden_weights_pre_tfrmd_desc, num_dirs, num_hidden, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_WEIGHTS | PREV_LAYER_NONE, &hidden_weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hidden_weights_pre_tfrmd_desc, &hidden_weights_tfrmd_desc, &hidden_weights); assert(status == ZDNN_OK); uint64_t hidden_weights_data_size = num_hidden * num_hidden * element_size; void *hidden_weights_data_f = malloc(hidden_weights_data_size); void *hidden_weights_data_i = malloc(hidden_weights_data_size); void *hidden_weights_data_c = malloc(hidden_weights_data_size); void *hidden_weights_data_o = malloc(hidden_weights_data_size); status = zdnn_transform_ztensor(&hidden_weights, hidden_weights_data_f, hidden_weights_data_i, hidden_weights_data_c, hidden_weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc hidden_biases_pre_tfrmd_desc, hidden_biases_tfrmd_desc; zdnn_ztensor hidden_biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &hidden_biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_BIASES | PREV_LAYER_NONE, &hidden_biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc( &hidden_biases_pre_tfrmd_desc, &hidden_biases_tfrmd_desc, &hidden_biases); assert(status == ZDNN_OK); uint64_t hidden_biases_data_size = num_hidden * element_size; void *hidden_biases_data_f = malloc(hidden_biases_data_size); void *hidden_biases_data_i = malloc(hidden_biases_data_size); void *hidden_biases_data_c = malloc(hidden_biases_data_size); void *hidden_biases_data_o = malloc(hidden_biases_data_size); status = zdnn_transform_ztensor(&hidden_biases, hidden_biases_data_f, hidden_biases_data_i, hidden_biases_data_c, hidden_biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create output zTensor ***********************************************************************/ zdnn_tensor_desc hn_pre_tfrmd_desc, hn_tfrmd_desc, cf_pre_tfrmd_desc, cf_tfrmd_desc; zdnn_ztensor hn_output_ztensor, cf_output_ztensor; zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &hn_pre_tfrmd_desc, num_timesteps, 2, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&hn_pre_tfrmd_desc, &hn_tfrmd_desc); assert(status == ZDNN_OK); zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &cf_pre_tfrmd_desc, 1, 2, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&cf_pre_tfrmd_desc, &cf_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hn_pre_tfrmd_desc, &hn_tfrmd_desc, &hn_output_ztensor); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&cf_pre_tfrmd_desc, &cf_tfrmd_desc, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Call the AIU ***********************************************************************/ void *work_area = NULL; status = zdnn_lstm(&input, &h0, &c0, &weights, &biases, &hidden_weights, &hidden_biases, dir, work_area, &hn_output_ztensor, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Output and Cleanup ***********************************************************************/ uint64_t hn_data_size = num_timesteps * 2 * num_batches * num_hidden * element_size; uint64_t cf_data_size = 2 * num_batches * num_hidden * element_size; void *hn_output_data = malloc(hn_data_size); void *cf_output_data = malloc(cf_data_size); status = zdnn_transform_origtensor(&hn_output_ztensor, hn_output_data); assert(status == ZDNN_OK); status = zdnn_transform_origtensor(&cf_output_ztensor, cf_output_data); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&input); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&h0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&c0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output_ztensor); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&cf_output_ztensor); assert(status == ZDNN_OK); free(input_data); free(hidden_state_data); free(cell_state_data); free(weights_data_f); free(weights_data_i); free(weights_data_c); free(weights_data_o); free(hidden_weights_data_f); free(hidden_weights_data_i); free(hidden_weights_data_c); free(hidden_weights_data_o); free(biases_data_f); free(biases_data_i); free(biases_data_c); free(biases_data_o); free(hidden_biases_data_f); free(hidden_biases_data_i); free(hidden_biases_data_c); free(hidden_biases_data_o); free(hn_output_data); free(cf_output_data); } ``` --- ### Example of an application calling the zdnn_lstm API (multi-layer bi-directional) [Back to Table of Contents](#TOC) ``` // SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" void do_bidir_layer(zdnn_ztensor *input, uint32_t num_hidden, zdnn_ztensor *hn_output, bool is_prev_layer_bidir) { zdnn_status status; uint32_t num_batches = input->pre_transformed_desc->dim2; // if input is bidir output from previous layer then number of features for // this layer is 2x of hidden-state size (dim1) of the previous layer uint32_t num_features = input->pre_transformed_desc->dim1 * (is_prev_layer_bidir ? 2 : 1); zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes lstm_gru_direction dir = BIDIR; uint8_t num_dirs = 2; /*********************************************************************** * Create initial hidden and cell state zTensors ***********************************************************************/ zdnn_tensor_desc h0c0_pre_tfrmd_desc, h0c0_tfrmd_desc; zdnn_ztensor h0, c0; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &h0c0_pre_tfrmd_desc, num_dirs, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &h0); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &c0); assert(status == ZDNN_OK); uint64_t h0c0_data_size = num_batches * num_hidden * element_size; void *hidden_state_data = malloc(h0c0_data_size); void *cell_state_data = malloc(h0c0_data_size); status = zdnn_transform_ztensor(&h0, hidden_state_data); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&c0, cell_state_data); assert(status == ZDNN_OK); /*********************************************************************** * Create input weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc weights_pre_tfrmd_desc, weights_tfrmd_desc; zdnn_ztensor weights; // if using previous layer bidir output as input then number of features of // this layer is zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &weights_pre_tfrmd_desc, num_dirs, num_features, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_WEIGHTS | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI), &weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&weights_pre_tfrmd_desc, &weights_tfrmd_desc, &weights); assert(status == ZDNN_OK); uint64_t weights_data_size = num_features * num_hidden * element_size; void *weights_data_f = malloc(weights_data_size); void *weights_data_i = malloc(weights_data_size); void *weights_data_c = malloc(weights_data_size); void *weights_data_o = malloc(weights_data_size); status = zdnn_transform_ztensor(&weights, weights_data_f, weights_data_i, weights_data_c, weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc biases_pre_tfrmd_desc, biases_tfrmd_desc; zdnn_ztensor biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_BIASES | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI), &biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&biases_pre_tfrmd_desc, &biases_tfrmd_desc, &biases); assert(status == ZDNN_OK); uint64_t biases_data_size = num_hidden * element_size; void *biases_data_f = malloc(biases_data_size); void *biases_data_i = malloc(biases_data_size); void *biases_data_c = malloc(biases_data_size); void *biases_data_o = malloc(biases_data_size); status = zdnn_transform_ztensor(&biases, biases_data_f, biases_data_i, biases_data_c, biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc hidden_weights_pre_tfrmd_desc, hidden_weights_tfrmd_desc; zdnn_ztensor hidden_weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &hidden_weights_pre_tfrmd_desc, num_dirs, num_hidden, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_WEIGHTS | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI), &hidden_weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hidden_weights_pre_tfrmd_desc, &hidden_weights_tfrmd_desc, &hidden_weights); assert(status == ZDNN_OK); uint64_t hidden_weights_data_size = num_hidden * num_hidden * element_size; void *hidden_weights_data_f = malloc(hidden_weights_data_size); void *hidden_weights_data_i = malloc(hidden_weights_data_size); void *hidden_weights_data_c = malloc(hidden_weights_data_size); void *hidden_weights_data_o = malloc(hidden_weights_data_size); status = zdnn_transform_ztensor(&hidden_weights, hidden_weights_data_f, hidden_weights_data_i, hidden_weights_data_c, hidden_weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc hidden_biases_pre_tfrmd_desc, hidden_biases_tfrmd_desc; zdnn_ztensor hidden_biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &hidden_biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_BIASES | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI), &hidden_biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc( &hidden_biases_pre_tfrmd_desc, &hidden_biases_tfrmd_desc, &hidden_biases); assert(status == ZDNN_OK); uint64_t hidden_biases_data_size = num_hidden * element_size; void *hidden_biases_data_f = malloc(hidden_biases_data_size); void *hidden_biases_data_i = malloc(hidden_biases_data_size); void *hidden_biases_data_c = malloc(hidden_biases_data_size); void *hidden_biases_data_o = malloc(hidden_biases_data_size); status = zdnn_transform_ztensor(&hidden_biases, hidden_biases_data_f, hidden_biases_data_i, hidden_biases_data_c, hidden_biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create cf output zTensor ***********************************************************************/ zdnn_tensor_desc cf_pre_tfrmd_desc, cf_tfrmd_desc; zdnn_ztensor cf_output_ztensor; zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &cf_pre_tfrmd_desc, 1, 2, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&cf_pre_tfrmd_desc, &cf_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&cf_pre_tfrmd_desc, &cf_tfrmd_desc, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Call the AIU ***********************************************************************/ void *work_area = NULL; status = zdnn_lstm(input, &h0, &c0, &weights, &biases, &hidden_weights, &hidden_biases, dir, work_area, hn_output, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Cleanup and Return ***********************************************************************/ status = zdnn_free_ztensor_buffer(&h0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&c0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&cf_output_ztensor); assert(status == ZDNN_OK); free(hidden_state_data); free(cell_state_data); free(weights_data_f); free(weights_data_i); free(weights_data_c); free(weights_data_o); free(hidden_weights_data_f); free(hidden_weights_data_i); free(hidden_weights_data_c); free(hidden_weights_data_o); free(biases_data_f); free(biases_data_i); free(biases_data_c); free(biases_data_o); free(hidden_biases_data_f); free(hidden_biases_data_i); free(hidden_biases_data_c); free(hidden_biases_data_o); } // Sample: LSTM multi-layer BIDIR int main(int argc, char *argv[]) { zdnn_status status; #ifdef STATIC_LIB zdnn_init(); #endif uint32_t num_hidden[2] = {5, 4}; /*********************************************************************** * Create input zTensor ***********************************************************************/ zdnn_tensor_desc input_pre_tfrmd_desc, input_tfrmd_desc; zdnn_ztensor input; uint32_t num_timesteps = 5; uint32_t num_batches = 3; uint32_t num_features = 32; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &input_pre_tfrmd_desc, num_timesteps, num_batches, num_features); status = zdnn_generate_transformed_desc(&input_pre_tfrmd_desc, &input_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&input_pre_tfrmd_desc, &input_tfrmd_desc, &input); assert(status == ZDNN_OK); uint64_t input_data_size = num_timesteps * num_batches * num_features * element_size; void *input_data = malloc(input_data_size); status = zdnn_transform_ztensor(&input, input_data); assert(status == ZDNN_OK); /*********************************************************************** * Create 2 hn output zTensors ***********************************************************************/ zdnn_tensor_desc hn_pre_tfrmd_desc[2], hn_tfrmd_desc[2]; zdnn_ztensor hn_output[2]; for (int i = 0; i < 2; i++) { zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &hn_pre_tfrmd_desc[i], num_timesteps, 2, num_batches, num_hidden[i]); status = zdnn_generate_transformed_desc(&hn_pre_tfrmd_desc[i], &hn_tfrmd_desc[i]); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hn_pre_tfrmd_desc[i], &hn_tfrmd_desc[i], &hn_output[i]); assert(status == ZDNN_OK); } /*********************************************************************** * Do the layers ***********************************************************************/ // call the first layer with input, previous layer bidir = false, output goes // to hn_output[0] do_bidir_layer(&input, num_hidden[0], &hn_output[0], false); // call the second layer with hn_output[0] from layer 1, previous layer bidir // = true, output goes to hn_output[1] do_bidir_layer(&hn_output[0], num_hidden[1], &hn_output[1], true); /*********************************************************************** * Output and Cleanup ***********************************************************************/ void *hn_output_data[2]; for (int i = 0; i < 2; i++) { uint64_t hn_output_data_size = (uint64_t)num_timesteps * num_batches * num_hidden[i] * 2 * element_size; hn_output_data[i] = malloc(hn_output_data_size); status = zdnn_transform_origtensor(&hn_output[i], hn_output_data[i]); assert(status == ZDNN_OK); } status = zdnn_free_ztensor_buffer(&input); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output[0]); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output[1]); assert(status == ZDNN_OK); free(input_data); free(hn_output_data[0]); free(hn_output_data[1]); } ``` --- ### Example of an application calling the zdnn_gru API (forward) [Back to Table of Contents](#TOC) ``` // SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // Sample: GRU int main(int argc, char *argv[]) { zdnn_status status; #ifdef STATIC_LIB zdnn_init(); #endif /*********************************************************************** * * GRU (FWD/BWD): * * INPUTS -------------------------------------------------------------- * input | ZDNN_3DS | (num_timesteps, num_batches, num_features) * h0 | ZDNN_3DS | (1, num_batches, num_hidden) * weights | ZDNN_3DS | (1, num_features, num_hidden) * input_biases | ZDNN_2DS | (1, num_hidden) * hidden_weights | ZDNN_3DS | (1, num_hidden, num_hidden) * hidden_biases | ZDNN_2DS | (1, num_hidden) * * OUTPUTS ------------------------------------------------------------- * hn_output | ZDNN_4DS | (num_timesteps, 1, num_batches, num_hidden) * | | or (1, 1, num_batches, num_hidden) ***********************************************************************/ /*********************************************************************** * Create input zTensor ***********************************************************************/ zdnn_tensor_desc input_pre_tfrmd_desc, input_tfrmd_desc; zdnn_ztensor input; uint32_t num_timesteps = 5; uint32_t num_batches = 3; uint32_t num_features = 32; uint32_t num_hidden = 5; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes lstm_gru_direction dir = FWD; uint8_t num_dirs = 1; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &input_pre_tfrmd_desc, num_timesteps, num_batches, num_features); status = zdnn_generate_transformed_desc(&input_pre_tfrmd_desc, &input_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&input_pre_tfrmd_desc, &input_tfrmd_desc, &input); assert(status == ZDNN_OK); uint64_t input_data_size = num_timesteps * num_batches * num_features * element_size; void *input_data = malloc(input_data_size); status = zdnn_transform_ztensor(&input, input_data); assert(status == ZDNN_OK); /*********************************************************************** * Create initial hidden zTensor ***********************************************************************/ zdnn_tensor_desc h0_pre_tfrmd_desc, h0_tfrmd_desc; zdnn_ztensor h0; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &h0_pre_tfrmd_desc, num_dirs, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&h0_pre_tfrmd_desc, &h0_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0_pre_tfrmd_desc, &h0_tfrmd_desc, &h0); assert(status == ZDNN_OK); uint64_t h0_data_size = num_batches * num_hidden * element_size; void *hidden_state_data = malloc(h0_data_size); status = zdnn_transform_ztensor(&h0, hidden_state_data); assert(status == ZDNN_OK); /*********************************************************************** * Create input weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc weights_pre_tfrmd_desc, weights_tfrmd_desc; zdnn_ztensor weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &weights_pre_tfrmd_desc, num_dirs, num_features, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &weights_pre_tfrmd_desc, RNN_TYPE_GRU | USAGE_WEIGHTS | PREV_LAYER_NONE, &weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&weights_pre_tfrmd_desc, &weights_tfrmd_desc, &weights); assert(status == ZDNN_OK); uint64_t weights_data_size = num_features * num_hidden * element_size; void *weights_data_z = malloc(weights_data_size); void *weights_data_r = malloc(weights_data_size); void *weights_data_h = malloc(weights_data_size); status = zdnn_transform_ztensor(&weights, weights_data_z, weights_data_r, weights_data_h); assert(status == ZDNN_OK); /*********************************************************************** * Create biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc biases_pre_tfrmd_desc, biases_tfrmd_desc; zdnn_ztensor biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &biases_pre_tfrmd_desc, RNN_TYPE_GRU | USAGE_BIASES | PREV_LAYER_NONE, &biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&biases_pre_tfrmd_desc, &biases_tfrmd_desc, &biases); assert(status == ZDNN_OK); uint64_t biases_data_size = num_hidden * element_size; void *biases_data_z = malloc(biases_data_size); void *biases_data_r = malloc(biases_data_size); void *biases_data_h = malloc(biases_data_size); status = zdnn_transform_ztensor(&biases, biases_data_z, biases_data_r, biases_data_h); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc hidden_weights_pre_tfrmd_desc, hidden_weights_tfrmd_desc; zdnn_ztensor hidden_weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &hidden_weights_pre_tfrmd_desc, num_dirs, num_hidden, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_weights_pre_tfrmd_desc, RNN_TYPE_GRU | USAGE_HIDDEN_WEIGHTS | PREV_LAYER_NONE, &hidden_weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hidden_weights_pre_tfrmd_desc, &hidden_weights_tfrmd_desc, &hidden_weights); assert(status == ZDNN_OK); uint64_t hidden_weights_data_size = num_hidden * num_hidden * element_size; void *hidden_weights_data_z = malloc(hidden_weights_data_size); void *hidden_weights_data_r = malloc(hidden_weights_data_size); void *hidden_weights_data_h = malloc(hidden_weights_data_size); status = zdnn_transform_ztensor(&hidden_weights, hidden_weights_data_z, hidden_weights_data_r, hidden_weights_data_h); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc hidden_biases_pre_tfrmd_desc, hidden_biases_tfrmd_desc; zdnn_ztensor hidden_biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &hidden_biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_biases_pre_tfrmd_desc, RNN_TYPE_GRU | USAGE_HIDDEN_BIASES | PREV_LAYER_NONE, &hidden_biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc( &hidden_biases_pre_tfrmd_desc, &hidden_biases_tfrmd_desc, &hidden_biases); assert(status == ZDNN_OK); uint64_t hidden_biases_data_size = num_hidden * element_size; void *hidden_biases_data_z = malloc(hidden_biases_data_size); void *hidden_biases_data_r = malloc(hidden_biases_data_size); void *hidden_biases_data_h = malloc(hidden_biases_data_size); status = zdnn_transform_ztensor(&hidden_biases, hidden_biases_data_z, hidden_biases_data_r, hidden_biases_data_h); assert(status == ZDNN_OK); /*********************************************************************** * Create output zTensor ***********************************************************************/ // get only the last timestep zdnn_tensor_desc hn_pre_tfrmd_desc, hn_tfrmd_desc; zdnn_ztensor hn_output_ztensor; zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &hn_pre_tfrmd_desc, 1, 1, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&hn_pre_tfrmd_desc, &hn_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hn_pre_tfrmd_desc, &hn_tfrmd_desc, &hn_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Call the AIU ***********************************************************************/ void *work_area = NULL; status = zdnn_gru(&input, &h0, &weights, &biases, &hidden_weights, &hidden_biases, dir, work_area, &hn_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Output and Cleanup ***********************************************************************/ uint64_t hn_data_size = num_batches * num_hidden * element_size; void *hn_output_data = malloc(hn_data_size); status = zdnn_transform_origtensor(&hn_output_ztensor, hn_output_data); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&input); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&h0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output_ztensor); assert(status == ZDNN_OK); free(input_data); free(hidden_state_data); free(weights_data_z); free(weights_data_r); free(weights_data_h); free(hidden_weights_data_z); free(hidden_weights_data_r); free(hidden_weights_data_h); free(biases_data_z); free(biases_data_r); free(biases_data_h); free(hidden_biases_data_z); free(hidden_biases_data_r); free(hidden_biases_data_h); free(hn_output_data); } ``` ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/config.h.in������������������������������������������������������������������������������0000664�0000000�0000000�00000001354�14364043643�0014357�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Enable additional checking, error reporting, disable compiler optimizations, and add debug information */ #undef ZDNN_CONFIG_DEBUG /* Skip all NNPA facility instructions. */ #undef ZDNN_CONFIG_NO_NNPA ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/config.make.in���������������������������������������������������������������������������0000664�0000000�0000000�00000003452�14364043643�0015046�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # #     http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. srcdir := @srcdir@ objdir := @objdir@ # The following variables influences the paths used by make install. prefix := @prefix@ exec_prefix := @exec_prefix@ includedir := @includedir@ libdir := @libdir@ CC := @CC@ CXX := @CXX@ LD := @LD@ AR := @AR@ ARFLAGS := @ARFLAGS@ CFLAGS_INIT := @CFLAGS_INIT@ "@CFLAGS_QUOTE_INIT@" CFLAGS := @CFLAGS@ "@CFLAGS_QUOTE@" CFLAGS_DEBUG := @CFLAGS_DEBUG@ CFLAGS_SHARED := @CFLAGS_SHARED@ CFLAGS_NOSEARCH := @CFLAGS_NOSEARCH@ CXXFLAGS_ASM := @CXXFLAGS_ASM@ CFLAGS_ASM := @CFLAGS_ASM@ CXXFLAGS := @CXXFLAGS@ CPP_SYMCHECK_FLAGS := @CPP_SYMCHECK_FLAGS@ SODIR := @SODIR@ LIBNAME := @LIBNAME@ LIBSONAME := @LIBSONAME@ LIBNAME_PRIVATE=@LIBNAME_PRIVATE@ LIBSONAME_PRIVATE=@LIBSONAME_PRIVATE@ LDFLAGS := @LDFLAGS@ LDFLAGS_SHARED := @LDFLAGS_SHARED@ LDFLAGS_SHARED_EXPORTALL := @LDFLAGS_SHARED_EXPORTALL@ LDFLAGS_TEST := @LDFLAGS_TEST@ LD_PATH_VAR := @LD_PATH_VAR@ ECHOFLAGS := "@ECHOFLAGS@" AWK := @AWK@ READELF := @READELF@ INSTALL := install -c INSTALL_DATA := $(INSTALL) -m 644 ZDNN_TMAKE_FILES := @ZDNN_TMAKE_FILES@ ZDNN_MAKE_TARGETS := @ZDNN_MAKE_TARGETS@ ZDNN_INSTALL_TARGETS := @ZDNN_INSTALL_TARGETS@ # Build options debug := @zdnn_config_debug@ no_rpath := @zdnn_config_no_rpath@ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/config.zdnn������������������������������������������������������������������������������0000664�0000000�0000000�00000007423�14364043643�0014477�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 #  # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at #  #     http://www.apache.org/licenses/LICENSE-2.0 #  # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This script is invoked by configure to set the initial values of # certain platform-dependent variables. target="$(uname -m)-$(uname)" case "${target}" in s390x-Linux) CC=${CC:-gcc} CXX=${CXX:-g++} LD=${LD:-g++} AR=${AR:-ar} ARFLAGS="${ARFLAGS:--rc}" CFLAGS_INIT="-O3 -mzvector -Wall -std=gnu99 -fstack-protector-all ${CFLAGS_INIT:-}" CFLAGS_QUOTE_INIT="-Wall" # Not needed on Linux. Just repeat an option to prevent it from being empty. CFLAGS="-O3 -march=z14 -mzvector -Wall -std=gnu99 -fstack-protector-all ${CFLAGS:-}" CFLAGS_QUOTE="-Wall" CFLAGS_DEBUG="-O0 -g3 ${CFLAGS_DEBUG:-}" CFLAGS_SHARED="-fPIC ${CFLAGS_SHARED:-}" CFLAGS_ASM="-Wa,-adhln -fno-asynchronous-unwind-tables ${CFLAGS_ASM:-}" CFLAGS_OPT_EXPENSIVE="-funroll-loops" CFLAGS_NOSEARCH="" CXXFLAGS="-O3 -march=z14 -Wall ${CXXFLAGS:-}" CPP_SYMCHECK_FLAGS="-E -o zdnn.i" SODIR="${SODIR:-lib}" LIBNAME="${LIBNAME:-libzdnn}" LIBSONAME="${LIBSONAME:-${LIBNAME}.so.0}" LIBNAME_PRIVATE="${LIBNAME_PRIVATE:-${LIBNAME}-private}" LIBSONAME_PRIVATE="${LIBSONAME_PRIVATE:-${LIBNAME_PRIVATE}.so.0}" LDFLAGS="${LDFLAGS:-}" LDFLAGS_SHARED="-shared -Wl,-Bsymbolic-functions -Wl,-soname,${LIBSONAME} -Wl,--version-script=zdnn.map -lm ${LDFLAGS_SHARED:-}" LDFLAGS_SHARED_EXPORTALL="-shared -Wl,-Bsymbolic-functions -Wl,-soname,${LIBSONAME_PRIVATE} -Wl,--version-script=zdnn_exportall.map -lm ${LDFLAGS_SHARED_EXPORTALL:-}" LDFLAGS_TEST="-L ../zdnn/${SODIR} -l${LIBNAME_PRIVATE#lib} ../zdnn/${SODIR}/${LIBNAME_PRIVATE}.so -lm ${LDFLAGS_TEST:-}" LD_PATH_VAR="${LD_PATH_VAR:-LD_LIBRARY_PATH}" ECHOFLAGS="-e" ZDNN_TMAKE_FILES="t-static t-libsoname t-gccexpo t-symcheck t-listings" ZDNN_MAKE_TARGETS="${SODIR}/${LIBNAME}.a libsoname symcheck" ZDNN_INSTALL_TARGETS="install_libsoname install_static" ;; *-OS/390) CC=${CC:-xlc} CXX=${CXX:-xlC} LD=${LD:-xlC} AR=${AR:-ar} ARFLAGS="${ARFLAGS:--rc}" CXXFLAGS="-I /usr/include -I /u/mvsbuild/zos25/usr/include/zos/ -Wc,ASM,LP64,INLINE,VECTOR ${CXXFLAGS:-}" CFLAGS_INIT="${CXXFLAGS} -qlanglvl=extc99 ${CFLAGS_INIT:-}" CFLAGS_QUOTE_INIT="-Wc,SUPPRESS(CCN4108),STACKPROTECT(ALL)" # The options with () require an extra pair of quotes in config.make.in CFLAGS="${CXXFLAGS} -qlanglvl=extc99 ${CFLAGS:-}" CFLAGS_QUOTE="-Wc,ARCH(12),SUPPRESS(CCN4108),STACKPROTECT(ALL)" CFLAGS_DEBUG="-g3 ${CFLAGS_DEBUG:-}" CFLAGS_SHARED="-Wc,DLL ${CFLAGS_SHARED:-}" CXXFLAGS_ASM='-Wc,"SOURCE,LIST"'" ${CXXFLAGS_ASM:-}" CFLAGS_ASM="${CXXFLAGS_ASM} -Wc,AGGREGATE ${CFLAGS_ASM:-}" CFLAGS_OPT_EXPENSIVE="-qhot" CFLAGS_NOSEARCH="-qnosearch" CPP_SYMCHECK_FLAGS="-P" SODIR="${SODIR:-lib}" LIBNAME="${LIBNAME:-libzdnn}" LIBSONAME="${LIBSONAME:-}" LIBNAME_PRIVATE="${LIBNAME_PRIVATE:-${LIBNAME}-private}" LIBSONAME_PRIVATE="${LIBSONAME_PRIVATE:-}" LDFLAGS="${LDFLAGS:-}" LDFLAGS_SHARED="-Wl,DLL -Wc,LP64 ${LDFLAGS_SHARED:-}" LDFLAGS_SHARED_EXPORTALL="${LDFLAGS_SHARED_EXPORTALL:-}" LDFLAGS_TEST="../zdnn/${SODIR}/${LIBNAME_PRIVATE}.x -lm ${LDFLAGS_TEST:-}" LD_PATH_VAR="${LD_PATH_VAR:-LIBPATH}" ECHOFLAGS="" ZDNN_TMAKE_FILES="t-xlcexpo t-symcheck t-listings" ZDNN_MAKE_TARGETS="${SODIR}/${LIBNAME}.x symcheck" ZDNN_INSTALL_TARGETS="" ;; *) echo "Platform ${target} is not supported" exit 1 ;; esac ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/configure.ac�����������������������������������������������������������������������������0000664�0000000�0000000�00000007042�14364043643�0014622�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # #     http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. AC_INIT([libzdnn], [1.0.1]) objdir=`pwd -P` if test ! "`cd $srcdir; pwd -P`" = "$objdir"; then AC_MSG_ERROR([Configuring is only allowed in source directory! If needed, please propose a patch!]) fi . ./config.zdnn || exit 1 # Currently objdir is equal to srcdir, but it is used in "make install" # in order to distinguish sources and binaries. AC_SUBST(objdir) # Check for requirements AC_PROG_CC AC_PROG_CXX AC_CONFIG_HEADERS([config.h]) AC_ARG_VAR(CC) AC_ARG_VAR(CXX) AC_ARG_VAR(LD) AC_ARG_VAR(AR) AC_ARG_VAR(ARFLAGS) AC_ARG_VAR(CFLAGS) AC_ARG_VAR(CFLAGS_INIT) AC_ARG_VAR(CFLAGS_DEBUG) AC_ARG_VAR(CFLAGS_SHARED) AC_ARG_VAR(CFLAGS_ASM) AC_ARG_VAR(CFLAGS_NOSEARCH) AC_ARG_VAR(CXXFLAGS) AC_ARG_VAR(CXXFLAGS_ASM) AC_ARG_VAR(CPP_SYMCHECK_FLAGS) AC_ARG_VAR(SODIR) AC_ARG_VAR(LIBNAME) AC_ARG_VAR(LIBSONAME) AC_ARG_VAR(LIBNAME_PRIVATE) AC_ARG_VAR(LIBSONAME_PRIVATE) AC_ARG_VAR(LDFLAGS) AC_ARG_VAR(LDFLAGS_SHARED) AC_ARG_VAR(LDFLAGS_SHARED_EXPORTALL) AC_ARG_VAR(LDFLAGS_TEST) AC_ARG_VAR(ECHOFLAGS) AC_ARG_VAR(AWK) AC_ARG_VAR(READELF) AC_SUBST(CFLAGS_QUOTE) AC_SUBST(CFLAGS_QUOTE_INIT) AC_SUBST(zdnn_config_debug, 0) AC_SUBST(zdnn_config_no_rpath, 0) AC_SUBST(ZDNN_TMAKE_FILES) AC_SUBST(ZDNN_MAKE_TARGETS) AC_SUBST(ZDNN_INSTALL_TARGETS) AC_SUBST(LD_PATH_VAR) AC_CHECK_PROG(AWK, awk, awk, false) AS_IF([test x"$AWK" = x"false"], [AC_MSG_ERROR([Please install awk before configuring.])]) AC_CHECK_TOOL(READELF, readelf, "") AS_IF([test x"$READELF" = x"false"], [AC_MSG_WARN([readelf is required for checking the exported symbols. Check will be skipped.])]) AC_ARG_ENABLE([nnpa], AS_HELP_STRING([--disable-nnpa], [Skip all NNPA facility instructions.])) AS_IF([test "x$enable_nnpa" = "xno"], [ AC_DEFINE(ZDNN_CONFIG_NO_NNPA, 1, [Skip all NNPA facility instructions.]) ]) AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [Enable additional checking, error reporting, disable compiler optimizations, and add debug information])) AS_IF([test "x$enable_debug" = "xyes"], [ zdnn_config_debug=1 CFLAGS="${CFLAGS} ${CFLAGS_DEBUG}" CFLAGS_INIT="${CFLAGS_INIT} ${CFLAGS_DEBUG}" CXXFLAGS="${CXXFLAGS} ${CFLAGS_DEBUG}" AC_DEFINE(ZDNN_CONFIG_DEBUG, 1, [Enable additional checking, error reporting, disable compiler optimizations, and add debug information]) ]) AC_ARG_ENABLE([listings], AS_HELP_STRING([--enable-listings], [Make 'make all' generate assembler listings])) AS_IF([test "x$enable_listings" = "xyes"], [ ZDNN_MAKE_TARGETS="${ZDNN_MAKE_TARGETS} listings" ]) AC_ARG_ENABLE([test-rpath], AS_HELP_STRING([--disable-test-rpath], [Don't set the rpath in the test binaries to keep them relocatable])) AS_IF([test "x$enable_test_rpath" = "xno"], [zdnn_config_no_rpath=1]) AC_ARG_ENABLE([expensive-optimizations], AS_HELP_STRING([--disable-expensive-optimizations], [Disable expensive compiler optimizations.])) AS_IF([test "x$enable_expensive_optimizations" != "xno"], [ CFLAGS="${CFLAGS} ${CFLAGS_OPT_EXPENSIVE}" ]) # Generate output AC_CONFIG_FILES([config.make]) AC_OUTPUT ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/docs/������������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14364043643�0013261�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/docs/CODEOWNERS��������������������������������������������������������������������������0000664�0000000�0000000�00000000167�14364043643�0014660�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Trigger following contributors/global code owners for each code change. * nmarion@us.ibm.com krebbel@linux.ibm.com ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/docs/pull_request_template.md������������������������������������������������������������0000664�0000000�0000000�00000000666�14364043643�0020232�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������### Description <!-- COMMENT: Please give a good description of your contribution so that the reviewers quickly understand the meaning of this contribution. --> #### Features <!-- COMMENT: A list of new implemented features. If there is a reference to an issue, please reference it with "#<ISSUE-ID>". --> #### Fixes <!-- COMMENT: A list of bug fixes. If there is a reference to an issue, please reference it with "#<ISSUE-ID>". --> ��������������������������������������������������������������������������zDNN-1.0.1/samples/���������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14364043643�0013775�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/README.md������������������������������������������������������������������������0000664�0000000�0000000�00000000615�14364043643�0015256�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Samples ## Compile Assume current directroy is `/samples` z/OS: ``` xlc -g3 -qlanglvl=extc99 -Wc,LP64 -I ../zdnn -o simple_add simple_add.c ../zdnn/lib/libzdnn.x ``` Linux's: ``` gcc -g3 -Wall -fmessage-length=0 -std=c99 -I ../zdnn -o simple_add simple_add.c ../zdnn/lib/libzdnn.so ``` ### NOTE: Add `-D STATIC_LIB` to gcc invocation if you're compiling using statically-linked library �������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/descriptor_share.c���������������������������������������������������������������0000664�0000000�0000000�00000004616�14364043643�0017510�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // *************************************************************************** // Sample: // // Descriptor sharing among zTensors // *************************************************************************** int main(int argc, char *argv[]) { zdnn_tensor_desc *pre_tfrmd_desc, *tfrmd_desc; zdnn_ztensor ztensor1, ztensor2; zdnn_status status; uint32_t dim2 = 32, dim1 = 3; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes uint64_t num_elements = dim2 * dim1; #ifdef STATIC_LIB zdnn_init(); #endif void *data1 = malloc(num_elements * element_size); void *data2 = malloc(num_elements * element_size); pre_tfrmd_desc = malloc(sizeof(zdnn_tensor_desc)); tfrmd_desc = malloc(sizeof(zdnn_tensor_desc)); zdnn_init_pre_transformed_desc(ZDNN_2DS, type, pre_tfrmd_desc, dim2, dim1); status = zdnn_generate_transformed_desc_concatenated(pre_tfrmd_desc, CONCAT_LSTM, tfrmd_desc); assert(status == ZDNN_OK); ztensor1.pre_transformed_desc = pre_tfrmd_desc; ztensor1.transformed_desc = tfrmd_desc; ztensor2.pre_transformed_desc = pre_tfrmd_desc; ztensor2.transformed_desc = tfrmd_desc; status = zdnn_init_ztensor_with_malloc(pre_tfrmd_desc, tfrmd_desc, &ztensor1); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(pre_tfrmd_desc, tfrmd_desc, &ztensor2); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&ztensor1, data1, data1, data1, data1); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&ztensor2, data2, data2, data2, data2); assert(status == ZDNN_OK); free(pre_tfrmd_desc); free(tfrmd_desc); free(data2); free(data1); } ������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/rnn_gru_fwd.c��������������������������������������������������������������������0000664�0000000�0000000�00000025653�14364043643�0016466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // Sample: GRU int main(int argc, char *argv[]) { zdnn_status status; #ifdef STATIC_LIB zdnn_init(); #endif /*********************************************************************** * * GRU (FWD/BWD): * * INPUTS -------------------------------------------------------------- * input | ZDNN_3DS | (num_timesteps, num_batches, num_features) * h0 | ZDNN_3DS | (1, num_batches, num_hidden) * weights | ZDNN_3DS | (1, num_features, num_hidden) * input_biases | ZDNN_2DS | (1, num_hidden) * hidden_weights | ZDNN_3DS | (1, num_hidden, num_hidden) * hidden_biases | ZDNN_2DS | (1, num_hidden) * * OUTPUTS ------------------------------------------------------------- * hn_output | ZDNN_4DS | (num_timesteps, 1, num_batches, num_hidden) * | | or (1, 1, num_batches, num_hidden) ***********************************************************************/ /*********************************************************************** * Create input zTensor ***********************************************************************/ zdnn_tensor_desc input_pre_tfrmd_desc, input_tfrmd_desc; zdnn_ztensor input; uint32_t num_timesteps = 5; uint32_t num_batches = 3; uint32_t num_features = 32; uint32_t num_hidden = 5; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes lstm_gru_direction dir = FWD; uint8_t num_dirs = 1; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &input_pre_tfrmd_desc, num_timesteps, num_batches, num_features); status = zdnn_generate_transformed_desc(&input_pre_tfrmd_desc, &input_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&input_pre_tfrmd_desc, &input_tfrmd_desc, &input); assert(status == ZDNN_OK); uint64_t input_data_size = num_timesteps * num_batches * num_features * element_size; void *input_data = malloc(input_data_size); status = zdnn_transform_ztensor(&input, input_data); assert(status == ZDNN_OK); /*********************************************************************** * Create initial hidden zTensor ***********************************************************************/ zdnn_tensor_desc h0_pre_tfrmd_desc, h0_tfrmd_desc; zdnn_ztensor h0; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &h0_pre_tfrmd_desc, num_dirs, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&h0_pre_tfrmd_desc, &h0_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0_pre_tfrmd_desc, &h0_tfrmd_desc, &h0); assert(status == ZDNN_OK); uint64_t h0_data_size = num_batches * num_hidden * element_size; void *hidden_state_data = malloc(h0_data_size); status = zdnn_transform_ztensor(&h0, hidden_state_data); assert(status == ZDNN_OK); /*********************************************************************** * Create input weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc weights_pre_tfrmd_desc, weights_tfrmd_desc; zdnn_ztensor weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &weights_pre_tfrmd_desc, num_dirs, num_features, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &weights_pre_tfrmd_desc, RNN_TYPE_GRU | USAGE_WEIGHTS | PREV_LAYER_NONE, &weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&weights_pre_tfrmd_desc, &weights_tfrmd_desc, &weights); assert(status == ZDNN_OK); uint64_t weights_data_size = num_features * num_hidden * element_size; void *weights_data_z = malloc(weights_data_size); void *weights_data_r = malloc(weights_data_size); void *weights_data_h = malloc(weights_data_size); status = zdnn_transform_ztensor(&weights, weights_data_z, weights_data_r, weights_data_h); assert(status == ZDNN_OK); /*********************************************************************** * Create biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc biases_pre_tfrmd_desc, biases_tfrmd_desc; zdnn_ztensor biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &biases_pre_tfrmd_desc, RNN_TYPE_GRU | USAGE_BIASES | PREV_LAYER_NONE, &biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&biases_pre_tfrmd_desc, &biases_tfrmd_desc, &biases); assert(status == ZDNN_OK); uint64_t biases_data_size = num_hidden * element_size; void *biases_data_z = malloc(biases_data_size); void *biases_data_r = malloc(biases_data_size); void *biases_data_h = malloc(biases_data_size); status = zdnn_transform_ztensor(&biases, biases_data_z, biases_data_r, biases_data_h); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc hidden_weights_pre_tfrmd_desc, hidden_weights_tfrmd_desc; zdnn_ztensor hidden_weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &hidden_weights_pre_tfrmd_desc, num_dirs, num_hidden, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_weights_pre_tfrmd_desc, RNN_TYPE_GRU | USAGE_HIDDEN_WEIGHTS | PREV_LAYER_NONE, &hidden_weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hidden_weights_pre_tfrmd_desc, &hidden_weights_tfrmd_desc, &hidden_weights); assert(status == ZDNN_OK); uint64_t hidden_weights_data_size = num_hidden * num_hidden * element_size; void *hidden_weights_data_z = malloc(hidden_weights_data_size); void *hidden_weights_data_r = malloc(hidden_weights_data_size); void *hidden_weights_data_h = malloc(hidden_weights_data_size); status = zdnn_transform_ztensor(&hidden_weights, hidden_weights_data_z, hidden_weights_data_r, hidden_weights_data_h); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc hidden_biases_pre_tfrmd_desc, hidden_biases_tfrmd_desc; zdnn_ztensor hidden_biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &hidden_biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_biases_pre_tfrmd_desc, RNN_TYPE_GRU | USAGE_HIDDEN_BIASES | PREV_LAYER_NONE, &hidden_biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc( &hidden_biases_pre_tfrmd_desc, &hidden_biases_tfrmd_desc, &hidden_biases); assert(status == ZDNN_OK); uint64_t hidden_biases_data_size = num_hidden * element_size; void *hidden_biases_data_z = malloc(hidden_biases_data_size); void *hidden_biases_data_r = malloc(hidden_biases_data_size); void *hidden_biases_data_h = malloc(hidden_biases_data_size); status = zdnn_transform_ztensor(&hidden_biases, hidden_biases_data_z, hidden_biases_data_r, hidden_biases_data_h); assert(status == ZDNN_OK); /*********************************************************************** * Create output zTensor ***********************************************************************/ // get only the last timestep zdnn_tensor_desc hn_pre_tfrmd_desc, hn_tfrmd_desc; zdnn_ztensor hn_output_ztensor; zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &hn_pre_tfrmd_desc, 1, 1, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&hn_pre_tfrmd_desc, &hn_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hn_pre_tfrmd_desc, &hn_tfrmd_desc, &hn_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Call the AIU ***********************************************************************/ void *work_area = NULL; status = zdnn_gru(&input, &h0, &weights, &biases, &hidden_weights, &hidden_biases, dir, work_area, &hn_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Output and Cleanup ***********************************************************************/ uint64_t hn_data_size = num_batches * num_hidden * element_size; void *hn_output_data = malloc(hn_data_size); status = zdnn_transform_origtensor(&hn_output_ztensor, hn_output_data); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&input); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&h0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output_ztensor); assert(status == ZDNN_OK); free(input_data); free(hidden_state_data); free(weights_data_z); free(weights_data_r); free(weights_data_h); free(hidden_weights_data_z); free(hidden_weights_data_r); free(hidden_weights_data_h); free(biases_data_z); free(biases_data_r); free(biases_data_h); free(hidden_biases_data_z); free(hidden_biases_data_r); free(hidden_biases_data_h); free(hn_output_data); } �������������������������������������������������������������������������������������zDNN-1.0.1/samples/rnn_lstm_bidir.c�����������������������������������������������������������������0000664�0000000�0000000�00000031516�14364043643�0017154�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // Sample: LSTM BI-DIR int main(int argc, char *argv[]) { zdnn_status status; #ifdef STATIC_LIB zdnn_init(); #endif /*********************************************************************** * * LSTM (BI-DIR): * * INPUTS -------------------------------------------------------------- * input | ZDNN_3DS | (num_timesteps, num_batches, num_features) * h0 | ZDNN_3DS | (2, num_batches, num_hidden) * c0 | ZDNN_3DS | (2, num_batches, num_hidden) * weights | ZDNN_3DS | (2, num_features, num_hidden) * biases | ZDNN_2DS | (2, num_hidden) * hidden_weights | ZDNN_3DS | (2, num_hidden, num_hidden) * hidden_biases | ZDNN_2DS | (2, num_hidden) * * OUTPUTS ------------------------------------------------------------- * hn_output | ZDNN_4DS | (num_timesteps, 2, num_batches, num_hidden) * | | or (1, 2, num_batches, num_hidden) * cf_output | ZDNN_4DS | (1, 2, num_batches, num_hidden) ***********************************************************************/ /*********************************************************************** * Create input zTensor ***********************************************************************/ zdnn_tensor_desc input_pre_tfrmd_desc, input_tfrmd_desc; zdnn_ztensor input; uint32_t num_timesteps = 5; uint32_t num_batches = 3; uint32_t num_features = 32; uint32_t num_hidden = 5; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes lstm_gru_direction dir = BIDIR; uint8_t num_dirs = 2; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &input_pre_tfrmd_desc, num_timesteps, num_batches, num_features); status = zdnn_generate_transformed_desc(&input_pre_tfrmd_desc, &input_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&input_pre_tfrmd_desc, &input_tfrmd_desc, &input); assert(status == ZDNN_OK); uint64_t input_data_size = num_timesteps * num_batches * num_features * element_size; void *input_data = malloc(input_data_size); status = zdnn_transform_ztensor(&input, input_data); assert(status == ZDNN_OK); /*********************************************************************** * Create initial hidden and cell state zTensors ***********************************************************************/ zdnn_tensor_desc h0c0_pre_tfrmd_desc, h0c0_tfrmd_desc; zdnn_ztensor h0, c0; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &h0c0_pre_tfrmd_desc, num_dirs, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &h0); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &c0); assert(status == ZDNN_OK); uint64_t h0c0_data_size = num_batches * num_hidden * element_size; void *hidden_state_data = malloc(h0c0_data_size); void *cell_state_data = malloc(h0c0_data_size); status = zdnn_transform_ztensor(&h0, hidden_state_data); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&c0, cell_state_data); assert(status == ZDNN_OK); /*********************************************************************** * Create input weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc weights_pre_tfrmd_desc, weights_tfrmd_desc; zdnn_ztensor weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &weights_pre_tfrmd_desc, num_dirs, num_features, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_NONE, &weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&weights_pre_tfrmd_desc, &weights_tfrmd_desc, &weights); assert(status == ZDNN_OK); uint64_t weights_data_size = num_features * num_hidden * element_size; void *weights_data_f = malloc(weights_data_size); void *weights_data_i = malloc(weights_data_size); void *weights_data_c = malloc(weights_data_size); void *weights_data_o = malloc(weights_data_size); status = zdnn_transform_ztensor(&weights, weights_data_f, weights_data_i, weights_data_c, weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc biases_pre_tfrmd_desc, biases_tfrmd_desc; zdnn_ztensor biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_BIASES | PREV_LAYER_NONE, &biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&biases_pre_tfrmd_desc, &biases_tfrmd_desc, &biases); assert(status == ZDNN_OK); uint64_t biases_data_size = num_hidden * element_size; void *biases_data_f = malloc(biases_data_size); void *biases_data_i = malloc(biases_data_size); void *biases_data_c = malloc(biases_data_size); void *biases_data_o = malloc(biases_data_size); status = zdnn_transform_ztensor(&biases, biases_data_f, biases_data_i, biases_data_c, biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc hidden_weights_pre_tfrmd_desc, hidden_weights_tfrmd_desc; zdnn_ztensor hidden_weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &hidden_weights_pre_tfrmd_desc, num_dirs, num_hidden, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_WEIGHTS | PREV_LAYER_NONE, &hidden_weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hidden_weights_pre_tfrmd_desc, &hidden_weights_tfrmd_desc, &hidden_weights); assert(status == ZDNN_OK); uint64_t hidden_weights_data_size = num_hidden * num_hidden * element_size; void *hidden_weights_data_f = malloc(hidden_weights_data_size); void *hidden_weights_data_i = malloc(hidden_weights_data_size); void *hidden_weights_data_c = malloc(hidden_weights_data_size); void *hidden_weights_data_o = malloc(hidden_weights_data_size); status = zdnn_transform_ztensor(&hidden_weights, hidden_weights_data_f, hidden_weights_data_i, hidden_weights_data_c, hidden_weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc hidden_biases_pre_tfrmd_desc, hidden_biases_tfrmd_desc; zdnn_ztensor hidden_biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &hidden_biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_BIASES | PREV_LAYER_NONE, &hidden_biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc( &hidden_biases_pre_tfrmd_desc, &hidden_biases_tfrmd_desc, &hidden_biases); assert(status == ZDNN_OK); uint64_t hidden_biases_data_size = num_hidden * element_size; void *hidden_biases_data_f = malloc(hidden_biases_data_size); void *hidden_biases_data_i = malloc(hidden_biases_data_size); void *hidden_biases_data_c = malloc(hidden_biases_data_size); void *hidden_biases_data_o = malloc(hidden_biases_data_size); status = zdnn_transform_ztensor(&hidden_biases, hidden_biases_data_f, hidden_biases_data_i, hidden_biases_data_c, hidden_biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create output zTensor ***********************************************************************/ zdnn_tensor_desc hn_pre_tfrmd_desc, hn_tfrmd_desc, cf_pre_tfrmd_desc, cf_tfrmd_desc; zdnn_ztensor hn_output_ztensor, cf_output_ztensor; zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &hn_pre_tfrmd_desc, num_timesteps, 2, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&hn_pre_tfrmd_desc, &hn_tfrmd_desc); assert(status == ZDNN_OK); zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &cf_pre_tfrmd_desc, 1, 2, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&cf_pre_tfrmd_desc, &cf_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hn_pre_tfrmd_desc, &hn_tfrmd_desc, &hn_output_ztensor); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&cf_pre_tfrmd_desc, &cf_tfrmd_desc, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Call the AIU ***********************************************************************/ void *work_area = NULL; status = zdnn_lstm(&input, &h0, &c0, &weights, &biases, &hidden_weights, &hidden_biases, dir, work_area, &hn_output_ztensor, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Output and Cleanup ***********************************************************************/ uint64_t hn_data_size = num_timesteps * 2 * num_batches * num_hidden * element_size; uint64_t cf_data_size = 2 * num_batches * num_hidden * element_size; void *hn_output_data = malloc(hn_data_size); void *cf_output_data = malloc(cf_data_size); status = zdnn_transform_origtensor(&hn_output_ztensor, hn_output_data); assert(status == ZDNN_OK); status = zdnn_transform_origtensor(&cf_output_ztensor, cf_output_data); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&input); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&h0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&c0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output_ztensor); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&cf_output_ztensor); assert(status == ZDNN_OK); free(input_data); free(hidden_state_data); free(cell_state_data); free(weights_data_f); free(weights_data_i); free(weights_data_c); free(weights_data_o); free(hidden_weights_data_f); free(hidden_weights_data_i); free(hidden_weights_data_c); free(hidden_weights_data_o); free(biases_data_f); free(biases_data_i); free(biases_data_c); free(biases_data_o); free(hidden_biases_data_f); free(hidden_biases_data_i); free(hidden_biases_data_c); free(hidden_biases_data_o); free(hn_output_data); free(cf_output_data); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/rnn_lstm_fwd.c�������������������������������������������������������������������0000664�0000000�0000000�00000031041�14364043643�0016634�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // Sample: LSTM int main(int argc, char *argv[]) { zdnn_status status; #ifdef STATIC_LIB zdnn_init(); #endif /*********************************************************************** * * LSTM (FWD/BWD): * * INPUTS -------------------------------------------------------------- * input | ZDNN_3DS | (num_timesteps, num_batches, num_features) * h0 | ZDNN_3DS | (1, num_batches, num_hidden) * c0 | ZDNN_3DS | (1, num_batches, num_hidden) * weights | ZDNN_3DS | (1, num_features, num_hidden) * biases | ZDNN_2DS | (1, num_hidden) * hidden_weights | ZDNN_3DS | (1, num_hidden, num_hidden) * hidden_biases | ZDNN_2DS | (1, num_hidden) * * OUTPUTS ------------------------------------------------------------- * hn_output | ZDNN_4DS | (num_timesteps, 1, num_batches, num_hidden) * | | or (1, 1, num_batches, num_hidden) * cf_output | ZDNN_4DS | (1, 1, num_batches, num_hidden) ***********************************************************************/ /*********************************************************************** * Create input zTensor ***********************************************************************/ zdnn_tensor_desc input_pre_tfrmd_desc, input_tfrmd_desc; zdnn_ztensor input; uint32_t num_timesteps = 5; uint32_t num_batches = 3; uint32_t num_features = 32; uint32_t num_hidden = 5; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes lstm_gru_direction dir = FWD; uint8_t num_dirs = 1; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &input_pre_tfrmd_desc, num_timesteps, num_batches, num_features); status = zdnn_generate_transformed_desc(&input_pre_tfrmd_desc, &input_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&input_pre_tfrmd_desc, &input_tfrmd_desc, &input); assert(status == ZDNN_OK); uint64_t input_data_size = num_timesteps * num_batches * num_features * element_size; void *input_data = malloc(input_data_size); status = zdnn_transform_ztensor(&input, input_data); assert(status == ZDNN_OK); /*********************************************************************** * Create initial hidden and cell state zTensors ***********************************************************************/ zdnn_tensor_desc h0c0_pre_tfrmd_desc, h0c0_tfrmd_desc; zdnn_ztensor h0, c0; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &h0c0_pre_tfrmd_desc, num_dirs, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &h0); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &c0); assert(status == ZDNN_OK); uint64_t h0c0_data_size = num_batches * num_hidden * element_size; void *hidden_state_data = malloc(h0c0_data_size); void *cell_state_data = malloc(h0c0_data_size); status = zdnn_transform_ztensor(&h0, hidden_state_data); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&c0, cell_state_data); assert(status == ZDNN_OK); /*********************************************************************** * Create input weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc weights_pre_tfrmd_desc, weights_tfrmd_desc; zdnn_ztensor weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &weights_pre_tfrmd_desc, num_dirs, num_features, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_NONE, &weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&weights_pre_tfrmd_desc, &weights_tfrmd_desc, &weights); assert(status == ZDNN_OK); uint64_t weights_data_size = num_features * num_hidden * element_size; void *weights_data_f = malloc(weights_data_size); void *weights_data_i = malloc(weights_data_size); void *weights_data_c = malloc(weights_data_size); void *weights_data_o = malloc(weights_data_size); status = zdnn_transform_ztensor(&weights, weights_data_f, weights_data_i, weights_data_c, weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc biases_pre_tfrmd_desc, biases_tfrmd_desc; zdnn_ztensor biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_BIASES | PREV_LAYER_NONE, &biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&biases_pre_tfrmd_desc, &biases_tfrmd_desc, &biases); assert(status == ZDNN_OK); uint64_t biases_data_size = num_hidden * element_size; void *biases_data_f = malloc(biases_data_size); void *biases_data_i = malloc(biases_data_size); void *biases_data_c = malloc(biases_data_size); void *biases_data_o = malloc(biases_data_size); status = zdnn_transform_ztensor(&biases, biases_data_f, biases_data_i, biases_data_c, biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc hidden_weights_pre_tfrmd_desc, hidden_weights_tfrmd_desc; zdnn_ztensor hidden_weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &hidden_weights_pre_tfrmd_desc, num_dirs, num_hidden, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_WEIGHTS | PREV_LAYER_NONE, &hidden_weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hidden_weights_pre_tfrmd_desc, &hidden_weights_tfrmd_desc, &hidden_weights); assert(status == ZDNN_OK); uint64_t hidden_weights_data_size = num_hidden * num_hidden * element_size; void *hidden_weights_data_f = malloc(hidden_weights_data_size); void *hidden_weights_data_i = malloc(hidden_weights_data_size); void *hidden_weights_data_c = malloc(hidden_weights_data_size); void *hidden_weights_data_o = malloc(hidden_weights_data_size); status = zdnn_transform_ztensor(&hidden_weights, hidden_weights_data_f, hidden_weights_data_i, hidden_weights_data_c, hidden_weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc hidden_biases_pre_tfrmd_desc, hidden_biases_tfrmd_desc; zdnn_ztensor hidden_biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &hidden_biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_BIASES | PREV_LAYER_NONE, &hidden_biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc( &hidden_biases_pre_tfrmd_desc, &hidden_biases_tfrmd_desc, &hidden_biases); assert(status == ZDNN_OK); uint64_t hidden_biases_data_size = num_hidden * element_size; void *hidden_biases_data_f = malloc(hidden_biases_data_size); void *hidden_biases_data_i = malloc(hidden_biases_data_size); void *hidden_biases_data_c = malloc(hidden_biases_data_size); void *hidden_biases_data_o = malloc(hidden_biases_data_size); status = zdnn_transform_ztensor(&hidden_biases, hidden_biases_data_f, hidden_biases_data_i, hidden_biases_data_c, hidden_biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create output zTensor ***********************************************************************/ // get only the last timestep, thus hn and cf can share descriptor zdnn_tensor_desc hncf_pre_tfrmd_desc, hncf_tfrmd_desc; zdnn_ztensor hn_output_ztensor, cf_output_ztensor; zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &hncf_pre_tfrmd_desc, 1, 1, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&hncf_pre_tfrmd_desc, &hncf_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hncf_pre_tfrmd_desc, &hncf_tfrmd_desc, &hn_output_ztensor); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hncf_pre_tfrmd_desc, &hncf_tfrmd_desc, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Call the AIU ***********************************************************************/ void *work_area = NULL; status = zdnn_lstm(&input, &h0, &c0, &weights, &biases, &hidden_weights, &hidden_biases, dir, work_area, &hn_output_ztensor, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Output and Cleanup ***********************************************************************/ uint64_t hncf_data_size = num_batches * num_hidden * element_size; void *hn_output_data = malloc(hncf_data_size); void *cf_output_data = malloc(hncf_data_size); status = zdnn_transform_origtensor(&hn_output_ztensor, hn_output_data); assert(status == ZDNN_OK); status = zdnn_transform_origtensor(&cf_output_ztensor, cf_output_data); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&input); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&h0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&c0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output_ztensor); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&cf_output_ztensor); assert(status == ZDNN_OK); free(input_data); free(hidden_state_data); free(cell_state_data); free(weights_data_f); free(weights_data_i); free(weights_data_c); free(weights_data_o); free(hidden_weights_data_f); free(hidden_weights_data_i); free(hidden_weights_data_c); free(hidden_weights_data_o); free(biases_data_f); free(biases_data_i); free(biases_data_c); free(biases_data_o); free(hidden_biases_data_f); free(hidden_biases_data_i); free(hidden_biases_data_c); free(hidden_biases_data_o); free(hn_output_data); free(cf_output_data); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/rnn_lstm_multi_layers.c����������������������������������������������������������0000664�0000000�0000000�00000033347�14364043643�0020600�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" void do_bidir_layer(zdnn_ztensor *input, uint32_t num_hidden, zdnn_ztensor *hn_output, bool is_prev_layer_bidir) { zdnn_status status; uint32_t num_batches = input->pre_transformed_desc->dim2; // if input is bidir output from previous layer then number of features for // this layer is 2x of hidden-state size (dim1) of the previous layer uint32_t num_features = input->pre_transformed_desc->dim1 * (is_prev_layer_bidir ? 2 : 1); zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes lstm_gru_direction dir = BIDIR; uint8_t num_dirs = 2; /*********************************************************************** * Create initial hidden and cell state zTensors ***********************************************************************/ zdnn_tensor_desc h0c0_pre_tfrmd_desc, h0c0_tfrmd_desc; zdnn_ztensor h0, c0; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &h0c0_pre_tfrmd_desc, num_dirs, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &h0); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&h0c0_pre_tfrmd_desc, &h0c0_tfrmd_desc, &c0); assert(status == ZDNN_OK); uint64_t h0c0_data_size = num_batches * num_hidden * element_size; void *hidden_state_data = malloc(h0c0_data_size); void *cell_state_data = malloc(h0c0_data_size); status = zdnn_transform_ztensor(&h0, hidden_state_data); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&c0, cell_state_data); assert(status == ZDNN_OK); /*********************************************************************** * Create input weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc weights_pre_tfrmd_desc, weights_tfrmd_desc; zdnn_ztensor weights; // if using previous layer bidir output as input then number of features of // this layer is zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &weights_pre_tfrmd_desc, num_dirs, num_features, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_WEIGHTS | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI), &weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&weights_pre_tfrmd_desc, &weights_tfrmd_desc, &weights); assert(status == ZDNN_OK); uint64_t weights_data_size = num_features * num_hidden * element_size; void *weights_data_f = malloc(weights_data_size); void *weights_data_i = malloc(weights_data_size); void *weights_data_c = malloc(weights_data_size); void *weights_data_o = malloc(weights_data_size); status = zdnn_transform_ztensor(&weights, weights_data_f, weights_data_i, weights_data_c, weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc biases_pre_tfrmd_desc, biases_tfrmd_desc; zdnn_ztensor biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_BIASES | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI), &biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&biases_pre_tfrmd_desc, &biases_tfrmd_desc, &biases); assert(status == ZDNN_OK); uint64_t biases_data_size = num_hidden * element_size; void *biases_data_f = malloc(biases_data_size); void *biases_data_i = malloc(biases_data_size); void *biases_data_c = malloc(biases_data_size); void *biases_data_o = malloc(biases_data_size); status = zdnn_transform_ztensor(&biases, biases_data_f, biases_data_i, biases_data_c, biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden weights zTensor * Resultant zTensor is concatenated ***********************************************************************/ zdnn_tensor_desc hidden_weights_pre_tfrmd_desc, hidden_weights_tfrmd_desc; zdnn_ztensor hidden_weights; zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &hidden_weights_pre_tfrmd_desc, num_dirs, num_hidden, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_weights_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_WEIGHTS | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI), &hidden_weights_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hidden_weights_pre_tfrmd_desc, &hidden_weights_tfrmd_desc, &hidden_weights); assert(status == ZDNN_OK); uint64_t hidden_weights_data_size = num_hidden * num_hidden * element_size; void *hidden_weights_data_f = malloc(hidden_weights_data_size); void *hidden_weights_data_i = malloc(hidden_weights_data_size); void *hidden_weights_data_c = malloc(hidden_weights_data_size); void *hidden_weights_data_o = malloc(hidden_weights_data_size); status = zdnn_transform_ztensor(&hidden_weights, hidden_weights_data_f, hidden_weights_data_i, hidden_weights_data_c, hidden_weights_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create hidden biases zTensors * Resultant zTensors are concatenated ***********************************************************************/ zdnn_tensor_desc hidden_biases_pre_tfrmd_desc, hidden_biases_tfrmd_desc; zdnn_ztensor hidden_biases; zdnn_init_pre_transformed_desc(ZDNN_2DS, type, &hidden_biases_pre_tfrmd_desc, num_dirs, num_hidden); status = zdnn_generate_transformed_desc_concatenated( &hidden_biases_pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_BIASES | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI), &hidden_biases_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc( &hidden_biases_pre_tfrmd_desc, &hidden_biases_tfrmd_desc, &hidden_biases); assert(status == ZDNN_OK); uint64_t hidden_biases_data_size = num_hidden * element_size; void *hidden_biases_data_f = malloc(hidden_biases_data_size); void *hidden_biases_data_i = malloc(hidden_biases_data_size); void *hidden_biases_data_c = malloc(hidden_biases_data_size); void *hidden_biases_data_o = malloc(hidden_biases_data_size); status = zdnn_transform_ztensor(&hidden_biases, hidden_biases_data_f, hidden_biases_data_i, hidden_biases_data_c, hidden_biases_data_o); assert(status == ZDNN_OK); /*********************************************************************** * Create cf output zTensor ***********************************************************************/ zdnn_tensor_desc cf_pre_tfrmd_desc, cf_tfrmd_desc; zdnn_ztensor cf_output_ztensor; zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &cf_pre_tfrmd_desc, 1, 2, num_batches, num_hidden); status = zdnn_generate_transformed_desc(&cf_pre_tfrmd_desc, &cf_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&cf_pre_tfrmd_desc, &cf_tfrmd_desc, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Call the AIU ***********************************************************************/ void *work_area = NULL; status = zdnn_lstm(input, &h0, &c0, &weights, &biases, &hidden_weights, &hidden_biases, dir, work_area, hn_output, &cf_output_ztensor); assert(status == ZDNN_OK); /*********************************************************************** * Cleanup and Return ***********************************************************************/ status = zdnn_free_ztensor_buffer(&h0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&c0); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_weights); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hidden_biases); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&cf_output_ztensor); assert(status == ZDNN_OK); free(hidden_state_data); free(cell_state_data); free(weights_data_f); free(weights_data_i); free(weights_data_c); free(weights_data_o); free(hidden_weights_data_f); free(hidden_weights_data_i); free(hidden_weights_data_c); free(hidden_weights_data_o); free(biases_data_f); free(biases_data_i); free(biases_data_c); free(biases_data_o); free(hidden_biases_data_f); free(hidden_biases_data_i); free(hidden_biases_data_c); free(hidden_biases_data_o); } // Sample: LSTM multi-layer BIDIR int main(int argc, char *argv[]) { zdnn_status status; #ifdef STATIC_LIB zdnn_init(); #endif uint32_t num_hidden[2] = {5, 4}; /*********************************************************************** * Create input zTensor ***********************************************************************/ zdnn_tensor_desc input_pre_tfrmd_desc, input_tfrmd_desc; zdnn_ztensor input; uint32_t num_timesteps = 5; uint32_t num_batches = 3; uint32_t num_features = 32; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes zdnn_init_pre_transformed_desc(ZDNN_3DS, type, &input_pre_tfrmd_desc, num_timesteps, num_batches, num_features); status = zdnn_generate_transformed_desc(&input_pre_tfrmd_desc, &input_tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&input_pre_tfrmd_desc, &input_tfrmd_desc, &input); assert(status == ZDNN_OK); uint64_t input_data_size = num_timesteps * num_batches * num_features * element_size; void *input_data = malloc(input_data_size); status = zdnn_transform_ztensor(&input, input_data); assert(status == ZDNN_OK); /*********************************************************************** * Create 2 hn output zTensors ***********************************************************************/ zdnn_tensor_desc hn_pre_tfrmd_desc[2], hn_tfrmd_desc[2]; zdnn_ztensor hn_output[2]; for (int i = 0; i < 2; i++) { zdnn_init_pre_transformed_desc(ZDNN_4DS, type, &hn_pre_tfrmd_desc[i], num_timesteps, 2, num_batches, num_hidden[i]); status = zdnn_generate_transformed_desc(&hn_pre_tfrmd_desc[i], &hn_tfrmd_desc[i]); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&hn_pre_tfrmd_desc[i], &hn_tfrmd_desc[i], &hn_output[i]); assert(status == ZDNN_OK); } /*********************************************************************** * Do the layers ***********************************************************************/ // call the first layer with input, previous layer bidir = false, output goes // to hn_output[0] do_bidir_layer(&input, num_hidden[0], &hn_output[0], false); // call the second layer with hn_output[0] from layer 1, previous layer bidir // = true, output goes to hn_output[1] do_bidir_layer(&hn_output[0], num_hidden[1], &hn_output[1], true); /*********************************************************************** * Output and Cleanup ***********************************************************************/ void *hn_output_data[2]; for (int i = 0; i < 2; i++) { uint64_t hn_output_data_size = (uint64_t)num_timesteps * num_batches * num_hidden[i] * 2 * element_size; hn_output_data[i] = malloc(hn_output_data_size); status = zdnn_transform_origtensor(&hn_output[i], hn_output_data[i]); assert(status == ZDNN_OK); } status = zdnn_free_ztensor_buffer(&input); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output[0]); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&hn_output[1]); assert(status == ZDNN_OK); free(input_data); free(hn_output_data[0]); free(hn_output_data[1]); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/simple_add.c���������������������������������������������������������������������0000664�0000000�0000000�00000007007�14364043643�0016246�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // *************************************************************************** // Sample: // // Create 2 zTensors a and b, and add them together via zdnn_add() // *************************************************************************** int main(int argc, char *argv[]) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor_a; zdnn_ztensor ztensor_b; zdnn_ztensor ztensor_out; zdnn_status status; uint32_t dim_n = 1, dim_h = 32, dim_w = 32, dim_c = 3; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes uint64_t num_elements = dim_n * dim_h * dim_w * dim_c; #ifdef STATIC_LIB zdnn_init(); #endif // allocate tensor data storage void *data1 = malloc(num_elements * element_size); void *data2 = malloc(num_elements * element_size); void *data_out = malloc(num_elements * element_size); // read input_data // check status for AIU availability, supported ops, etc. here // status = zdnn_query(…); // set input tensor data to 0 to 127 sequentially and repeat for (uint64_t i = 0; i < num_elements; i++) { ((float *)data1)[i] = (float)(i & 0x7f); ((float *)data2)[i] = (float)(i & 0x7f); } zdnn_init_pre_transformed_desc(ZDNN_NHWC, type, &pre_tfrmd_desc, dim_n, dim_h, dim_w, dim_c); // generate transformed shape information status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); assert(status == ZDNN_OK); // initialize zTensors and allocate 4k-aligned storage via helper function status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor_a); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor_b); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor_out); assert(status == ZDNN_OK); // transform the feature tensor status = zdnn_transform_ztensor(&ztensor_a, data1); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&ztensor_b, data2); assert(status == ZDNN_OK); // perform element-wise add between the two input tensors status = zdnn_add(&ztensor_a, &ztensor_b, &ztensor_out); assert(status == ZDNN_OK); // transform resultant zTensor back to original data format status = zdnn_transform_origtensor(&ztensor_out, data_out); assert(status == ZDNN_OK); for (uint64_t i = 0; i < num_elements; i++) { printf("out element %" PRIu64 " %f\n", i, ((float *)data_out)[i]); } // Free zTensors status = zdnn_free_ztensor_buffer(&ztensor_a); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&ztensor_b); assert(status == ZDNN_OK); status = zdnn_free_ztensor_buffer(&ztensor_out); assert(status == ZDNN_OK); free(data1); free(data2); free(data_out); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/simple_concat_lstm.c�������������������������������������������������������������0000664�0000000�0000000�00000004524�14364043643�0020025�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // *************************************************************************** // Sample: // // CONCAT_LSTM usage // *************************************************************************** int main(int argc, char *argv[]) { zdnn_tensor_desc *pre_tfrmd_desc, *tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; uint32_t dim2 = 32, dim1 = 3; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes uint64_t num_elements = dim2 * dim1; #ifdef STATIC_LIB zdnn_init(); #endif void *data_forget = malloc(num_elements * element_size), *data_input = malloc(num_elements * element_size), *data_cell = malloc(num_elements * element_size), *data_output = malloc(num_elements * element_size); pre_tfrmd_desc = malloc(sizeof(zdnn_tensor_desc)); tfrmd_desc = malloc(sizeof(zdnn_tensor_desc)); zdnn_init_pre_transformed_desc(ZDNN_2DS, type, pre_tfrmd_desc, dim2, dim1); status = zdnn_generate_transformed_desc_concatenated(pre_tfrmd_desc, CONCAT_LSTM, tfrmd_desc); assert(status == ZDNN_OK); ztensor.pre_transformed_desc = pre_tfrmd_desc; ztensor.transformed_desc = tfrmd_desc; status = zdnn_allochelper_ztensor(&ztensor); assert(status == ZDNN_OK); // gate buffers must be supplied in Forget, Input, Cell, Output (FICO) order status = zdnn_transform_ztensor(&ztensor, data_forget, data_input, data_cell, data_output); assert(status == ZDNN_OK); free(pre_tfrmd_desc); free(tfrmd_desc); free(data_forget); free(data_input); free(data_cell); free(data_output); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/simple_heap.c��������������������������������������������������������������������0000664�0000000�0000000�00000003636�14364043643�0016437�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // *************************************************************************** // Sample: // // Descriptor allocation on heap // *************************************************************************** int main(int argc, char *argv[]) { zdnn_tensor_desc *pre_tfrmd_desc, *tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; uint32_t dim_n = 1, dim_h = 32, dim_w = 32, dim_c = 3; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes uint64_t num_elements = dim_n * dim_h * dim_w * dim_c; #ifdef STATIC_LIB zdnn_init(); #endif void *data = malloc(num_elements * element_size); pre_tfrmd_desc = malloc(sizeof(zdnn_tensor_desc)); tfrmd_desc = malloc(sizeof(zdnn_tensor_desc)); zdnn_init_pre_transformed_desc(ZDNN_NHWC, type, pre_tfrmd_desc, dim_n, dim_h, dim_w, dim_c); status = zdnn_generate_transformed_desc(pre_tfrmd_desc, tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(pre_tfrmd_desc, tfrmd_desc, &ztensor); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&ztensor, data); assert(status == ZDNN_OK); free(pre_tfrmd_desc); free(tfrmd_desc); free(data); } ��������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/simple_stack.c�������������������������������������������������������������������0000664�0000000�0000000�00000003425�14364043643�0016623�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // *************************************************************************** // Sample: // // Descriptor allocation on stack // *************************************************************************** int main(int argc, char *argv[]) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; uint32_t dim_n = 1, dim_h = 32, dim_w = 32, dim_c = 3; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes uint64_t num_elements = dim_n * dim_h * dim_w * dim_c; #ifdef STATIC_LIB zdnn_init(); #endif void *data = malloc(num_elements * element_size); zdnn_init_pre_transformed_desc(ZDNN_NHWC, type, &pre_tfrmd_desc, dim_n, dim_h, dim_w, dim_c); status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&ztensor, data); assert(status == ZDNN_OK); free(data); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/samples/stickify_unstickify.c������������������������������������������������������������0000664�0000000�0000000�00000003764�14364043643�0020250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // *************************************************************************** // Sample: // // Transform raw tensor data to zTensor, then transform the zTensor back // to original format // *************************************************************************** int main(int argc, char *argv[]) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; uint32_t dim_n = 1, dim_h = 32, dim_w = 32, dim_c = 3; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes uint64_t num_elements = dim_n * dim_h * dim_w * dim_c; #ifdef STATIC_LIB zdnn_init(); #endif void *data = malloc(num_elements * element_size); void *data_out = malloc(num_elements * element_size); zdnn_init_pre_transformed_desc(ZDNN_NHWC, type, &pre_tfrmd_desc, dim_n, dim_h, dim_w, dim_c); status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&ztensor, data); assert(status == ZDNN_OK); status = zdnn_transform_origtensor(&ztensor, data_out); assert(status == ZDNN_OK); free(data); free(data_out); } ������������zDNN-1.0.1/samples/ztensor_reuse.c������������������������������������������������������������������0000664�0000000�0000000�00000004102�14364043643�0017045�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "zdnn.h" // *************************************************************************** // Sample: // // Transform 2 pieces of raw tensor data using the same zdnn_ztensor struct // *************************************************************************** int main(int argc, char *argv[]) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; uint32_t dim_n = 1, dim_h = 32, dim_w = 32, dim_c = 3; zdnn_data_types type = FP32; short element_size = 4; // size of each element in bytes uint64_t num_elements = dim_n * dim_h * dim_w * dim_c; #ifdef STATIC_LIB zdnn_init(); #endif void *data1 = malloc(num_elements * element_size); void *data2 = malloc(num_elements * element_size); zdnn_init_pre_transformed_desc(ZDNN_NHWC, type, &pre_tfrmd_desc, dim_n, dim_h, dim_w, dim_c); status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); assert(status == ZDNN_OK); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); assert(status == ZDNN_OK); status = zdnn_transform_ztensor(&ztensor, data1); assert(status == ZDNN_OK); zdnn_reset_ztensor(&ztensor); // essentially overwriting previous stickification buffer with data2's status = zdnn_transform_ztensor(&ztensor, data2); assert(status == ZDNN_OK); free(data1); free(data2); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/�����������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14364043643�0013473�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/Makefile���������������������������������������������������������������������������0000664�0000000�0000000�00000004550�14364043643�0015137�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. THIRDPARTY_ROOT = third_party UNITY_ROOT = $(THIRDPARTY_ROOT)/Unity OBJDIR := obj BINDIR := bin _dummy := $(shell mkdir -p $(OBJDIR); mkdir -p $(BINDIR)) include ../config.make INCDIR := $(CFLAGS_NOSEARCH) -I ../zdnn -I $(UNITY_ROOT)/src ifneq ($(CC),xlc) ifneq ($(no_rpath),1) LDFLAGS := $(LDFLAGS) -Wl,-rpath=\$$ORIGIN/../../zdnn/${SODIR} endif endif C_TEST_SUPPORTFILES := $(UNITY_ROOT)/src/unity.c testsupport.c $(wildcard common_*.c) CXX_TEST_SUPPORTFILES := $(wildcard *.cpp) TEST_FILES := $(wildcard testDriver*.c) C_TEST_SUPPORTOBJ := $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(C_TEST_SUPPORTFILES))) CXX_TEST_SUPPORTOBJ := $(patsubst %.cpp,$(OBJDIR)/%.o,$(notdir $(CXX_TEST_SUPPORTFILES))) TEST_OBJ := $(patsubst %.c,$(OBJDIR)/%.o,$(TEST_FILES)) TEST_BINARIES := $(patsubst %.c,$(BINDIR)/%,$(TEST_FILES)) TEST_RESULTS := $(patsubst %.c,$(BINDIR)/%.txt,$(TEST_FILES)) PARSED_RESULT:= `python3 resources/testresult_parser.py` all: test .PHONY: test test: $(TEST_RESULTS) $(TEST_BINARIES) $(TEST_OBJ) $(C_TEST_SUPPORTOBJ) $(CXX_TEST_SUPPORTOBJ) @echo $(ECHOFLAGS) ${PARSED_RESULT} # Compile $(OBJDIR)/%.o: $(UNITY_ROOT)/src/%.c $(CC) $(INCDIR) $(CFLAGS) -c -o $@ $< $(OBJDIR)/%.o: $(ARGTABLE3_ROOT)/src/%.c $(CC) $(INCDIR) $(CFLAGS) -c -o $@ $< $(OBJDIR)/%.o: %.c $(CC) $(INCDIR) $(CFLAGS) -c -o $@ $< $(OBJDIR)/%.o: %.cpp $(CXX) $(INCDIR) $(CXXFLAGS) -c -o $@ $< # Link $(BINDIR)/testDriver_%: $(OBJDIR)/testDriver_%.o $(C_TEST_SUPPORTOBJ) $(CXX_TEST_SUPPORTOBJ) $(CXX) $(INCDIR) $(CXXFLAGS) -o $@ $< $(C_TEST_SUPPORTOBJ) $(CXX_TEST_SUPPORTOBJ) $(LDFLAGS) $(LDFLAGS_TEST) # Run testcase $(BINDIR)/%.txt: $(BINDIR)/% -$(LD_PATH_VAR)=../zdnn/$(SODIR) ZDNN_LOGLEVEL=off ./$< > $@ .PHONY: clean clean: $(RM) $(OBJDIR)/* *~ core $(RM) $(BINDIR)/* *~ core ��������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/common_act.h�����������������������������������������������������������������������0000664�0000000�0000000�00000001473�14364043643�0015770�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TESTS_COMMON_ACT_H_ #define TESTS_COMMON_ACT_H_ #include "testsupport.h" #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #endif /* TESTS_COMMON_ACT_H_ */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/common_elwise.c��������������������������������������������������������������������0000664�0000000�0000000�00000027467�14364043643�0016517�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_elwise.h" /** * helper function to compute the natural log without using math.h */ float ln(float x) { float old_sum = 0.0; float xmlxpl = (x - 1) / (x + 1); float xmlxpl_2 = xmlxpl * xmlxpl; float denom = 1.0; float frac = xmlxpl; float term = frac; // denom start from 1.0 float sum = term; while (sum != old_sum) { old_sum = sum; denom += 2.0; frac *= xmlxpl_2; sum += frac / denom; } return 2.0 * sum; } /** * Helper function to compute output tensor values using elementwise * natural log */ void elwise_log(float input[], float output[], int num_elems, zdnn_data_types type) { for (int i = 0; i < num_elems; i++) { if (input[i] > 0) { switch (type) { case (BFLOAT): output[i] = ln(CLEANSE_BFLOAT(input[i])); break; case (FP16): output[i] = ln(CLEANSE_FP16(input[i])); break; case (FP32): output[i] = ln(CLEANSE_FP32(input[i])); break; default: break; } } } } /** * Helper function to compute output tensor values using elementwise * exponential */ void elwise_exp(float input[], float output[], int num_elems, zdnn_data_types type) { for (int i = 0; i < num_elems; i++) { switch (type) { case (BFLOAT): output[i] = exp(CLEANSE_BFLOAT(input[i])); break; case (FP16): output[i] = exp(CLEANSE_FP16(input[i])); break; case (FP32): output[i] = exp(CLEANSE_FP32(input[i])); break; default: break; } } } /** * Helper function to compute output tensor values using elementwise add */ void elwise_add(float input1[], float input2[], float output[], int num_elems, zdnn_data_types type) { for (int i = 0; i < num_elems; i++) { switch (type) { case (BFLOAT): output[i] = CLEANSE_BFLOAT(input1[i]) + CLEANSE_BFLOAT(input2[i]); break; case (FP16): output[i] = CLEANSE_FP16(input1[i]) + CLEANSE_FP16(input2[i]); break; case (FP32): output[i] = CLEANSE_FP32(input1[i]) + CLEANSE_FP32(input2[i]); break; default: break; } } } /** * Helper function to compute output tensor values using elementwise sub */ void elwise_sub(float input1[], float input2[], float output[], int num_elems, zdnn_data_types type) { for (int i = 0; i < num_elems; i++) { switch (type) { case (BFLOAT): output[i] = CLEANSE_BFLOAT(input1[i]) - CLEANSE_BFLOAT(input2[i]); break; case (FP16): output[i] = CLEANSE_FP16(input1[i]) - CLEANSE_FP16(input2[i]); break; case (FP32): output[i] = CLEANSE_FP32(input1[i]) - CLEANSE_FP32(input2[i]); break; default: break; } } } /** * Helper function to compute output tensor values using elementwise * division */ void elwise_div(float input1[], float input2[], float output[], int num_elems, zdnn_data_types type) { for (int i = 0; i < num_elems; i++) { switch (type) { case (BFLOAT): output[i] = CLEANSE_BFLOAT(input1[i]) / CLEANSE_BFLOAT(input2[i]); break; case (FP16): output[i] = CLEANSE_FP16(input1[i]) / CLEANSE_FP16(input2[i]); break; case (FP32): output[i] = CLEANSE_FP32(input1[i]) / CLEANSE_FP32(input2[i]); break; default: break; } } } /** * Helper function to compute output tensor values using elementwise * multiplication */ void elwise_mul(float input1[], float input2[], float output[], int num_elems, zdnn_data_types type) { for (int i = 0; i < num_elems; i++) { switch (type) { case (BFLOAT): output[i] = CLEANSE_BFLOAT(input1[i]) * CLEANSE_BFLOAT(input2[i]); break; case (FP16): output[i] = CLEANSE_FP16(input1[i]) * CLEANSE_FP16(input2[i]); break; case (FP32): output[i] = CLEANSE_FP32(input1[i]) * CLEANSE_FP32(input2[i]); break; default: break; } } } /** * Helper function to compute output tensor values using elementwise * minimum */ void elwise_min(float input1[], float input2[], float output[], int num_elems, zdnn_data_types type) { for (int i = 0; i < num_elems; i++) { switch (type) { case (BFLOAT): output[i] = (input1[i] < input2[i]) ? CLEANSE_BFLOAT(input1[i]) : CLEANSE_BFLOAT(input2[i]); break; case (FP16): output[i] = (input1[i] < input2[i]) ? CLEANSE_FP16(input1[i]) : CLEANSE_FP16(input2[i]); break; case (FP32): output[i] = (input1[i] < input2[i]) ? CLEANSE_FP32(input1[i]) : CLEANSE_FP32(input2[i]); break; default: break; } } } /** * Helper function to compute output tensor values using elementwise * maximum */ void elwise_max(float input1[], float input2[], float output[], int num_elems, zdnn_data_types type) { for (int i = 0; i < num_elems; i++) { switch (type) { case (BFLOAT): output[i] = (input1[i] > input2[i]) ? CLEANSE_BFLOAT(input1[i]) : CLEANSE_BFLOAT(input2[i]); break; case (FP16): output[i] = (input1[i] > input2[i]) ? CLEANSE_FP16(input1[i]) : CLEANSE_FP16(input2[i]); break; case (FP32): output[i] = (input1[i] > input2[i]) ? CLEANSE_FP32(input1[i]) : CLEANSE_FP32(input2[i]); break; default: break; } } } /** * Helper function to run end to end elementwise tests that only have * one input tensor */ void test_elwise_api_1_input(uint32_t *shape, zdnn_data_layouts layout, float *input_values, nnpa_function_code function_code, zdnn_status expected_status) { // Create ztensor with input_values zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( shape, layout, test_datatype, NO_CONCAT, false, input_values); // Create output ztensor initialized to 0's zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( shape, layout, test_datatype, NO_CONCAT, true, ZERO_ARRAY); #ifdef TEST_AIU // Test requires AIU // calculate number of values in each tensor buffer for helper function uint64_t num_elements = get_num_elements(output_ztensor, ELEMENTS_PRE); // Values in ZDNN_NHWC order float expected_values[num_elements]; char api_method[AIU_METHOD_STR_LENGTH] = "zdnn_<tbd>"; zdnn_status status = GENERAL_TESTCASE_FAILURE; switch (function_code) { case NNPA_LOG: strcpy(api_method, "zdnn_log"); // Use public zDNN method to make NNPA call to AIU status = zdnn_log(input_ztensor, output_ztensor); // fill expected_values array with calculated expected values using // helper function elwise_log(input_values, expected_values, num_elements, test_datatype); break; case NNPA_EXP: strcpy(api_method, "zdnn_exp"); // Use public zDNN method to make NNPA call to AIU status = zdnn_exp(input_ztensor, output_ztensor); // fill expected_values array with calculated expected values using // helper function elwise_exp(input_values, expected_values, num_elements, test_datatype); break; default: TEST_FAIL_MESSAGE_FORMATTED("unsupported function_code: %d", function_code); break; } TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to %s() to returned status %08x but expected %08x", api_method, status, expected_status); // Only check expected values if expected status is ZDNN_OK if (expected_status == ZDNN_OK) { assert_ztensor_values(output_ztensor, false, expected_values); } #endif // Cleanup test tensor buffers free_ztensor_buffers(2, input_ztensor, output_ztensor); } /** * Helper function to run end to end elementwise tests that only have * two input tensors. This version allows the user to select * which type (FP32, Bfloat or FP16) they are testing. */ void test_elwise_api_2_inputs_adv(uint32_t *shape, zdnn_data_layouts layout, zdnn_data_types type, float *input1_values, float *input2_values, nnpa_function_code function_code, zdnn_status expected_status) { // Create ztensor with input1_values zdnn_ztensor *input1_ztensor = alloc_ztensor_with_values( shape, layout, type, NO_CONCAT, false, input1_values); // Create ztensor with input2_values zdnn_ztensor *input2_ztensor = alloc_ztensor_with_values( shape, layout, type, NO_CONCAT, false, input2_values); // Create output ztensor initialized to 0's zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( shape, layout, type, NO_CONCAT, true, ZERO_ARRAY); #ifdef TEST_AIU // Test requires AIU // calculate number of values in each tensor buffer for helper function uint64_t num_elements = get_num_elements(output_ztensor, ELEMENTS_PRE); // Values in ZDNN_NHWC order float expected_values[num_elements]; char api_method[AIU_METHOD_STR_LENGTH]; zdnn_status status = GENERAL_TESTCASE_FAILURE; // Use public zDNN method to make NNPA call to AIU // then fill expected_values array with calculated expected values using // helper function if we expect to succeed. Otherwise don't bother. #define CASE(func_code, func_name) \ case func_code: \ strcpy(api_method, "zdnn_" #func_name); \ status = zdnn_##func_name(input1_ztensor, input2_ztensor, output_ztensor); \ elwise_##func_name(input1_values, input2_values, expected_values, \ num_elements, type); \ break; switch (function_code) { CASE(NNPA_MAX, max) CASE(NNPA_MIN, min) CASE(NNPA_ADD, add) CASE(NNPA_SUB, sub) CASE(NNPA_MUL, mul) CASE(NNPA_DIV, div) default: TEST_FAIL_MESSAGE_FORMATTED("unsupported function_code: %d", function_code); break; } TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to %s() to returned status %08x but expected %08x", api_method, status, expected_status); // Only check expected values if expected status is ZDNN_OK if (expected_status == ZDNN_OK) { assert_ztensor_values(output_ztensor, false, expected_values); } #endif // Cleanup test tensor buffers free_ztensor_buffers(3, input1_ztensor, input2_ztensor, output_ztensor); } /** * Helper function to run end to end elementwise tests that only have * two input tensors. This version tests all supported data types by * looping over the supported data types (FP32, Bfloat and FP16) * calling test_elwise_ap_2_input_adv for each. */ void test_elwise_api_2_inputs(uint32_t *shape, zdnn_data_layouts layout, float *input1_values, float *input2_values, nnpa_function_code function_code, zdnn_status expected_status) { test_elwise_api_2_inputs_adv(shape, layout, test_datatype, input1_values, input2_values, function_code, expected_status); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/common_elwise.h��������������������������������������������������������������������0000664�0000000�0000000�00000003147�14364043643�0016511�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TESTS_COMMON_ELWISE_H_ #define TESTS_COMMON_ELWISE_H_ #include "testsupport.h" #include <string.h> void test_elwise_api_1_input(uint32_t *shape, zdnn_data_layouts layout, float *input_values, nnpa_function_code function_code, zdnn_status expected_status); void test_elwise_api_2_inputs(uint32_t *shape, zdnn_data_layouts layout, float *input1_values, float *input2_values, nnpa_function_code function_code, zdnn_status expected_status); void test_elwise_api_2_inputs_adv(uint32_t *shape, zdnn_data_layouts layout, zdnn_data_types type, float *input1_values, float *input2_values, nnpa_function_code function_code, zdnn_status expected_status); #endif /* TESTS_COMMON_ELWISE_H_ */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/common_pool.c����������������������������������������������������������������������0000664�0000000�0000000�00000007134�14364043643�0016165�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_pool.h" /// Call public API and checks returned status and values matches expected. /// /// \return nothing but throws test failure if actual status status doesn't /// match expected. An error is also thrown if expected status is ZDNN_OK but /// actual output values to not match expected input values. /// void test_pool_function(nnpa_function_code function_code, uint32_t *input_shape, zdnn_data_layouts input_layout, bool repeat_first_input_value, float *input_values, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, uint32_t *output_shape, zdnn_data_layouts output_layout, zdnn_status expected_status, bool repeat_first_expected_value, float *expected_values) { // Test requires AIU #ifdef TEST_AIU // Create input and output ztensors zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_shape, input_layout, test_datatype, NO_CONCAT, repeat_first_input_value, input_values); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_shape, output_layout, test_datatype, NO_CONCAT, true, ZERO_ARRAY); char api_method[AIU_METHOD_STR_LENGTH] = "zdnn_<tbd>"; zdnn_status status = GENERAL_TESTCASE_FAILURE; // Call public NNPA method switch (function_code) { case NNPA_AVGPOOL2D: strcpy(api_method, "zdnn_avgpool2d"); status = zdnn_avgpool2d(input_ztensor, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_ztensor); break; case NNPA_MAXPOOL2D: strcpy(api_method, "zdnn_maxpool2d"); status = zdnn_maxpool2d(input_ztensor, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_ztensor); break; default: TEST_FAIL_MESSAGE_FORMATTED("unsupported function_code: %d", function_code); break; } // Assert returned status matches expected TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to %s() to returned status %08x \"%s\" but expected %08x \"%s\"", api_method, status, zdnn_get_status_message(status), expected_status, zdnn_get_status_message(expected_status)); fp_tolerance *tol = NULL; switch (output_ztensor->pre_transformed_desc->type) { case BFLOAT: tol = &tol_bfloat; break; case FP16: tol = &tol_fp16; break; case FP32: tol = &tol_fp32; break; default: break; // should never get here } // If expected status is ZDNN_OK, assert output values matches expected if (expected_status == ZDNN_OK) { assert_ztensor_values_adv(output_ztensor, repeat_first_expected_value, expected_values, *tol); } // Cleanup test ztensors free_ztensor_buffers(2, input_ztensor, output_ztensor); #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/common_pool.h����������������������������������������������������������������������0000664�0000000�0000000�00000003353�14364043643�0016171�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TESTS_COMMON_POOL_H_ #define TESTS_COMMON_POOL_H_ #include "testsupport.h" #include <string.h> // Restrictions placed on pooling ops. If they're changed, update the API // documentation for all pool (avg, max, meanreduce2d) ops! #define MAXIMUM_POOL_ZERO_STRIDES_KERNEL_SIZE 1024 #define MAXIMUM_POOL_NONZERO_STRIDES_HEIGHT_WIDTH 1024 #define MAXIMUM_POOL_NONZERO_STRIDES_KERNEL_SIZE 64 #define MAXIMUM_POOL_NONZERO_STRIDES_STRIDE_SIZE 30 void test_pool_function(nnpa_function_code function_code, uint32_t *input_shape, zdnn_data_layouts input_layout, bool repeat_first_input_value, float *input_values, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, uint32_t *output_shape, zdnn_data_layouts output_layout, zdnn_status expected_status, bool repeat_first_expected_value, float *expected_values); #endif /* TESTS_COMMON_POOL_H_ */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/common_rnn.c�����������������������������������������������������������������������0000664�0000000�0000000�00000027655�14364043643�0016023�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_rnn.h" #include <stdlib.h> #include <string.h> #include <strings.h> /// Returns the size in bytes required for a RNN work_area buffer. /// /// \param[in] rnn_layer RNN layer type (ie LSTM or GRU) /// \param[in] batch_size batch size for the RNN /// \param[in] num_timesteps number of timesteps in the RNN /// \param[in] hidden_state_size number of hidden states in the RNN /// /// \return number of bytes required for work_area based on RNN values or /// throws a test failure. /// size_t calc_rnn_work_area_size(uint8_t function_code, uint32_t batch_size, uint32_t num_timesteps, uint32_t hidden_state_size, lstm_gru_direction direction) { uint32_t padded_hidden_state_size = CEIL(hidden_state_size, 64) * 64 * 4; uint32_t num_gates = get_func_code_num_gates(function_code); zdnn_data_layouts layout = 0; if (function_code == NNPA_LSTMACT) { layout = ZDNN_4D; } else if (function_code == NNPA_GRUACT) { layout = ZDNN_3D; } else { TEST_FAIL_MESSAGE_FORMATTED("NNPA function code %d is not supported.", function_code); } // Initialize descs for work area zdnn_tensor_desc fused_desc, bias_add_desc, c_desc; init_transformed_desc(layout, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &fused_desc, num_timesteps, 1, batch_size, padded_hidden_state_size); init_transformed_desc(layout, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &bias_add_desc, num_gates, 1, batch_size, hidden_state_size); init_transformed_desc(layout, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &c_desc, 2, 1, batch_size, hidden_state_size); size_t work_area_size = zdnn_getsize_ztensor(&fused_desc) + zdnn_getsize_ztensor(&bias_add_desc); if (function_code == NNPA_LSTMACT) { work_area_size += zdnn_getsize_ztensor(&c_desc); } if (direction == BIDIR) { work_area_size *= 2; } return work_area_size; } /// Allocates a 4k aligned work area buffer based on the given size and returns /// a pointer to the memory. /// /// \param[in] work_area_size size in bytes required for the work_] area /// /// \return pointer to the work area buffer or throws test failure /// void *alloc_rnn_work_area(size_t work_area_size) { void *work_area = NULL; if (!(work_area = malloc_aligned_4k(work_area_size))) { TEST_FAIL_MESSAGE_FORMATTED("malloc_aligned_4k (%zu) failed", work_area_size); } memset(work_area, 0, work_area_size); return work_area; } /// Call public API and checks returned status matches expected status. If OK /// status expected, confirm actual output values match expected values. /// /// \param[in] rnn_layer Type of RNN layer (ie LSTM or GRU). For LSTM /// weights and biases will use all four gates values (FICO order) /// and c0 and cf inputs. For GRU weights and biases use the first /// three gate values (ZRH order). GRU ignores all g3 values and all /// c0 and cf related inputs. /// \param[in] ... shapes, layouts, and values to create required tensors. /// \param[in] direction RNN layer direction (ie FWD, BWD, BIDIR) /// \param[in] exp_status Expected status for the public API call /// /// \return nothing but throws test failure if values don't match /// expected or an unexpected failure prevents the test from completing. /// void test_zdnn_api_lstm_gru( uint8_t function_code, uint32_t *input_shape, zdnn_data_layouts input_layout, float *input_values, uint32_t *h0_shape, zdnn_data_layouts h0_layout, float *h0_values, uint32_t *c0_shape, zdnn_data_layouts c0_layout, float *c0_values, uint32_t *input_weights_shape, zdnn_data_layouts input_weights_layout, float *input_weights_g0_values, float *input_weights_g1_values, float *input_weights_g2_values, float *input_weights_g3_values, uint32_t *input_biases_shape, zdnn_data_layouts input_biases_layout, float *input_biases_g0_values, float *input_biases_g1_values, float *input_biases_g2_values, float *input_biases_g3_values, uint32_t *hidden_weights_shape, zdnn_data_layouts hidden_weights_layout, float *hidden_weights_g0_values, float *hidden_weights_g1_values, float *hidden_weights_g2_values, float *hidden_weights_g3_values, uint32_t *hidden_biases_shape, zdnn_data_layouts hidden_biases_layout, float *hidden_biases_g0_values, float *hidden_biases_g1_values, float *hidden_biases_g2_values, float *hidden_biases_g3_values, uint32_t *hn_out_shape, zdnn_data_layouts hn_out_layout, float *exp_hn_out_values, uint32_t *cf_out_shape, zdnn_data_layouts cf_out_layout, float *exp_cf_out_values, lstm_gru_direction direction, zdnn_status exp_status) { char api_method[AIU_METHOD_STR_LENGTH] = "zdnn_<tbd>"; if (function_code != NNPA_LSTMACT && function_code != NNPA_GRUACT) { TEST_FAIL_MESSAGE_FORMATTED("NNPA function code %d is not supported.", function_code); } // Run test for each pretransformed data type zdnn_ztensor *input, *h0, *c0, *weights, *biases, *hidden_weights, *hidden_biases; input = alloc_ztensor_with_values(input_shape, input_layout, test_datatype, NO_CONCAT, false, input_values); h0 = alloc_ztensor_with_values(h0_shape, h0_layout, test_datatype, NO_CONCAT, false, h0_values); if (function_code == NNPA_LSTMACT) { // Pass all four gate buffers (FICO) to alloc_ztensor weights = alloc_ztensor_with_values( input_weights_shape, input_weights_layout, test_datatype, RNN_TYPE_LSTM | PREV_LAYER_UNI | USAGE_WEIGHTS, false, input_weights_g0_values, input_weights_g1_values, input_weights_g2_values, input_weights_g3_values); biases = alloc_ztensor_with_values( input_biases_shape, input_biases_layout, test_datatype, RNN_TYPE_LSTM | USAGE_BIASES, false, input_biases_g0_values, input_biases_g1_values, input_biases_g2_values, input_biases_g3_values); hidden_weights = alloc_ztensor_with_values( hidden_weights_shape, hidden_weights_layout, test_datatype, RNN_TYPE_LSTM | USAGE_HIDDEN_WEIGHTS, false, hidden_weights_g0_values, hidden_weights_g1_values, hidden_weights_g2_values, hidden_weights_g3_values); hidden_biases = alloc_ztensor_with_values( hidden_biases_shape, hidden_biases_layout, test_datatype, RNN_TYPE_LSTM | USAGE_HIDDEN_BIASES, false, hidden_biases_g0_values, hidden_biases_g1_values, hidden_biases_g2_values, hidden_biases_g3_values); // Alloc c0 ztensor c0 = alloc_ztensor_with_values(c0_shape, c0_layout, test_datatype, NO_CONCAT, false, c0_values); } else { // Pass three gate buffers (ZRH) to alloc_ztensor, the fourth isn't used // in GRU. weights = alloc_ztensor_with_values( input_weights_shape, input_weights_layout, test_datatype, RNN_TYPE_GRU | PREV_LAYER_UNI | USAGE_WEIGHTS, false, input_weights_g0_values, input_weights_g1_values, input_weights_g2_values); biases = alloc_ztensor_with_values( input_biases_shape, input_biases_layout, test_datatype, RNN_TYPE_GRU | USAGE_BIASES, false, input_biases_g0_values, input_biases_g1_values, input_biases_g2_values); hidden_weights = alloc_ztensor_with_values( hidden_weights_shape, hidden_weights_layout, test_datatype, RNN_TYPE_GRU | USAGE_HIDDEN_WEIGHTS, false, hidden_weights_g0_values, hidden_weights_g1_values, hidden_weights_g2_values); hidden_biases = alloc_ztensor_with_values( hidden_biases_shape, hidden_biases_layout, test_datatype, RNN_TYPE_GRU | USAGE_HIDDEN_BIASES, false, hidden_biases_g0_values, hidden_biases_g1_values, hidden_biases_g2_values); c0 = NULL; // just so the compiler won't complain about uninitialized c0 } // Get some basic shape info from the shapes of the various inputs uint32_t batch_size = input->transformed_desc->dim2; uint32_t num_timesteps = input->transformed_desc->dim4; uint32_t hidden_state_size = h0->transformed_desc->dim1; // Run API once NULL work_area and again with work_area set. for (int work_area_pass = 0; work_area_pass < 2; work_area_pass++) { zdnn_ztensor *hn_out, *cf_out; hn_out = alloc_ztensor_with_values(hn_out_shape, hn_out_layout, test_datatype, NO_CONCAT, true, ZERO_ARRAY); size_t work_area_size = 0; void *work_area = NULL; void *zeroed_work_area = NULL; // Set work_area during second pass if (work_area_pass == 1) { work_area_size = calc_rnn_work_area_size(NNPA_LSTMACT, batch_size, num_timesteps, hidden_state_size, direction); work_area = alloc_rnn_work_area(work_area_size); zeroed_work_area = alloc_rnn_work_area(work_area_size); memset(zeroed_work_area, 0, work_area_size); } zdnn_status status = GENERAL_TESTCASE_FAILURE; // Call to correct API based on layer type if (function_code == NNPA_LSTMACT) { cf_out = alloc_ztensor_with_values(cf_out_shape, cf_out_layout, test_datatype, NO_CONCAT, true, ZERO_ARRAY); // Make API call and confirm status matches expected strcpy(api_method, "zdnn_lstm"); status = zdnn_lstm(input, h0, c0, weights, biases, hidden_weights, hidden_biases, direction, work_area, hn_out, cf_out); } else if (function_code == NNPA_GRUACT) { strcpy(api_method, "zdnn_gru"); status = zdnn_gru(input, h0, weights, biases, hidden_weights, hidden_biases, direction, work_area, hn_out); } TEST_ASSERT_MESSAGE_FORMATTED(status == exp_status, "work_area_pass %d call to %s() returned " "status %08x \"%s\" but expected %08x \"%s\"", work_area_pass, api_method, status, zdnn_get_status_message(status), exp_status, zdnn_get_status_message(exp_status)); // Check that work_area was written to on second pass if (work_area_pass == 1) { if (exp_status == ZDNN_OK && !memcmp(work_area, zeroed_work_area, work_area_size)) { TEST_FAIL_MESSAGE_FORMATTED( "%s() - expected work_area have been written to but it " "contains all zeros", __func__); } free_aligned_4k(work_area); free_aligned_4k(zeroed_work_area); } // Confirm per timestep output tensor values match expected values if (exp_status == ZDNN_OK) { assert_ztensor_values(hn_out, false, exp_hn_out_values); } free_ztensor_buffers(1, hn_out); // (LSTM only) Confirm final cell state tensor values match expected if (function_code == NNPA_LSTMACT) { if (exp_status == ZDNN_OK) { assert_ztensor_values(cf_out, false, exp_cf_out_values); } free_ztensor_buffers(1, cf_out); } } // end of work_area_pass loop // Free input tensors free_ztensor_buffers(6, input, h0, weights, biases, hidden_weights, hidden_biases); if (function_code == NNPA_LSTMACT) { free_ztensor_buffers(1, c0); } } �����������������������������������������������������������������������������������zDNN-1.0.1/tests/common_rnn.h�����������������������������������������������������������������������0000664�0000000�0000000�00000004113�14364043643�0016010�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TESTS_COMMON_RNN_H_ #define TESTS_COMMON_RNN_H_ #include "testsupport.h" void test_zdnn_api_lstm_gru( uint8_t function_code, uint32_t *input_shape, zdnn_data_layouts input_layout, float *input_values, uint32_t *h0_shape, zdnn_data_layouts h0_layout, float *h0_values, uint32_t *c0_shape, zdnn_data_layouts c0_layout, float *c0_values, uint32_t *input_weights_shape, zdnn_data_layouts input_weights_layout, float *input_weights_g0_values, float *input_weights_g1_values, float *input_weights_g2_values, float *input_weights_g3_values, uint32_t *input_biases_shape, zdnn_data_layouts input_biases_layout, float *input_biases_g0_values, float *input_biases_g1_values, float *input_biases_g2_values, float *input_biases_g3_values, uint32_t *hidden_weights_shape, zdnn_data_layouts hidden_weights_layout, float *hidden_weights_g0_values, float *hidden_weights_g1_values, float *hidden_weights_g2_values, float *hidden_weights_g3_values, uint32_t *hidden_biases_shape, zdnn_data_layouts hidden_biases_layout, float *hidden_biases_g0_values, float *hidden_biases_g1_values, float *hidden_biases_g2_values, float *hidden_biases_g3_values, uint32_t *hn_out_shape, zdnn_data_layouts hn_out_layout, float *exp_hn_out_values, uint32_t *cf_out_shape, zdnn_data_layouts cf_out_layout, float *exp_cf_out_values, lstm_gru_direction direction, zdnn_status exp_status); #endif /* TESTS_COMMON_RNN_H_ */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/�������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14364043643�0015505�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/������������������������������������������������������������0000775�0000000�0000000�00000000000�14364043643�0020155�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x31x64.txt������������������������������������������0000664�0000000�0000000�00000022225�14364043643�0023244�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x32x63.txt������������������������������������������0000664�0000000�0000000�00000022474�14364043643�0023252�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x32x64.txt������������������������������������������0000664�0000000�0000000�00000022725�14364043643�0023252�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 4094 �������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x32x65.txt������������������������������������������0000664�0000000�0000000�00000023165�14364043643�0023252�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 4096 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 4224 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 4352 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 4480 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 4608 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 4736 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 4864 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 4992 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 5120 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 5248 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 5376 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 5504 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 5632 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 5760 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 5888 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 6016 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 6144 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 6272 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 6400 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 6528 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 6656 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 6784 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 6912 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 7040 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 7168 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 7296 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 7424 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 7552 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 7680 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 7808 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 7936 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 4094 8064 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x33x64.txt������������������������������������������0000664�0000000�0000000�00000023425�14364043643�0023251�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 4094 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 4222 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x4x127.txt������������������������������������������0000664�0000000�0000000�00000004265�14364043643�0023250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 4224 4226 4228 4230 4232 4234 4236 4238 4240 4242 4244 4246 4248 4250 4252 4254 4256 4258 4260 4262 4264 4266 4268 4270 4272 4274 4276 4278 4280 4282 4284 4286 4288 4290 4292 4294 4296 4298 4300 4302 4304 4306 4308 4310 4312 4314 4316 4318 4320 4322 4324 4326 4328 4330 4332 4334 4336 4338 4340 4342 4344 4346 4348 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 4352 4354 4356 4358 4360 4362 4364 4366 4368 4370 4372 4374 4376 4378 4380 4382 4384 4386 4388 4390 4392 4394 4396 4398 4400 4402 4404 4406 4408 4410 4412 4414 4416 4418 4420 4422 4424 4426 4428 4430 4432 4434 4436 4438 4440 4442 4444 4446 4448 4450 4452 4454 4456 4458 4460 4462 4464 4466 4468 4470 4472 4474 4476 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 4480 4482 4484 4486 4488 4490 4492 4494 4496 4498 4500 4502 4504 4506 4508 4510 4512 4514 4516 4518 4520 4522 4524 4526 4528 4530 4532 4534 4536 4538 4540 4542 4544 4546 4548 4550 4552 4554 4556 4558 4560 4562 4564 4566 4568 4570 4572 4574 4576 4578 4580 4582 4584 4586 4588 4590 4592 4594 4596 4598 4600 4602 4604 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x4x128.txt������������������������������������������0000664�0000000�0000000�00000004311�14364043643�0023241�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 4222 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 4224 4226 4228 4230 4232 4234 4236 4238 4240 4242 4244 4246 4248 4250 4252 4254 4256 4258 4260 4262 4264 4266 4268 4270 4272 4274 4276 4278 4280 4282 4284 4286 4288 4290 4292 4294 4296 4298 4300 4302 4304 4306 4308 4310 4312 4314 4316 4318 4320 4322 4324 4326 4328 4330 4332 4334 4336 4338 4340 4342 4344 4346 4348 4350 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 4352 4354 4356 4358 4360 4362 4364 4366 4368 4370 4372 4374 4376 4378 4380 4382 4384 4386 4388 4390 4392 4394 4396 4398 4400 4402 4404 4406 4408 4410 4412 4414 4416 4418 4420 4422 4424 4426 4428 4430 4432 4434 4436 4438 4440 4442 4444 4446 4448 4450 4452 4454 4456 4458 4460 4462 4464 4466 4468 4470 4472 4474 4476 4478 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 4480 4482 4484 4486 4488 4490 4492 4494 4496 4498 4500 4502 4504 4506 4508 4510 4512 4514 4516 4518 4520 4522 4524 4526 4528 4530 4532 4534 4536 4538 4540 4542 4544 4546 4548 4550 4552 4554 4556 4558 4560 4562 4564 4566 4568 4570 4572 4574 4576 4578 4580 4582 4584 4586 4588 4590 4592 4594 4596 4598 4600 4602 4604 4606 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x4x129.txt������������������������������������������0000664�0000000�0000000�00000004335�14364043643�0023250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 4222 8192 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 4224 4226 4228 4230 4232 4234 4236 4238 4240 4242 4244 4246 4248 4250 4252 4254 4256 4258 4260 4262 4264 4266 4268 4270 4272 4274 4276 4278 4280 4282 4284 4286 4288 4290 4292 4294 4296 4298 4300 4302 4304 4306 4308 4310 4312 4314 4316 4318 4320 4322 4324 4326 4328 4330 4332 4334 4336 4338 4340 4342 4344 4346 4348 4350 8320 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 4352 4354 4356 4358 4360 4362 4364 4366 4368 4370 4372 4374 4376 4378 4380 4382 4384 4386 4388 4390 4392 4394 4396 4398 4400 4402 4404 4406 4408 4410 4412 4414 4416 4418 4420 4422 4424 4426 4428 4430 4432 4434 4436 4438 4440 4442 4444 4446 4448 4450 4452 4454 4456 4458 4460 4462 4464 4466 4468 4470 4472 4474 4476 4478 8448 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 4480 4482 4484 4486 4488 4490 4492 4494 4496 4498 4500 4502 4504 4506 4508 4510 4512 4514 4516 4518 4520 4522 4524 4526 4528 4530 4532 4534 4536 4538 4540 4542 4544 4546 4548 4550 4552 4554 4556 4558 4560 4562 4564 4566 4568 4570 4572 4574 4576 4578 4580 4582 4584 4586 4588 4590 4592 4594 4596 4598 4600 4602 4604 4606 8576 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x63x4.txt�������������������������������������������0000664�0000000�0000000�00000002304�14364043643�0023157�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 128 130 132 134 256 258 260 262 384 386 388 390 512 514 516 518 640 642 644 646 768 770 772 774 896 898 900 902 1024 1026 1028 1030 1152 1154 1156 1158 1280 1282 1284 1286 1408 1410 1412 1414 1536 1538 1540 1542 1664 1666 1668 1670 1792 1794 1796 1798 1920 1922 1924 1926 2048 2050 2052 2054 2176 2178 2180 2182 2304 2306 2308 2310 2432 2434 2436 2438 2560 2562 2564 2566 2688 2690 2692 2694 2816 2818 2820 2822 2944 2946 2948 2950 3072 3074 3076 3078 3200 3202 3204 3206 3328 3330 3332 3334 3456 3458 3460 3462 3584 3586 3588 3590 3712 3714 3716 3718 3840 3842 3844 3846 3968 3970 3972 3974 4096 4098 4100 4102 4224 4226 4228 4230 4352 4354 4356 4358 4480 4482 4484 4486 4608 4610 4612 4614 4736 4738 4740 4742 4864 4866 4868 4870 4992 4994 4996 4998 5120 5122 5124 5126 5248 5250 5252 5254 5376 5378 5380 5382 5504 5506 5508 5510 5632 5634 5636 5638 5760 5762 5764 5766 5888 5890 5892 5894 6016 6018 6020 6022 6144 6146 6148 6150 6272 6274 6276 6278 6400 6402 6404 6406 6528 6530 6532 6534 6656 6658 6660 6662 6784 6786 6788 6790 6912 6914 6916 6918 7040 7042 7044 7046 7168 7170 7172 7174 7296 7298 7300 7302 7424 7426 7428 7430 7552 7554 7556 7558 7680 7682 7684 7686 7808 7810 7812 7814 7936 7938 7940 7942 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x64x4.txt�������������������������������������������0000664�0000000�0000000�00000002330�14364043643�0023157�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 128 130 132 134 256 258 260 262 384 386 388 390 512 514 516 518 640 642 644 646 768 770 772 774 896 898 900 902 1024 1026 1028 1030 1152 1154 1156 1158 1280 1282 1284 1286 1408 1410 1412 1414 1536 1538 1540 1542 1664 1666 1668 1670 1792 1794 1796 1798 1920 1922 1924 1926 2048 2050 2052 2054 2176 2178 2180 2182 2304 2306 2308 2310 2432 2434 2436 2438 2560 2562 2564 2566 2688 2690 2692 2694 2816 2818 2820 2822 2944 2946 2948 2950 3072 3074 3076 3078 3200 3202 3204 3206 3328 3330 3332 3334 3456 3458 3460 3462 3584 3586 3588 3590 3712 3714 3716 3718 3840 3842 3844 3846 3968 3970 3972 3974 4096 4098 4100 4102 4224 4226 4228 4230 4352 4354 4356 4358 4480 4482 4484 4486 4608 4610 4612 4614 4736 4738 4740 4742 4864 4866 4868 4870 4992 4994 4996 4998 5120 5122 5124 5126 5248 5250 5252 5254 5376 5378 5380 5382 5504 5506 5508 5510 5632 5634 5636 5638 5760 5762 5764 5766 5888 5890 5892 5894 6016 6018 6020 6022 6144 6146 6148 6150 6272 6274 6276 6278 6400 6402 6404 6406 6528 6530 6532 6534 6656 6658 6660 6662 6784 6786 6788 6790 6912 6914 6916 6918 7040 7042 7044 7046 7168 7170 7172 7174 7296 7298 7300 7302 7424 7426 7428 7430 7552 7554 7556 7558 7680 7682 7684 7686 7808 7810 7812 7814 7936 7938 7940 7942 8064 8066 8068 8070 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x1x65x4.txt�������������������������������������������0000664�0000000�0000000�00000002354�14364043643�0023166�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 128 130 132 134 256 258 260 262 384 386 388 390 512 514 516 518 640 642 644 646 768 770 772 774 896 898 900 902 1024 1026 1028 1030 1152 1154 1156 1158 1280 1282 1284 1286 1408 1410 1412 1414 1536 1538 1540 1542 1664 1666 1668 1670 1792 1794 1796 1798 1920 1922 1924 1926 2048 2050 2052 2054 2176 2178 2180 2182 2304 2306 2308 2310 2432 2434 2436 2438 2560 2562 2564 2566 2688 2690 2692 2694 2816 2818 2820 2822 2944 2946 2948 2950 3072 3074 3076 3078 3200 3202 3204 3206 3328 3330 3332 3334 3456 3458 3460 3462 3584 3586 3588 3590 3712 3714 3716 3718 3840 3842 3844 3846 3968 3970 3972 3974 4096 4098 4100 4102 4224 4226 4228 4230 4352 4354 4356 4358 4480 4482 4484 4486 4608 4610 4612 4614 4736 4738 4740 4742 4864 4866 4868 4870 4992 4994 4996 4998 5120 5122 5124 5126 5248 5250 5252 5254 5376 5378 5380 5382 5504 5506 5508 5510 5632 5634 5636 5638 5760 5762 5764 5766 5888 5890 5892 5894 6016 6018 6020 6022 6144 6146 6148 6150 6272 6274 6276 6278 6400 6402 6404 6406 6528 6530 6532 6534 6656 6658 6660 6662 6784 6786 6788 6790 6912 6914 6916 6918 7040 7042 7044 7046 7168 7170 7172 7174 7296 7298 7300 7302 7424 7426 7428 7430 7552 7554 7556 7558 7680 7682 7684 7686 7808 7810 7812 7814 7936 7938 7940 7942 8064 8066 8068 8070 8192 8194 8196 8198 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x2x3x4.txt��������������������������������������������0000664�0000000�0000000�00000000144�14364043643�0023072�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 128 130 132 134 256 258 260 262 4096 4098 4100 4102 4224 4226 4228 4230 4352 4354 4356 4358 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x32x32x3.txt������������������������������������������0000664�0000000�0000000�00000044713�14364043643�0023250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 128 130 132 256 258 260 384 386 388 512 514 516 640 642 644 768 770 772 896 898 900 1024 1026 1028 1152 1154 1156 1280 1282 1284 1408 1410 1412 1536 1538 1540 1664 1666 1668 1792 1794 1796 1920 1922 1924 2048 2050 2052 2176 2178 2180 2304 2306 2308 2432 2434 2436 2560 2562 2564 2688 2690 2692 2816 2818 2820 2944 2946 2948 3072 3074 3076 3200 3202 3204 3328 3330 3332 3456 3458 3460 3584 3586 3588 3712 3714 3716 3840 3842 3844 3968 3970 3972 4096 4098 4100 4224 4226 4228 4352 4354 4356 4480 4482 4484 4608 4610 4612 4736 4738 4740 4864 4866 4868 4992 4994 4996 5120 5122 5124 5248 5250 5252 5376 5378 5380 5504 5506 5508 5632 5634 5636 5760 5762 5764 5888 5890 5892 6016 6018 6020 6144 6146 6148 6272 6274 6276 6400 6402 6404 6528 6530 6532 6656 6658 6660 6784 6786 6788 6912 6914 6916 7040 7042 7044 7168 7170 7172 7296 7298 7300 7424 7426 7428 7552 7554 7556 7680 7682 7684 7808 7810 7812 7936 7938 7940 8064 8066 8068 8192 8194 8196 8320 8322 8324 8448 8450 8452 8576 8578 8580 8704 8706 8708 8832 8834 8836 8960 8962 8964 9088 9090 9092 9216 9218 9220 9344 9346 9348 9472 9474 9476 9600 9602 9604 9728 9730 9732 9856 9858 9860 9984 9986 9988 10112 10114 10116 10240 10242 10244 10368 10370 10372 10496 10498 10500 10624 10626 10628 10752 10754 10756 10880 10882 10884 11008 11010 11012 11136 11138 11140 11264 11266 11268 11392 11394 11396 11520 11522 11524 11648 11650 11652 11776 11778 11780 11904 11906 11908 12032 12034 12036 12160 12162 12164 12288 12290 12292 12416 12418 12420 12544 12546 12548 12672 12674 12676 12800 12802 12804 12928 12930 12932 13056 13058 13060 13184 13186 13188 13312 13314 13316 13440 13442 13444 13568 13570 13572 13696 13698 13700 13824 13826 13828 13952 13954 13956 14080 14082 14084 14208 14210 14212 14336 14338 14340 14464 14466 14468 14592 14594 14596 14720 14722 14724 14848 14850 14852 14976 14978 14980 15104 15106 15108 15232 15234 15236 15360 15362 15364 15488 15490 15492 15616 15618 15620 15744 15746 15748 15872 15874 15876 16000 16002 16004 16128 16130 16132 16256 16258 16260 16384 16386 16388 16512 16514 16516 16640 16642 16644 16768 16770 16772 16896 16898 16900 17024 17026 17028 17152 17154 17156 17280 17282 17284 17408 17410 17412 17536 17538 17540 17664 17666 17668 17792 17794 17796 17920 17922 17924 18048 18050 18052 18176 18178 18180 18304 18306 18308 18432 18434 18436 18560 18562 18564 18688 18690 18692 18816 18818 18820 18944 18946 18948 19072 19074 19076 19200 19202 19204 19328 19330 19332 19456 19458 19460 19584 19586 19588 19712 19714 19716 19840 19842 19844 19968 19970 19972 20096 20098 20100 20224 20226 20228 20352 20354 20356 20480 20482 20484 20608 20610 20612 20736 20738 20740 20864 20866 20868 20992 20994 20996 21120 21122 21124 21248 21250 21252 21376 21378 21380 21504 21506 21508 21632 21634 21636 21760 21762 21764 21888 21890 21892 22016 22018 22020 22144 22146 22148 22272 22274 22276 22400 22402 22404 22528 22530 22532 22656 22658 22660 22784 22786 22788 22912 22914 22916 23040 23042 23044 23168 23170 23172 23296 23298 23300 23424 23426 23428 23552 23554 23556 23680 23682 23684 23808 23810 23812 23936 23938 23940 24064 24066 24068 24192 24194 24196 24320 24322 24324 24448 24450 24452 24576 24578 24580 24704 24706 24708 24832 24834 24836 24960 24962 24964 25088 25090 25092 25216 25218 25220 25344 25346 25348 25472 25474 25476 25600 25602 25604 25728 25730 25732 25856 25858 25860 25984 25986 25988 26112 26114 26116 26240 26242 26244 26368 26370 26372 26496 26498 26500 26624 26626 26628 26752 26754 26756 26880 26882 26884 27008 27010 27012 27136 27138 27140 27264 27266 27268 27392 27394 27396 27520 27522 27524 27648 27650 27652 27776 27778 27780 27904 27906 27908 28032 28034 28036 28160 28162 28164 28288 28290 28292 28416 28418 28420 28544 28546 28548 28672 28674 28676 28800 28802 28804 28928 28930 28932 29056 29058 29060 29184 29186 29188 29312 29314 29316 29440 29442 29444 29568 29570 29572 29696 29698 29700 29824 29826 29828 29952 29954 29956 30080 30082 30084 30208 30210 30212 30336 30338 30340 30464 30466 30468 30592 30594 30596 30720 30722 30724 30848 30850 30852 30976 30978 30980 31104 31106 31108 31232 31234 31236 31360 31362 31364 31488 31490 31492 31616 31618 31620 31744 31746 31748 31872 31874 31876 32000 32002 32004 32128 32130 32132 32256 32258 32260 32384 32386 32388 32512 32514 32516 32640 32642 32644 32768 32770 32772 32896 32898 32900 33024 33026 33028 33152 33154 33156 33280 33282 33284 33408 33410 33412 33536 33538 33540 33664 33666 33668 33792 33794 33796 33920 33922 33924 34048 34050 34052 34176 34178 34180 34304 34306 34308 34432 34434 34436 34560 34562 34564 34688 34690 34692 34816 34818 34820 34944 34946 34948 35072 35074 35076 35200 35202 35204 35328 35330 35332 35456 35458 35460 35584 35586 35588 35712 35714 35716 35840 35842 35844 35968 35970 35972 36096 36098 36100 36224 36226 36228 36352 36354 36356 36480 36482 36484 36608 36610 36612 36736 36738 36740 36864 36866 36868 36992 36994 36996 37120 37122 37124 37248 37250 37252 37376 37378 37380 37504 37506 37508 37632 37634 37636 37760 37762 37764 37888 37890 37892 38016 38018 38020 38144 38146 38148 38272 38274 38276 38400 38402 38404 38528 38530 38532 38656 38658 38660 38784 38786 38788 38912 38914 38916 39040 39042 39044 39168 39170 39172 39296 39298 39300 39424 39426 39428 39552 39554 39556 39680 39682 39684 39808 39810 39812 39936 39938 39940 40064 40066 40068 40192 40194 40196 40320 40322 40324 40448 40450 40452 40576 40578 40580 40704 40706 40708 40832 40834 40836 40960 40962 40964 41088 41090 41092 41216 41218 41220 41344 41346 41348 41472 41474 41476 41600 41602 41604 41728 41730 41732 41856 41858 41860 41984 41986 41988 42112 42114 42116 42240 42242 42244 42368 42370 42372 42496 42498 42500 42624 42626 42628 42752 42754 42756 42880 42882 42884 43008 43010 43012 43136 43138 43140 43264 43266 43268 43392 43394 43396 43520 43522 43524 43648 43650 43652 43776 43778 43780 43904 43906 43908 44032 44034 44036 44160 44162 44164 44288 44290 44292 44416 44418 44420 44544 44546 44548 44672 44674 44676 44800 44802 44804 44928 44930 44932 45056 45058 45060 45184 45186 45188 45312 45314 45316 45440 45442 45444 45568 45570 45572 45696 45698 45700 45824 45826 45828 45952 45954 45956 46080 46082 46084 46208 46210 46212 46336 46338 46340 46464 46466 46468 46592 46594 46596 46720 46722 46724 46848 46850 46852 46976 46978 46980 47104 47106 47108 47232 47234 47236 47360 47362 47364 47488 47490 47492 47616 47618 47620 47744 47746 47748 47872 47874 47876 48000 48002 48004 48128 48130 48132 48256 48258 48260 48384 48386 48388 48512 48514 48516 48640 48642 48644 48768 48770 48772 48896 48898 48900 49024 49026 49028 49152 49154 49156 49280 49282 49284 49408 49410 49412 49536 49538 49540 49664 49666 49668 49792 49794 49796 49920 49922 49924 50048 50050 50052 50176 50178 50180 50304 50306 50308 50432 50434 50436 50560 50562 50564 50688 50690 50692 50816 50818 50820 50944 50946 50948 51072 51074 51076 51200 51202 51204 51328 51330 51332 51456 51458 51460 51584 51586 51588 51712 51714 51716 51840 51842 51844 51968 51970 51972 52096 52098 52100 52224 52226 52228 52352 52354 52356 52480 52482 52484 52608 52610 52612 52736 52738 52740 52864 52866 52868 52992 52994 52996 53120 53122 53124 53248 53250 53252 53376 53378 53380 53504 53506 53508 53632 53634 53636 53760 53762 53764 53888 53890 53892 54016 54018 54020 54144 54146 54148 54272 54274 54276 54400 54402 54404 54528 54530 54532 54656 54658 54660 54784 54786 54788 54912 54914 54916 55040 55042 55044 55168 55170 55172 55296 55298 55300 55424 55426 55428 55552 55554 55556 55680 55682 55684 55808 55810 55812 55936 55938 55940 56064 56066 56068 56192 56194 56196 56320 56322 56324 56448 56450 56452 56576 56578 56580 56704 56706 56708 56832 56834 56836 56960 56962 56964 57088 57090 57092 57216 57218 57220 57344 57346 57348 57472 57474 57476 57600 57602 57604 57728 57730 57732 57856 57858 57860 57984 57986 57988 58112 58114 58116 58240 58242 58244 58368 58370 58372 58496 58498 58500 58624 58626 58628 58752 58754 58756 58880 58882 58884 59008 59010 59012 59136 59138 59140 59264 59266 59268 59392 59394 59396 59520 59522 59524 59648 59650 59652 59776 59778 59780 59904 59906 59908 60032 60034 60036 60160 60162 60164 60288 60290 60292 60416 60418 60420 60544 60546 60548 60672 60674 60676 60800 60802 60804 60928 60930 60932 61056 61058 61060 61184 61186 61188 61312 61314 61316 61440 61442 61444 61568 61570 61572 61696 61698 61700 61824 61826 61828 61952 61954 61956 62080 62082 62084 62208 62210 62212 62336 62338 62340 62464 62466 62468 62592 62594 62596 62720 62722 62724 62848 62850 62852 62976 62978 62980 63104 63106 63108 63232 63234 63236 63360 63362 63364 63488 63490 63492 63616 63618 63620 63744 63746 63748 63872 63874 63876 64000 64002 64004 64128 64130 64132 64256 64258 64260 64384 64386 64388 64512 64514 64516 64640 64642 64644 64768 64770 64772 64896 64898 64900 65024 65026 65028 65152 65154 65156 65280 65282 65284 65408 65410 65412 65536 65538 65540 65664 65666 65668 65792 65794 65796 65920 65922 65924 66048 66050 66052 66176 66178 66180 66304 66306 66308 66432 66434 66436 66560 66562 66564 66688 66690 66692 66816 66818 66820 66944 66946 66948 67072 67074 67076 67200 67202 67204 67328 67330 67332 67456 67458 67460 67584 67586 67588 67712 67714 67716 67840 67842 67844 67968 67970 67972 68096 68098 68100 68224 68226 68228 68352 68354 68356 68480 68482 68484 68608 68610 68612 68736 68738 68740 68864 68866 68868 68992 68994 68996 69120 69122 69124 69248 69250 69252 69376 69378 69380 69504 69506 69508 69632 69634 69636 69760 69762 69764 69888 69890 69892 70016 70018 70020 70144 70146 70148 70272 70274 70276 70400 70402 70404 70528 70530 70532 70656 70658 70660 70784 70786 70788 70912 70914 70916 71040 71042 71044 71168 71170 71172 71296 71298 71300 71424 71426 71428 71552 71554 71556 71680 71682 71684 71808 71810 71812 71936 71938 71940 72064 72066 72068 72192 72194 72196 72320 72322 72324 72448 72450 72452 72576 72578 72580 72704 72706 72708 72832 72834 72836 72960 72962 72964 73088 73090 73092 73216 73218 73220 73344 73346 73348 73472 73474 73476 73600 73602 73604 73728 73730 73732 73856 73858 73860 73984 73986 73988 74112 74114 74116 74240 74242 74244 74368 74370 74372 74496 74498 74500 74624 74626 74628 74752 74754 74756 74880 74882 74884 75008 75010 75012 75136 75138 75140 75264 75266 75268 75392 75394 75396 75520 75522 75524 75648 75650 75652 75776 75778 75780 75904 75906 75908 76032 76034 76036 76160 76162 76164 76288 76290 76292 76416 76418 76420 76544 76546 76548 76672 76674 76676 76800 76802 76804 76928 76930 76932 77056 77058 77060 77184 77186 77188 77312 77314 77316 77440 77442 77444 77568 77570 77572 77696 77698 77700 77824 77826 77828 77952 77954 77956 78080 78082 78084 78208 78210 78212 78336 78338 78340 78464 78466 78468 78592 78594 78596 78720 78722 78724 78848 78850 78852 78976 78978 78980 79104 79106 79108 79232 79234 79236 79360 79362 79364 79488 79490 79492 79616 79618 79620 79744 79746 79748 79872 79874 79876 80000 80002 80004 80128 80130 80132 80256 80258 80260 80384 80386 80388 80512 80514 80516 80640 80642 80644 80768 80770 80772 80896 80898 80900 81024 81026 81028 81152 81154 81156 81280 81282 81284 81408 81410 81412 81536 81538 81540 81664 81666 81668 81792 81794 81796 81920 81922 81924 82048 82050 82052 82176 82178 82180 82304 82306 82308 82432 82434 82436 82560 82562 82564 82688 82690 82692 82816 82818 82820 82944 82946 82948 83072 83074 83076 83200 83202 83204 83328 83330 83332 83456 83458 83460 83584 83586 83588 83712 83714 83716 83840 83842 83844 83968 83970 83972 84096 84098 84100 84224 84226 84228 84352 84354 84356 84480 84482 84484 84608 84610 84612 84736 84738 84740 84864 84866 84868 84992 84994 84996 85120 85122 85124 85248 85250 85252 85376 85378 85380 85504 85506 85508 85632 85634 85636 85760 85762 85764 85888 85890 85892 86016 86018 86020 86144 86146 86148 86272 86274 86276 86400 86402 86404 86528 86530 86532 86656 86658 86660 86784 86786 86788 86912 86914 86916 87040 87042 87044 87168 87170 87172 87296 87298 87300 87424 87426 87428 87552 87554 87556 87680 87682 87684 87808 87810 87812 87936 87938 87940 88064 88066 88068 88192 88194 88196 88320 88322 88324 88448 88450 88452 88576 88578 88580 88704 88706 88708 88832 88834 88836 88960 88962 88964 89088 89090 89092 89216 89218 89220 89344 89346 89348 89472 89474 89476 89600 89602 89604 89728 89730 89732 89856 89858 89860 89984 89986 89988 90112 90114 90116 90240 90242 90244 90368 90370 90372 90496 90498 90500 90624 90626 90628 90752 90754 90756 90880 90882 90884 91008 91010 91012 91136 91138 91140 91264 91266 91268 91392 91394 91396 91520 91522 91524 91648 91650 91652 91776 91778 91780 91904 91906 91908 92032 92034 92036 92160 92162 92164 92288 92290 92292 92416 92418 92420 92544 92546 92548 92672 92674 92676 92800 92802 92804 92928 92930 92932 93056 93058 93060 93184 93186 93188 93312 93314 93316 93440 93442 93444 93568 93570 93572 93696 93698 93700 93824 93826 93828 93952 93954 93956 94080 94082 94084 94208 94210 94212 94336 94338 94340 94464 94466 94468 94592 94594 94596 94720 94722 94724 94848 94850 94852 94976 94978 94980 95104 95106 95108 95232 95234 95236 95360 95362 95364 95488 95490 95492 95616 95618 95620 95744 95746 95748 95872 95874 95876 96000 96002 96004 96128 96130 96132 96256 96258 96260 96384 96386 96388 96512 96514 96516 96640 96642 96644 96768 96770 96772 96896 96898 96900 97024 97026 97028 97152 97154 97156 97280 97282 97284 97408 97410 97412 97536 97538 97540 97664 97666 97668 97792 97794 97796 97920 97922 97924 98048 98050 98052 98176 98178 98180 98304 98306 98308 98432 98434 98436 98560 98562 98564 98688 98690 98692 98816 98818 98820 98944 98946 98948 99072 99074 99076 99200 99202 99204 99328 99330 99332 99456 99458 99460 99584 99586 99588 99712 99714 99716 99840 99842 99844 99968 99970 99972 100096 100098 100100 100224 100226 100228 100352 100354 100356 100480 100482 100484 100608 100610 100612 100736 100738 100740 100864 100866 100868 100992 100994 100996 101120 101122 101124 101248 101250 101252 101376 101378 101380 101504 101506 101508 101632 101634 101636 101760 101762 101764 101888 101890 101892 102016 102018 102020 102144 102146 102148 102272 102274 102276 102400 102402 102404 102528 102530 102532 102656 102658 102660 102784 102786 102788 102912 102914 102916 103040 103042 103044 103168 103170 103172 103296 103298 103300 103424 103426 103428 103552 103554 103556 103680 103682 103684 103808 103810 103812 103936 103938 103940 104064 104066 104068 104192 104194 104196 104320 104322 104324 104448 104450 104452 104576 104578 104580 104704 104706 104708 104832 104834 104836 104960 104962 104964 105088 105090 105092 105216 105218 105220 105344 105346 105348 105472 105474 105476 105600 105602 105604 105728 105730 105732 105856 105858 105860 105984 105986 105988 106112 106114 106116 106240 106242 106244 106368 106370 106372 106496 106498 106500 106624 106626 106628 106752 106754 106756 106880 106882 106884 107008 107010 107012 107136 107138 107140 107264 107266 107268 107392 107394 107396 107520 107522 107524 107648 107650 107652 107776 107778 107780 107904 107906 107908 108032 108034 108036 108160 108162 108164 108288 108290 108292 108416 108418 108420 108544 108546 108548 108672 108674 108676 108800 108802 108804 108928 108930 108932 109056 109058 109060 109184 109186 109188 109312 109314 109316 109440 109442 109444 109568 109570 109572 109696 109698 109700 109824 109826 109828 109952 109954 109956 110080 110082 110084 110208 110210 110212 110336 110338 110340 110464 110466 110468 110592 110594 110596 110720 110722 110724 110848 110850 110852 110976 110978 110980 111104 111106 111108 111232 111234 111236 111360 111362 111364 111488 111490 111492 111616 111618 111620 111744 111746 111748 111872 111874 111876 112000 112002 112004 112128 112130 112132 112256 112258 112260 112384 112386 112388 112512 112514 112516 112640 112642 112644 112768 112770 112772 112896 112898 112900 113024 113026 113028 113152 113154 113156 113280 113282 113284 113408 113410 113412 113536 113538 113540 113664 113666 113668 113792 113794 113796 113920 113922 113924 114048 114050 114052 114176 114178 114180 114304 114306 114308 114432 114434 114436 114560 114562 114564 114688 114690 114692 114816 114818 114820 114944 114946 114948 115072 115074 115076 115200 115202 115204 115328 115330 115332 115456 115458 115460 115584 115586 115588 115712 115714 115716 115840 115842 115844 115968 115970 115972 116096 116098 116100 116224 116226 116228 116352 116354 116356 116480 116482 116484 116608 116610 116612 116736 116738 116740 116864 116866 116868 116992 116994 116996 117120 117122 117124 117248 117250 117252 117376 117378 117380 117504 117506 117508 117632 117634 117636 117760 117762 117764 117888 117890 117892 118016 118018 118020 118144 118146 118148 118272 118274 118276 118400 118402 118404 118528 118530 118532 118656 118658 118660 118784 118786 118788 118912 118914 118916 119040 119042 119044 119168 119170 119172 119296 119298 119300 119424 119426 119428 119552 119554 119556 119680 119682 119684 119808 119810 119812 119936 119938 119940 120064 120066 120068 120192 120194 120196 120320 120322 120324 120448 120450 120452 120576 120578 120580 120704 120706 120708 120832 120834 120836 120960 120962 120964 121088 121090 121092 121216 121218 121220 121344 121346 121348 121472 121474 121476 121600 121602 121604 121728 121730 121732 121856 121858 121860 121984 121986 121988 122112 122114 122116 122240 122242 122244 122368 122370 122372 122496 122498 122500 122624 122626 122628 122752 122754 122756 122880 122882 122884 123008 123010 123012 123136 123138 123140 123264 123266 123268 123392 123394 123396 123520 123522 123524 123648 123650 123652 123776 123778 123780 123904 123906 123908 124032 124034 124036 124160 124162 124164 124288 124290 124292 124416 124418 124420 124544 124546 124548 124672 124674 124676 124800 124802 124804 124928 124930 124932 125056 125058 125060 125184 125186 125188 125312 125314 125316 125440 125442 125444 125568 125570 125572 125696 125698 125700 125824 125826 125828 125952 125954 125956 126080 126082 126084 126208 126210 126212 126336 126338 126340 126464 126466 126468 126592 126594 126596 126720 126722 126724 126848 126850 126852 126976 126978 126980 127104 127106 127108 127232 127234 127236 127360 127362 127364 127488 127490 127492 127616 127618 127620 127744 127746 127748 127872 127874 127876 128000 128002 128004 128128 128130 128132 128256 128258 128260 128384 128386 128388 128512 128514 128516 128640 128642 128644 128768 128770 128772 128896 128898 128900 129024 129026 129028 129152 129154 129156 129280 129282 129284 129408 129410 129412 129536 129538 129540 129664 129666 129668 129792 129794 129796 129920 129922 129924 130048 130050 130052 130176 130178 130180 130304 130306 130308 130432 130434 130436 130560 130562 130564 130688 130690 130692 130816 130818 130820 130944 130946 130948 �����������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_1x4x4x1.txt��������������������������������������������0000664�0000000�0000000�00000000116�14364043643�0023071�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 4096 4224 4352 4480 8192 8320 8448 8576 12288 12416 12544 12672 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/hwck_2x3x33x129.txt�����������������������������������������0000664�0000000�0000000�00000444551�14364043643�0023345�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 49152 49154 49156 49158 49160 49162 49164 49166 49168 49170 49172 49174 49176 49178 49180 49182 49184 49186 49188 49190 49192 49194 49196 49198 49200 49202 49204 49206 49208 49210 49212 49214 49216 49218 49220 49222 49224 49226 49228 49230 49232 49234 49236 49238 49240 49242 49244 49246 49248 49250 49252 49254 49256 49258 49260 49262 49264 49266 49268 49270 49272 49274 49276 49278 98304 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 49280 49282 49284 49286 49288 49290 49292 49294 49296 49298 49300 49302 49304 49306 49308 49310 49312 49314 49316 49318 49320 49322 49324 49326 49328 49330 49332 49334 49336 49338 49340 49342 49344 49346 49348 49350 49352 49354 49356 49358 49360 49362 49364 49366 49368 49370 49372 49374 49376 49378 49380 49382 49384 49386 49388 49390 49392 49394 49396 49398 49400 49402 49404 49406 98432 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 49408 49410 49412 49414 49416 49418 49420 49422 49424 49426 49428 49430 49432 49434 49436 49438 49440 49442 49444 49446 49448 49450 49452 49454 49456 49458 49460 49462 49464 49466 49468 49470 49472 49474 49476 49478 49480 49482 49484 49486 49488 49490 49492 49494 49496 49498 49500 49502 49504 49506 49508 49510 49512 49514 49516 49518 49520 49522 49524 49526 49528 49530 49532 49534 98560 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 49536 49538 49540 49542 49544 49546 49548 49550 49552 49554 49556 49558 49560 49562 49564 49566 49568 49570 49572 49574 49576 49578 49580 49582 49584 49586 49588 49590 49592 49594 49596 49598 49600 49602 49604 49606 49608 49610 49612 49614 49616 49618 49620 49622 49624 49626 49628 49630 49632 49634 49636 49638 49640 49642 49644 49646 49648 49650 49652 49654 49656 49658 49660 49662 98688 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 49664 49666 49668 49670 49672 49674 49676 49678 49680 49682 49684 49686 49688 49690 49692 49694 49696 49698 49700 49702 49704 49706 49708 49710 49712 49714 49716 49718 49720 49722 49724 49726 49728 49730 49732 49734 49736 49738 49740 49742 49744 49746 49748 49750 49752 49754 49756 49758 49760 49762 49764 49766 49768 49770 49772 49774 49776 49778 49780 49782 49784 49786 49788 49790 98816 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 49792 49794 49796 49798 49800 49802 49804 49806 49808 49810 49812 49814 49816 49818 49820 49822 49824 49826 49828 49830 49832 49834 49836 49838 49840 49842 49844 49846 49848 49850 49852 49854 49856 49858 49860 49862 49864 49866 49868 49870 49872 49874 49876 49878 49880 49882 49884 49886 49888 49890 49892 49894 49896 49898 49900 49902 49904 49906 49908 49910 49912 49914 49916 49918 98944 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 49920 49922 49924 49926 49928 49930 49932 49934 49936 49938 49940 49942 49944 49946 49948 49950 49952 49954 49956 49958 49960 49962 49964 49966 49968 49970 49972 49974 49976 49978 49980 49982 49984 49986 49988 49990 49992 49994 49996 49998 50000 50002 50004 50006 50008 50010 50012 50014 50016 50018 50020 50022 50024 50026 50028 50030 50032 50034 50036 50038 50040 50042 50044 50046 99072 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 50048 50050 50052 50054 50056 50058 50060 50062 50064 50066 50068 50070 50072 50074 50076 50078 50080 50082 50084 50086 50088 50090 50092 50094 50096 50098 50100 50102 50104 50106 50108 50110 50112 50114 50116 50118 50120 50122 50124 50126 50128 50130 50132 50134 50136 50138 50140 50142 50144 50146 50148 50150 50152 50154 50156 50158 50160 50162 50164 50166 50168 50170 50172 50174 99200 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 50176 50178 50180 50182 50184 50186 50188 50190 50192 50194 50196 50198 50200 50202 50204 50206 50208 50210 50212 50214 50216 50218 50220 50222 50224 50226 50228 50230 50232 50234 50236 50238 50240 50242 50244 50246 50248 50250 50252 50254 50256 50258 50260 50262 50264 50266 50268 50270 50272 50274 50276 50278 50280 50282 50284 50286 50288 50290 50292 50294 50296 50298 50300 50302 99328 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 50304 50306 50308 50310 50312 50314 50316 50318 50320 50322 50324 50326 50328 50330 50332 50334 50336 50338 50340 50342 50344 50346 50348 50350 50352 50354 50356 50358 50360 50362 50364 50366 50368 50370 50372 50374 50376 50378 50380 50382 50384 50386 50388 50390 50392 50394 50396 50398 50400 50402 50404 50406 50408 50410 50412 50414 50416 50418 50420 50422 50424 50426 50428 50430 99456 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 50432 50434 50436 50438 50440 50442 50444 50446 50448 50450 50452 50454 50456 50458 50460 50462 50464 50466 50468 50470 50472 50474 50476 50478 50480 50482 50484 50486 50488 50490 50492 50494 50496 50498 50500 50502 50504 50506 50508 50510 50512 50514 50516 50518 50520 50522 50524 50526 50528 50530 50532 50534 50536 50538 50540 50542 50544 50546 50548 50550 50552 50554 50556 50558 99584 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 50560 50562 50564 50566 50568 50570 50572 50574 50576 50578 50580 50582 50584 50586 50588 50590 50592 50594 50596 50598 50600 50602 50604 50606 50608 50610 50612 50614 50616 50618 50620 50622 50624 50626 50628 50630 50632 50634 50636 50638 50640 50642 50644 50646 50648 50650 50652 50654 50656 50658 50660 50662 50664 50666 50668 50670 50672 50674 50676 50678 50680 50682 50684 50686 99712 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 50688 50690 50692 50694 50696 50698 50700 50702 50704 50706 50708 50710 50712 50714 50716 50718 50720 50722 50724 50726 50728 50730 50732 50734 50736 50738 50740 50742 50744 50746 50748 50750 50752 50754 50756 50758 50760 50762 50764 50766 50768 50770 50772 50774 50776 50778 50780 50782 50784 50786 50788 50790 50792 50794 50796 50798 50800 50802 50804 50806 50808 50810 50812 50814 99840 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 50816 50818 50820 50822 50824 50826 50828 50830 50832 50834 50836 50838 50840 50842 50844 50846 50848 50850 50852 50854 50856 50858 50860 50862 50864 50866 50868 50870 50872 50874 50876 50878 50880 50882 50884 50886 50888 50890 50892 50894 50896 50898 50900 50902 50904 50906 50908 50910 50912 50914 50916 50918 50920 50922 50924 50926 50928 50930 50932 50934 50936 50938 50940 50942 99968 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 50944 50946 50948 50950 50952 50954 50956 50958 50960 50962 50964 50966 50968 50970 50972 50974 50976 50978 50980 50982 50984 50986 50988 50990 50992 50994 50996 50998 51000 51002 51004 51006 51008 51010 51012 51014 51016 51018 51020 51022 51024 51026 51028 51030 51032 51034 51036 51038 51040 51042 51044 51046 51048 51050 51052 51054 51056 51058 51060 51062 51064 51066 51068 51070 100096 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 51072 51074 51076 51078 51080 51082 51084 51086 51088 51090 51092 51094 51096 51098 51100 51102 51104 51106 51108 51110 51112 51114 51116 51118 51120 51122 51124 51126 51128 51130 51132 51134 51136 51138 51140 51142 51144 51146 51148 51150 51152 51154 51156 51158 51160 51162 51164 51166 51168 51170 51172 51174 51176 51178 51180 51182 51184 51186 51188 51190 51192 51194 51196 51198 100224 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 51200 51202 51204 51206 51208 51210 51212 51214 51216 51218 51220 51222 51224 51226 51228 51230 51232 51234 51236 51238 51240 51242 51244 51246 51248 51250 51252 51254 51256 51258 51260 51262 51264 51266 51268 51270 51272 51274 51276 51278 51280 51282 51284 51286 51288 51290 51292 51294 51296 51298 51300 51302 51304 51306 51308 51310 51312 51314 51316 51318 51320 51322 51324 51326 100352 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 51328 51330 51332 51334 51336 51338 51340 51342 51344 51346 51348 51350 51352 51354 51356 51358 51360 51362 51364 51366 51368 51370 51372 51374 51376 51378 51380 51382 51384 51386 51388 51390 51392 51394 51396 51398 51400 51402 51404 51406 51408 51410 51412 51414 51416 51418 51420 51422 51424 51426 51428 51430 51432 51434 51436 51438 51440 51442 51444 51446 51448 51450 51452 51454 100480 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 51456 51458 51460 51462 51464 51466 51468 51470 51472 51474 51476 51478 51480 51482 51484 51486 51488 51490 51492 51494 51496 51498 51500 51502 51504 51506 51508 51510 51512 51514 51516 51518 51520 51522 51524 51526 51528 51530 51532 51534 51536 51538 51540 51542 51544 51546 51548 51550 51552 51554 51556 51558 51560 51562 51564 51566 51568 51570 51572 51574 51576 51578 51580 51582 100608 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 51584 51586 51588 51590 51592 51594 51596 51598 51600 51602 51604 51606 51608 51610 51612 51614 51616 51618 51620 51622 51624 51626 51628 51630 51632 51634 51636 51638 51640 51642 51644 51646 51648 51650 51652 51654 51656 51658 51660 51662 51664 51666 51668 51670 51672 51674 51676 51678 51680 51682 51684 51686 51688 51690 51692 51694 51696 51698 51700 51702 51704 51706 51708 51710 100736 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 51712 51714 51716 51718 51720 51722 51724 51726 51728 51730 51732 51734 51736 51738 51740 51742 51744 51746 51748 51750 51752 51754 51756 51758 51760 51762 51764 51766 51768 51770 51772 51774 51776 51778 51780 51782 51784 51786 51788 51790 51792 51794 51796 51798 51800 51802 51804 51806 51808 51810 51812 51814 51816 51818 51820 51822 51824 51826 51828 51830 51832 51834 51836 51838 100864 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 51840 51842 51844 51846 51848 51850 51852 51854 51856 51858 51860 51862 51864 51866 51868 51870 51872 51874 51876 51878 51880 51882 51884 51886 51888 51890 51892 51894 51896 51898 51900 51902 51904 51906 51908 51910 51912 51914 51916 51918 51920 51922 51924 51926 51928 51930 51932 51934 51936 51938 51940 51942 51944 51946 51948 51950 51952 51954 51956 51958 51960 51962 51964 51966 100992 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 51968 51970 51972 51974 51976 51978 51980 51982 51984 51986 51988 51990 51992 51994 51996 51998 52000 52002 52004 52006 52008 52010 52012 52014 52016 52018 52020 52022 52024 52026 52028 52030 52032 52034 52036 52038 52040 52042 52044 52046 52048 52050 52052 52054 52056 52058 52060 52062 52064 52066 52068 52070 52072 52074 52076 52078 52080 52082 52084 52086 52088 52090 52092 52094 101120 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 52096 52098 52100 52102 52104 52106 52108 52110 52112 52114 52116 52118 52120 52122 52124 52126 52128 52130 52132 52134 52136 52138 52140 52142 52144 52146 52148 52150 52152 52154 52156 52158 52160 52162 52164 52166 52168 52170 52172 52174 52176 52178 52180 52182 52184 52186 52188 52190 52192 52194 52196 52198 52200 52202 52204 52206 52208 52210 52212 52214 52216 52218 52220 52222 101248 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 52224 52226 52228 52230 52232 52234 52236 52238 52240 52242 52244 52246 52248 52250 52252 52254 52256 52258 52260 52262 52264 52266 52268 52270 52272 52274 52276 52278 52280 52282 52284 52286 52288 52290 52292 52294 52296 52298 52300 52302 52304 52306 52308 52310 52312 52314 52316 52318 52320 52322 52324 52326 52328 52330 52332 52334 52336 52338 52340 52342 52344 52346 52348 52350 101376 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 52352 52354 52356 52358 52360 52362 52364 52366 52368 52370 52372 52374 52376 52378 52380 52382 52384 52386 52388 52390 52392 52394 52396 52398 52400 52402 52404 52406 52408 52410 52412 52414 52416 52418 52420 52422 52424 52426 52428 52430 52432 52434 52436 52438 52440 52442 52444 52446 52448 52450 52452 52454 52456 52458 52460 52462 52464 52466 52468 52470 52472 52474 52476 52478 101504 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 52480 52482 52484 52486 52488 52490 52492 52494 52496 52498 52500 52502 52504 52506 52508 52510 52512 52514 52516 52518 52520 52522 52524 52526 52528 52530 52532 52534 52536 52538 52540 52542 52544 52546 52548 52550 52552 52554 52556 52558 52560 52562 52564 52566 52568 52570 52572 52574 52576 52578 52580 52582 52584 52586 52588 52590 52592 52594 52596 52598 52600 52602 52604 52606 101632 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 52608 52610 52612 52614 52616 52618 52620 52622 52624 52626 52628 52630 52632 52634 52636 52638 52640 52642 52644 52646 52648 52650 52652 52654 52656 52658 52660 52662 52664 52666 52668 52670 52672 52674 52676 52678 52680 52682 52684 52686 52688 52690 52692 52694 52696 52698 52700 52702 52704 52706 52708 52710 52712 52714 52716 52718 52720 52722 52724 52726 52728 52730 52732 52734 101760 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 52736 52738 52740 52742 52744 52746 52748 52750 52752 52754 52756 52758 52760 52762 52764 52766 52768 52770 52772 52774 52776 52778 52780 52782 52784 52786 52788 52790 52792 52794 52796 52798 52800 52802 52804 52806 52808 52810 52812 52814 52816 52818 52820 52822 52824 52826 52828 52830 52832 52834 52836 52838 52840 52842 52844 52846 52848 52850 52852 52854 52856 52858 52860 52862 101888 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 52864 52866 52868 52870 52872 52874 52876 52878 52880 52882 52884 52886 52888 52890 52892 52894 52896 52898 52900 52902 52904 52906 52908 52910 52912 52914 52916 52918 52920 52922 52924 52926 52928 52930 52932 52934 52936 52938 52940 52942 52944 52946 52948 52950 52952 52954 52956 52958 52960 52962 52964 52966 52968 52970 52972 52974 52976 52978 52980 52982 52984 52986 52988 52990 102016 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 52992 52994 52996 52998 53000 53002 53004 53006 53008 53010 53012 53014 53016 53018 53020 53022 53024 53026 53028 53030 53032 53034 53036 53038 53040 53042 53044 53046 53048 53050 53052 53054 53056 53058 53060 53062 53064 53066 53068 53070 53072 53074 53076 53078 53080 53082 53084 53086 53088 53090 53092 53094 53096 53098 53100 53102 53104 53106 53108 53110 53112 53114 53116 53118 102144 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 4094 53120 53122 53124 53126 53128 53130 53132 53134 53136 53138 53140 53142 53144 53146 53148 53150 53152 53154 53156 53158 53160 53162 53164 53166 53168 53170 53172 53174 53176 53178 53180 53182 53184 53186 53188 53190 53192 53194 53196 53198 53200 53202 53204 53206 53208 53210 53212 53214 53216 53218 53220 53222 53224 53226 53228 53230 53232 53234 53236 53238 53240 53242 53244 53246 102272 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 4222 53248 53250 53252 53254 53256 53258 53260 53262 53264 53266 53268 53270 53272 53274 53276 53278 53280 53282 53284 53286 53288 53290 53292 53294 53296 53298 53300 53302 53304 53306 53308 53310 53312 53314 53316 53318 53320 53322 53324 53326 53328 53330 53332 53334 53336 53338 53340 53342 53344 53346 53348 53350 53352 53354 53356 53358 53360 53362 53364 53366 53368 53370 53372 53374 102400 8192 8194 8196 8198 8200 8202 8204 8206 8208 8210 8212 8214 8216 8218 8220 8222 8224 8226 8228 8230 8232 8234 8236 8238 8240 8242 8244 8246 8248 8250 8252 8254 8256 8258 8260 8262 8264 8266 8268 8270 8272 8274 8276 8278 8280 8282 8284 8286 8288 8290 8292 8294 8296 8298 8300 8302 8304 8306 8308 8310 8312 8314 8316 8318 57344 57346 57348 57350 57352 57354 57356 57358 57360 57362 57364 57366 57368 57370 57372 57374 57376 57378 57380 57382 57384 57386 57388 57390 57392 57394 57396 57398 57400 57402 57404 57406 57408 57410 57412 57414 57416 57418 57420 57422 57424 57426 57428 57430 57432 57434 57436 57438 57440 57442 57444 57446 57448 57450 57452 57454 57456 57458 57460 57462 57464 57466 57468 57470 106496 8320 8322 8324 8326 8328 8330 8332 8334 8336 8338 8340 8342 8344 8346 8348 8350 8352 8354 8356 8358 8360 8362 8364 8366 8368 8370 8372 8374 8376 8378 8380 8382 8384 8386 8388 8390 8392 8394 8396 8398 8400 8402 8404 8406 8408 8410 8412 8414 8416 8418 8420 8422 8424 8426 8428 8430 8432 8434 8436 8438 8440 8442 8444 8446 57472 57474 57476 57478 57480 57482 57484 57486 57488 57490 57492 57494 57496 57498 57500 57502 57504 57506 57508 57510 57512 57514 57516 57518 57520 57522 57524 57526 57528 57530 57532 57534 57536 57538 57540 57542 57544 57546 57548 57550 57552 57554 57556 57558 57560 57562 57564 57566 57568 57570 57572 57574 57576 57578 57580 57582 57584 57586 57588 57590 57592 57594 57596 57598 106624 8448 8450 8452 8454 8456 8458 8460 8462 8464 8466 8468 8470 8472 8474 8476 8478 8480 8482 8484 8486 8488 8490 8492 8494 8496 8498 8500 8502 8504 8506 8508 8510 8512 8514 8516 8518 8520 8522 8524 8526 8528 8530 8532 8534 8536 8538 8540 8542 8544 8546 8548 8550 8552 8554 8556 8558 8560 8562 8564 8566 8568 8570 8572 8574 57600 57602 57604 57606 57608 57610 57612 57614 57616 57618 57620 57622 57624 57626 57628 57630 57632 57634 57636 57638 57640 57642 57644 57646 57648 57650 57652 57654 57656 57658 57660 57662 57664 57666 57668 57670 57672 57674 57676 57678 57680 57682 57684 57686 57688 57690 57692 57694 57696 57698 57700 57702 57704 57706 57708 57710 57712 57714 57716 57718 57720 57722 57724 57726 106752 8576 8578 8580 8582 8584 8586 8588 8590 8592 8594 8596 8598 8600 8602 8604 8606 8608 8610 8612 8614 8616 8618 8620 8622 8624 8626 8628 8630 8632 8634 8636 8638 8640 8642 8644 8646 8648 8650 8652 8654 8656 8658 8660 8662 8664 8666 8668 8670 8672 8674 8676 8678 8680 8682 8684 8686 8688 8690 8692 8694 8696 8698 8700 8702 57728 57730 57732 57734 57736 57738 57740 57742 57744 57746 57748 57750 57752 57754 57756 57758 57760 57762 57764 57766 57768 57770 57772 57774 57776 57778 57780 57782 57784 57786 57788 57790 57792 57794 57796 57798 57800 57802 57804 57806 57808 57810 57812 57814 57816 57818 57820 57822 57824 57826 57828 57830 57832 57834 57836 57838 57840 57842 57844 57846 57848 57850 57852 57854 106880 8704 8706 8708 8710 8712 8714 8716 8718 8720 8722 8724 8726 8728 8730 8732 8734 8736 8738 8740 8742 8744 8746 8748 8750 8752 8754 8756 8758 8760 8762 8764 8766 8768 8770 8772 8774 8776 8778 8780 8782 8784 8786 8788 8790 8792 8794 8796 8798 8800 8802 8804 8806 8808 8810 8812 8814 8816 8818 8820 8822 8824 8826 8828 8830 57856 57858 57860 57862 57864 57866 57868 57870 57872 57874 57876 57878 57880 57882 57884 57886 57888 57890 57892 57894 57896 57898 57900 57902 57904 57906 57908 57910 57912 57914 57916 57918 57920 57922 57924 57926 57928 57930 57932 57934 57936 57938 57940 57942 57944 57946 57948 57950 57952 57954 57956 57958 57960 57962 57964 57966 57968 57970 57972 57974 57976 57978 57980 57982 107008 8832 8834 8836 8838 8840 8842 8844 8846 8848 8850 8852 8854 8856 8858 8860 8862 8864 8866 8868 8870 8872 8874 8876 8878 8880 8882 8884 8886 8888 8890 8892 8894 8896 8898 8900 8902 8904 8906 8908 8910 8912 8914 8916 8918 8920 8922 8924 8926 8928 8930 8932 8934 8936 8938 8940 8942 8944 8946 8948 8950 8952 8954 8956 8958 57984 57986 57988 57990 57992 57994 57996 57998 58000 58002 58004 58006 58008 58010 58012 58014 58016 58018 58020 58022 58024 58026 58028 58030 58032 58034 58036 58038 58040 58042 58044 58046 58048 58050 58052 58054 58056 58058 58060 58062 58064 58066 58068 58070 58072 58074 58076 58078 58080 58082 58084 58086 58088 58090 58092 58094 58096 58098 58100 58102 58104 58106 58108 58110 107136 8960 8962 8964 8966 8968 8970 8972 8974 8976 8978 8980 8982 8984 8986 8988 8990 8992 8994 8996 8998 9000 9002 9004 9006 9008 9010 9012 9014 9016 9018 9020 9022 9024 9026 9028 9030 9032 9034 9036 9038 9040 9042 9044 9046 9048 9050 9052 9054 9056 9058 9060 9062 9064 9066 9068 9070 9072 9074 9076 9078 9080 9082 9084 9086 58112 58114 58116 58118 58120 58122 58124 58126 58128 58130 58132 58134 58136 58138 58140 58142 58144 58146 58148 58150 58152 58154 58156 58158 58160 58162 58164 58166 58168 58170 58172 58174 58176 58178 58180 58182 58184 58186 58188 58190 58192 58194 58196 58198 58200 58202 58204 58206 58208 58210 58212 58214 58216 58218 58220 58222 58224 58226 58228 58230 58232 58234 58236 58238 107264 9088 9090 9092 9094 9096 9098 9100 9102 9104 9106 9108 9110 9112 9114 9116 9118 9120 9122 9124 9126 9128 9130 9132 9134 9136 9138 9140 9142 9144 9146 9148 9150 9152 9154 9156 9158 9160 9162 9164 9166 9168 9170 9172 9174 9176 9178 9180 9182 9184 9186 9188 9190 9192 9194 9196 9198 9200 9202 9204 9206 9208 9210 9212 9214 58240 58242 58244 58246 58248 58250 58252 58254 58256 58258 58260 58262 58264 58266 58268 58270 58272 58274 58276 58278 58280 58282 58284 58286 58288 58290 58292 58294 58296 58298 58300 58302 58304 58306 58308 58310 58312 58314 58316 58318 58320 58322 58324 58326 58328 58330 58332 58334 58336 58338 58340 58342 58344 58346 58348 58350 58352 58354 58356 58358 58360 58362 58364 58366 107392 9216 9218 9220 9222 9224 9226 9228 9230 9232 9234 9236 9238 9240 9242 9244 9246 9248 9250 9252 9254 9256 9258 9260 9262 9264 9266 9268 9270 9272 9274 9276 9278 9280 9282 9284 9286 9288 9290 9292 9294 9296 9298 9300 9302 9304 9306 9308 9310 9312 9314 9316 9318 9320 9322 9324 9326 9328 9330 9332 9334 9336 9338 9340 9342 58368 58370 58372 58374 58376 58378 58380 58382 58384 58386 58388 58390 58392 58394 58396 58398 58400 58402 58404 58406 58408 58410 58412 58414 58416 58418 58420 58422 58424 58426 58428 58430 58432 58434 58436 58438 58440 58442 58444 58446 58448 58450 58452 58454 58456 58458 58460 58462 58464 58466 58468 58470 58472 58474 58476 58478 58480 58482 58484 58486 58488 58490 58492 58494 107520 9344 9346 9348 9350 9352 9354 9356 9358 9360 9362 9364 9366 9368 9370 9372 9374 9376 9378 9380 9382 9384 9386 9388 9390 9392 9394 9396 9398 9400 9402 9404 9406 9408 9410 9412 9414 9416 9418 9420 9422 9424 9426 9428 9430 9432 9434 9436 9438 9440 9442 9444 9446 9448 9450 9452 9454 9456 9458 9460 9462 9464 9466 9468 9470 58496 58498 58500 58502 58504 58506 58508 58510 58512 58514 58516 58518 58520 58522 58524 58526 58528 58530 58532 58534 58536 58538 58540 58542 58544 58546 58548 58550 58552 58554 58556 58558 58560 58562 58564 58566 58568 58570 58572 58574 58576 58578 58580 58582 58584 58586 58588 58590 58592 58594 58596 58598 58600 58602 58604 58606 58608 58610 58612 58614 58616 58618 58620 58622 107648 9472 9474 9476 9478 9480 9482 9484 9486 9488 9490 9492 9494 9496 9498 9500 9502 9504 9506 9508 9510 9512 9514 9516 9518 9520 9522 9524 9526 9528 9530 9532 9534 9536 9538 9540 9542 9544 9546 9548 9550 9552 9554 9556 9558 9560 9562 9564 9566 9568 9570 9572 9574 9576 9578 9580 9582 9584 9586 9588 9590 9592 9594 9596 9598 58624 58626 58628 58630 58632 58634 58636 58638 58640 58642 58644 58646 58648 58650 58652 58654 58656 58658 58660 58662 58664 58666 58668 58670 58672 58674 58676 58678 58680 58682 58684 58686 58688 58690 58692 58694 58696 58698 58700 58702 58704 58706 58708 58710 58712 58714 58716 58718 58720 58722 58724 58726 58728 58730 58732 58734 58736 58738 58740 58742 58744 58746 58748 58750 107776 9600 9602 9604 9606 9608 9610 9612 9614 9616 9618 9620 9622 9624 9626 9628 9630 9632 9634 9636 9638 9640 9642 9644 9646 9648 9650 9652 9654 9656 9658 9660 9662 9664 9666 9668 9670 9672 9674 9676 9678 9680 9682 9684 9686 9688 9690 9692 9694 9696 9698 9700 9702 9704 9706 9708 9710 9712 9714 9716 9718 9720 9722 9724 9726 58752 58754 58756 58758 58760 58762 58764 58766 58768 58770 58772 58774 58776 58778 58780 58782 58784 58786 58788 58790 58792 58794 58796 58798 58800 58802 58804 58806 58808 58810 58812 58814 58816 58818 58820 58822 58824 58826 58828 58830 58832 58834 58836 58838 58840 58842 58844 58846 58848 58850 58852 58854 58856 58858 58860 58862 58864 58866 58868 58870 58872 58874 58876 58878 107904 9728 9730 9732 9734 9736 9738 9740 9742 9744 9746 9748 9750 9752 9754 9756 9758 9760 9762 9764 9766 9768 9770 9772 9774 9776 9778 9780 9782 9784 9786 9788 9790 9792 9794 9796 9798 9800 9802 9804 9806 9808 9810 9812 9814 9816 9818 9820 9822 9824 9826 9828 9830 9832 9834 9836 9838 9840 9842 9844 9846 9848 9850 9852 9854 58880 58882 58884 58886 58888 58890 58892 58894 58896 58898 58900 58902 58904 58906 58908 58910 58912 58914 58916 58918 58920 58922 58924 58926 58928 58930 58932 58934 58936 58938 58940 58942 58944 58946 58948 58950 58952 58954 58956 58958 58960 58962 58964 58966 58968 58970 58972 58974 58976 58978 58980 58982 58984 58986 58988 58990 58992 58994 58996 58998 59000 59002 59004 59006 108032 9856 9858 9860 9862 9864 9866 9868 9870 9872 9874 9876 9878 9880 9882 9884 9886 9888 9890 9892 9894 9896 9898 9900 9902 9904 9906 9908 9910 9912 9914 9916 9918 9920 9922 9924 9926 9928 9930 9932 9934 9936 9938 9940 9942 9944 9946 9948 9950 9952 9954 9956 9958 9960 9962 9964 9966 9968 9970 9972 9974 9976 9978 9980 9982 59008 59010 59012 59014 59016 59018 59020 59022 59024 59026 59028 59030 59032 59034 59036 59038 59040 59042 59044 59046 59048 59050 59052 59054 59056 59058 59060 59062 59064 59066 59068 59070 59072 59074 59076 59078 59080 59082 59084 59086 59088 59090 59092 59094 59096 59098 59100 59102 59104 59106 59108 59110 59112 59114 59116 59118 59120 59122 59124 59126 59128 59130 59132 59134 108160 9984 9986 9988 9990 9992 9994 9996 9998 10000 10002 10004 10006 10008 10010 10012 10014 10016 10018 10020 10022 10024 10026 10028 10030 10032 10034 10036 10038 10040 10042 10044 10046 10048 10050 10052 10054 10056 10058 10060 10062 10064 10066 10068 10070 10072 10074 10076 10078 10080 10082 10084 10086 10088 10090 10092 10094 10096 10098 10100 10102 10104 10106 10108 10110 59136 59138 59140 59142 59144 59146 59148 59150 59152 59154 59156 59158 59160 59162 59164 59166 59168 59170 59172 59174 59176 59178 59180 59182 59184 59186 59188 59190 59192 59194 59196 59198 59200 59202 59204 59206 59208 59210 59212 59214 59216 59218 59220 59222 59224 59226 59228 59230 59232 59234 59236 59238 59240 59242 59244 59246 59248 59250 59252 59254 59256 59258 59260 59262 108288 10112 10114 10116 10118 10120 10122 10124 10126 10128 10130 10132 10134 10136 10138 10140 10142 10144 10146 10148 10150 10152 10154 10156 10158 10160 10162 10164 10166 10168 10170 10172 10174 10176 10178 10180 10182 10184 10186 10188 10190 10192 10194 10196 10198 10200 10202 10204 10206 10208 10210 10212 10214 10216 10218 10220 10222 10224 10226 10228 10230 10232 10234 10236 10238 59264 59266 59268 59270 59272 59274 59276 59278 59280 59282 59284 59286 59288 59290 59292 59294 59296 59298 59300 59302 59304 59306 59308 59310 59312 59314 59316 59318 59320 59322 59324 59326 59328 59330 59332 59334 59336 59338 59340 59342 59344 59346 59348 59350 59352 59354 59356 59358 59360 59362 59364 59366 59368 59370 59372 59374 59376 59378 59380 59382 59384 59386 59388 59390 108416 10240 10242 10244 10246 10248 10250 10252 10254 10256 10258 10260 10262 10264 10266 10268 10270 10272 10274 10276 10278 10280 10282 10284 10286 10288 10290 10292 10294 10296 10298 10300 10302 10304 10306 10308 10310 10312 10314 10316 10318 10320 10322 10324 10326 10328 10330 10332 10334 10336 10338 10340 10342 10344 10346 10348 10350 10352 10354 10356 10358 10360 10362 10364 10366 59392 59394 59396 59398 59400 59402 59404 59406 59408 59410 59412 59414 59416 59418 59420 59422 59424 59426 59428 59430 59432 59434 59436 59438 59440 59442 59444 59446 59448 59450 59452 59454 59456 59458 59460 59462 59464 59466 59468 59470 59472 59474 59476 59478 59480 59482 59484 59486 59488 59490 59492 59494 59496 59498 59500 59502 59504 59506 59508 59510 59512 59514 59516 59518 108544 10368 10370 10372 10374 10376 10378 10380 10382 10384 10386 10388 10390 10392 10394 10396 10398 10400 10402 10404 10406 10408 10410 10412 10414 10416 10418 10420 10422 10424 10426 10428 10430 10432 10434 10436 10438 10440 10442 10444 10446 10448 10450 10452 10454 10456 10458 10460 10462 10464 10466 10468 10470 10472 10474 10476 10478 10480 10482 10484 10486 10488 10490 10492 10494 59520 59522 59524 59526 59528 59530 59532 59534 59536 59538 59540 59542 59544 59546 59548 59550 59552 59554 59556 59558 59560 59562 59564 59566 59568 59570 59572 59574 59576 59578 59580 59582 59584 59586 59588 59590 59592 59594 59596 59598 59600 59602 59604 59606 59608 59610 59612 59614 59616 59618 59620 59622 59624 59626 59628 59630 59632 59634 59636 59638 59640 59642 59644 59646 108672 10496 10498 10500 10502 10504 10506 10508 10510 10512 10514 10516 10518 10520 10522 10524 10526 10528 10530 10532 10534 10536 10538 10540 10542 10544 10546 10548 10550 10552 10554 10556 10558 10560 10562 10564 10566 10568 10570 10572 10574 10576 10578 10580 10582 10584 10586 10588 10590 10592 10594 10596 10598 10600 10602 10604 10606 10608 10610 10612 10614 10616 10618 10620 10622 59648 59650 59652 59654 59656 59658 59660 59662 59664 59666 59668 59670 59672 59674 59676 59678 59680 59682 59684 59686 59688 59690 59692 59694 59696 59698 59700 59702 59704 59706 59708 59710 59712 59714 59716 59718 59720 59722 59724 59726 59728 59730 59732 59734 59736 59738 59740 59742 59744 59746 59748 59750 59752 59754 59756 59758 59760 59762 59764 59766 59768 59770 59772 59774 108800 10624 10626 10628 10630 10632 10634 10636 10638 10640 10642 10644 10646 10648 10650 10652 10654 10656 10658 10660 10662 10664 10666 10668 10670 10672 10674 10676 10678 10680 10682 10684 10686 10688 10690 10692 10694 10696 10698 10700 10702 10704 10706 10708 10710 10712 10714 10716 10718 10720 10722 10724 10726 10728 10730 10732 10734 10736 10738 10740 10742 10744 10746 10748 10750 59776 59778 59780 59782 59784 59786 59788 59790 59792 59794 59796 59798 59800 59802 59804 59806 59808 59810 59812 59814 59816 59818 59820 59822 59824 59826 59828 59830 59832 59834 59836 59838 59840 59842 59844 59846 59848 59850 59852 59854 59856 59858 59860 59862 59864 59866 59868 59870 59872 59874 59876 59878 59880 59882 59884 59886 59888 59890 59892 59894 59896 59898 59900 59902 108928 10752 10754 10756 10758 10760 10762 10764 10766 10768 10770 10772 10774 10776 10778 10780 10782 10784 10786 10788 10790 10792 10794 10796 10798 10800 10802 10804 10806 10808 10810 10812 10814 10816 10818 10820 10822 10824 10826 10828 10830 10832 10834 10836 10838 10840 10842 10844 10846 10848 10850 10852 10854 10856 10858 10860 10862 10864 10866 10868 10870 10872 10874 10876 10878 59904 59906 59908 59910 59912 59914 59916 59918 59920 59922 59924 59926 59928 59930 59932 59934 59936 59938 59940 59942 59944 59946 59948 59950 59952 59954 59956 59958 59960 59962 59964 59966 59968 59970 59972 59974 59976 59978 59980 59982 59984 59986 59988 59990 59992 59994 59996 59998 60000 60002 60004 60006 60008 60010 60012 60014 60016 60018 60020 60022 60024 60026 60028 60030 109056 10880 10882 10884 10886 10888 10890 10892 10894 10896 10898 10900 10902 10904 10906 10908 10910 10912 10914 10916 10918 10920 10922 10924 10926 10928 10930 10932 10934 10936 10938 10940 10942 10944 10946 10948 10950 10952 10954 10956 10958 10960 10962 10964 10966 10968 10970 10972 10974 10976 10978 10980 10982 10984 10986 10988 10990 10992 10994 10996 10998 11000 11002 11004 11006 60032 60034 60036 60038 60040 60042 60044 60046 60048 60050 60052 60054 60056 60058 60060 60062 60064 60066 60068 60070 60072 60074 60076 60078 60080 60082 60084 60086 60088 60090 60092 60094 60096 60098 60100 60102 60104 60106 60108 60110 60112 60114 60116 60118 60120 60122 60124 60126 60128 60130 60132 60134 60136 60138 60140 60142 60144 60146 60148 60150 60152 60154 60156 60158 109184 11008 11010 11012 11014 11016 11018 11020 11022 11024 11026 11028 11030 11032 11034 11036 11038 11040 11042 11044 11046 11048 11050 11052 11054 11056 11058 11060 11062 11064 11066 11068 11070 11072 11074 11076 11078 11080 11082 11084 11086 11088 11090 11092 11094 11096 11098 11100 11102 11104 11106 11108 11110 11112 11114 11116 11118 11120 11122 11124 11126 11128 11130 11132 11134 60160 60162 60164 60166 60168 60170 60172 60174 60176 60178 60180 60182 60184 60186 60188 60190 60192 60194 60196 60198 60200 60202 60204 60206 60208 60210 60212 60214 60216 60218 60220 60222 60224 60226 60228 60230 60232 60234 60236 60238 60240 60242 60244 60246 60248 60250 60252 60254 60256 60258 60260 60262 60264 60266 60268 60270 60272 60274 60276 60278 60280 60282 60284 60286 109312 11136 11138 11140 11142 11144 11146 11148 11150 11152 11154 11156 11158 11160 11162 11164 11166 11168 11170 11172 11174 11176 11178 11180 11182 11184 11186 11188 11190 11192 11194 11196 11198 11200 11202 11204 11206 11208 11210 11212 11214 11216 11218 11220 11222 11224 11226 11228 11230 11232 11234 11236 11238 11240 11242 11244 11246 11248 11250 11252 11254 11256 11258 11260 11262 60288 60290 60292 60294 60296 60298 60300 60302 60304 60306 60308 60310 60312 60314 60316 60318 60320 60322 60324 60326 60328 60330 60332 60334 60336 60338 60340 60342 60344 60346 60348 60350 60352 60354 60356 60358 60360 60362 60364 60366 60368 60370 60372 60374 60376 60378 60380 60382 60384 60386 60388 60390 60392 60394 60396 60398 60400 60402 60404 60406 60408 60410 60412 60414 109440 11264 11266 11268 11270 11272 11274 11276 11278 11280 11282 11284 11286 11288 11290 11292 11294 11296 11298 11300 11302 11304 11306 11308 11310 11312 11314 11316 11318 11320 11322 11324 11326 11328 11330 11332 11334 11336 11338 11340 11342 11344 11346 11348 11350 11352 11354 11356 11358 11360 11362 11364 11366 11368 11370 11372 11374 11376 11378 11380 11382 11384 11386 11388 11390 60416 60418 60420 60422 60424 60426 60428 60430 60432 60434 60436 60438 60440 60442 60444 60446 60448 60450 60452 60454 60456 60458 60460 60462 60464 60466 60468 60470 60472 60474 60476 60478 60480 60482 60484 60486 60488 60490 60492 60494 60496 60498 60500 60502 60504 60506 60508 60510 60512 60514 60516 60518 60520 60522 60524 60526 60528 60530 60532 60534 60536 60538 60540 60542 109568 11392 11394 11396 11398 11400 11402 11404 11406 11408 11410 11412 11414 11416 11418 11420 11422 11424 11426 11428 11430 11432 11434 11436 11438 11440 11442 11444 11446 11448 11450 11452 11454 11456 11458 11460 11462 11464 11466 11468 11470 11472 11474 11476 11478 11480 11482 11484 11486 11488 11490 11492 11494 11496 11498 11500 11502 11504 11506 11508 11510 11512 11514 11516 11518 60544 60546 60548 60550 60552 60554 60556 60558 60560 60562 60564 60566 60568 60570 60572 60574 60576 60578 60580 60582 60584 60586 60588 60590 60592 60594 60596 60598 60600 60602 60604 60606 60608 60610 60612 60614 60616 60618 60620 60622 60624 60626 60628 60630 60632 60634 60636 60638 60640 60642 60644 60646 60648 60650 60652 60654 60656 60658 60660 60662 60664 60666 60668 60670 109696 11520 11522 11524 11526 11528 11530 11532 11534 11536 11538 11540 11542 11544 11546 11548 11550 11552 11554 11556 11558 11560 11562 11564 11566 11568 11570 11572 11574 11576 11578 11580 11582 11584 11586 11588 11590 11592 11594 11596 11598 11600 11602 11604 11606 11608 11610 11612 11614 11616 11618 11620 11622 11624 11626 11628 11630 11632 11634 11636 11638 11640 11642 11644 11646 60672 60674 60676 60678 60680 60682 60684 60686 60688 60690 60692 60694 60696 60698 60700 60702 60704 60706 60708 60710 60712 60714 60716 60718 60720 60722 60724 60726 60728 60730 60732 60734 60736 60738 60740 60742 60744 60746 60748 60750 60752 60754 60756 60758 60760 60762 60764 60766 60768 60770 60772 60774 60776 60778 60780 60782 60784 60786 60788 60790 60792 60794 60796 60798 109824 11648 11650 11652 11654 11656 11658 11660 11662 11664 11666 11668 11670 11672 11674 11676 11678 11680 11682 11684 11686 11688 11690 11692 11694 11696 11698 11700 11702 11704 11706 11708 11710 11712 11714 11716 11718 11720 11722 11724 11726 11728 11730 11732 11734 11736 11738 11740 11742 11744 11746 11748 11750 11752 11754 11756 11758 11760 11762 11764 11766 11768 11770 11772 11774 60800 60802 60804 60806 60808 60810 60812 60814 60816 60818 60820 60822 60824 60826 60828 60830 60832 60834 60836 60838 60840 60842 60844 60846 60848 60850 60852 60854 60856 60858 60860 60862 60864 60866 60868 60870 60872 60874 60876 60878 60880 60882 60884 60886 60888 60890 60892 60894 60896 60898 60900 60902 60904 60906 60908 60910 60912 60914 60916 60918 60920 60922 60924 60926 109952 11776 11778 11780 11782 11784 11786 11788 11790 11792 11794 11796 11798 11800 11802 11804 11806 11808 11810 11812 11814 11816 11818 11820 11822 11824 11826 11828 11830 11832 11834 11836 11838 11840 11842 11844 11846 11848 11850 11852 11854 11856 11858 11860 11862 11864 11866 11868 11870 11872 11874 11876 11878 11880 11882 11884 11886 11888 11890 11892 11894 11896 11898 11900 11902 60928 60930 60932 60934 60936 60938 60940 60942 60944 60946 60948 60950 60952 60954 60956 60958 60960 60962 60964 60966 60968 60970 60972 60974 60976 60978 60980 60982 60984 60986 60988 60990 60992 60994 60996 60998 61000 61002 61004 61006 61008 61010 61012 61014 61016 61018 61020 61022 61024 61026 61028 61030 61032 61034 61036 61038 61040 61042 61044 61046 61048 61050 61052 61054 110080 11904 11906 11908 11910 11912 11914 11916 11918 11920 11922 11924 11926 11928 11930 11932 11934 11936 11938 11940 11942 11944 11946 11948 11950 11952 11954 11956 11958 11960 11962 11964 11966 11968 11970 11972 11974 11976 11978 11980 11982 11984 11986 11988 11990 11992 11994 11996 11998 12000 12002 12004 12006 12008 12010 12012 12014 12016 12018 12020 12022 12024 12026 12028 12030 61056 61058 61060 61062 61064 61066 61068 61070 61072 61074 61076 61078 61080 61082 61084 61086 61088 61090 61092 61094 61096 61098 61100 61102 61104 61106 61108 61110 61112 61114 61116 61118 61120 61122 61124 61126 61128 61130 61132 61134 61136 61138 61140 61142 61144 61146 61148 61150 61152 61154 61156 61158 61160 61162 61164 61166 61168 61170 61172 61174 61176 61178 61180 61182 110208 12032 12034 12036 12038 12040 12042 12044 12046 12048 12050 12052 12054 12056 12058 12060 12062 12064 12066 12068 12070 12072 12074 12076 12078 12080 12082 12084 12086 12088 12090 12092 12094 12096 12098 12100 12102 12104 12106 12108 12110 12112 12114 12116 12118 12120 12122 12124 12126 12128 12130 12132 12134 12136 12138 12140 12142 12144 12146 12148 12150 12152 12154 12156 12158 61184 61186 61188 61190 61192 61194 61196 61198 61200 61202 61204 61206 61208 61210 61212 61214 61216 61218 61220 61222 61224 61226 61228 61230 61232 61234 61236 61238 61240 61242 61244 61246 61248 61250 61252 61254 61256 61258 61260 61262 61264 61266 61268 61270 61272 61274 61276 61278 61280 61282 61284 61286 61288 61290 61292 61294 61296 61298 61300 61302 61304 61306 61308 61310 110336 12160 12162 12164 12166 12168 12170 12172 12174 12176 12178 12180 12182 12184 12186 12188 12190 12192 12194 12196 12198 12200 12202 12204 12206 12208 12210 12212 12214 12216 12218 12220 12222 12224 12226 12228 12230 12232 12234 12236 12238 12240 12242 12244 12246 12248 12250 12252 12254 12256 12258 12260 12262 12264 12266 12268 12270 12272 12274 12276 12278 12280 12282 12284 12286 61312 61314 61316 61318 61320 61322 61324 61326 61328 61330 61332 61334 61336 61338 61340 61342 61344 61346 61348 61350 61352 61354 61356 61358 61360 61362 61364 61366 61368 61370 61372 61374 61376 61378 61380 61382 61384 61386 61388 61390 61392 61394 61396 61398 61400 61402 61404 61406 61408 61410 61412 61414 61416 61418 61420 61422 61424 61426 61428 61430 61432 61434 61436 61438 110464 12288 12290 12292 12294 12296 12298 12300 12302 12304 12306 12308 12310 12312 12314 12316 12318 12320 12322 12324 12326 12328 12330 12332 12334 12336 12338 12340 12342 12344 12346 12348 12350 12352 12354 12356 12358 12360 12362 12364 12366 12368 12370 12372 12374 12376 12378 12380 12382 12384 12386 12388 12390 12392 12394 12396 12398 12400 12402 12404 12406 12408 12410 12412 12414 61440 61442 61444 61446 61448 61450 61452 61454 61456 61458 61460 61462 61464 61466 61468 61470 61472 61474 61476 61478 61480 61482 61484 61486 61488 61490 61492 61494 61496 61498 61500 61502 61504 61506 61508 61510 61512 61514 61516 61518 61520 61522 61524 61526 61528 61530 61532 61534 61536 61538 61540 61542 61544 61546 61548 61550 61552 61554 61556 61558 61560 61562 61564 61566 110592 16384 16386 16388 16390 16392 16394 16396 16398 16400 16402 16404 16406 16408 16410 16412 16414 16416 16418 16420 16422 16424 16426 16428 16430 16432 16434 16436 16438 16440 16442 16444 16446 16448 16450 16452 16454 16456 16458 16460 16462 16464 16466 16468 16470 16472 16474 16476 16478 16480 16482 16484 16486 16488 16490 16492 16494 16496 16498 16500 16502 16504 16506 16508 16510 65536 65538 65540 65542 65544 65546 65548 65550 65552 65554 65556 65558 65560 65562 65564 65566 65568 65570 65572 65574 65576 65578 65580 65582 65584 65586 65588 65590 65592 65594 65596 65598 65600 65602 65604 65606 65608 65610 65612 65614 65616 65618 65620 65622 65624 65626 65628 65630 65632 65634 65636 65638 65640 65642 65644 65646 65648 65650 65652 65654 65656 65658 65660 65662 114688 16512 16514 16516 16518 16520 16522 16524 16526 16528 16530 16532 16534 16536 16538 16540 16542 16544 16546 16548 16550 16552 16554 16556 16558 16560 16562 16564 16566 16568 16570 16572 16574 16576 16578 16580 16582 16584 16586 16588 16590 16592 16594 16596 16598 16600 16602 16604 16606 16608 16610 16612 16614 16616 16618 16620 16622 16624 16626 16628 16630 16632 16634 16636 16638 65664 65666 65668 65670 65672 65674 65676 65678 65680 65682 65684 65686 65688 65690 65692 65694 65696 65698 65700 65702 65704 65706 65708 65710 65712 65714 65716 65718 65720 65722 65724 65726 65728 65730 65732 65734 65736 65738 65740 65742 65744 65746 65748 65750 65752 65754 65756 65758 65760 65762 65764 65766 65768 65770 65772 65774 65776 65778 65780 65782 65784 65786 65788 65790 114816 16640 16642 16644 16646 16648 16650 16652 16654 16656 16658 16660 16662 16664 16666 16668 16670 16672 16674 16676 16678 16680 16682 16684 16686 16688 16690 16692 16694 16696 16698 16700 16702 16704 16706 16708 16710 16712 16714 16716 16718 16720 16722 16724 16726 16728 16730 16732 16734 16736 16738 16740 16742 16744 16746 16748 16750 16752 16754 16756 16758 16760 16762 16764 16766 65792 65794 65796 65798 65800 65802 65804 65806 65808 65810 65812 65814 65816 65818 65820 65822 65824 65826 65828 65830 65832 65834 65836 65838 65840 65842 65844 65846 65848 65850 65852 65854 65856 65858 65860 65862 65864 65866 65868 65870 65872 65874 65876 65878 65880 65882 65884 65886 65888 65890 65892 65894 65896 65898 65900 65902 65904 65906 65908 65910 65912 65914 65916 65918 114944 16768 16770 16772 16774 16776 16778 16780 16782 16784 16786 16788 16790 16792 16794 16796 16798 16800 16802 16804 16806 16808 16810 16812 16814 16816 16818 16820 16822 16824 16826 16828 16830 16832 16834 16836 16838 16840 16842 16844 16846 16848 16850 16852 16854 16856 16858 16860 16862 16864 16866 16868 16870 16872 16874 16876 16878 16880 16882 16884 16886 16888 16890 16892 16894 65920 65922 65924 65926 65928 65930 65932 65934 65936 65938 65940 65942 65944 65946 65948 65950 65952 65954 65956 65958 65960 65962 65964 65966 65968 65970 65972 65974 65976 65978 65980 65982 65984 65986 65988 65990 65992 65994 65996 65998 66000 66002 66004 66006 66008 66010 66012 66014 66016 66018 66020 66022 66024 66026 66028 66030 66032 66034 66036 66038 66040 66042 66044 66046 115072 16896 16898 16900 16902 16904 16906 16908 16910 16912 16914 16916 16918 16920 16922 16924 16926 16928 16930 16932 16934 16936 16938 16940 16942 16944 16946 16948 16950 16952 16954 16956 16958 16960 16962 16964 16966 16968 16970 16972 16974 16976 16978 16980 16982 16984 16986 16988 16990 16992 16994 16996 16998 17000 17002 17004 17006 17008 17010 17012 17014 17016 17018 17020 17022 66048 66050 66052 66054 66056 66058 66060 66062 66064 66066 66068 66070 66072 66074 66076 66078 66080 66082 66084 66086 66088 66090 66092 66094 66096 66098 66100 66102 66104 66106 66108 66110 66112 66114 66116 66118 66120 66122 66124 66126 66128 66130 66132 66134 66136 66138 66140 66142 66144 66146 66148 66150 66152 66154 66156 66158 66160 66162 66164 66166 66168 66170 66172 66174 115200 17024 17026 17028 17030 17032 17034 17036 17038 17040 17042 17044 17046 17048 17050 17052 17054 17056 17058 17060 17062 17064 17066 17068 17070 17072 17074 17076 17078 17080 17082 17084 17086 17088 17090 17092 17094 17096 17098 17100 17102 17104 17106 17108 17110 17112 17114 17116 17118 17120 17122 17124 17126 17128 17130 17132 17134 17136 17138 17140 17142 17144 17146 17148 17150 66176 66178 66180 66182 66184 66186 66188 66190 66192 66194 66196 66198 66200 66202 66204 66206 66208 66210 66212 66214 66216 66218 66220 66222 66224 66226 66228 66230 66232 66234 66236 66238 66240 66242 66244 66246 66248 66250 66252 66254 66256 66258 66260 66262 66264 66266 66268 66270 66272 66274 66276 66278 66280 66282 66284 66286 66288 66290 66292 66294 66296 66298 66300 66302 115328 17152 17154 17156 17158 17160 17162 17164 17166 17168 17170 17172 17174 17176 17178 17180 17182 17184 17186 17188 17190 17192 17194 17196 17198 17200 17202 17204 17206 17208 17210 17212 17214 17216 17218 17220 17222 17224 17226 17228 17230 17232 17234 17236 17238 17240 17242 17244 17246 17248 17250 17252 17254 17256 17258 17260 17262 17264 17266 17268 17270 17272 17274 17276 17278 66304 66306 66308 66310 66312 66314 66316 66318 66320 66322 66324 66326 66328 66330 66332 66334 66336 66338 66340 66342 66344 66346 66348 66350 66352 66354 66356 66358 66360 66362 66364 66366 66368 66370 66372 66374 66376 66378 66380 66382 66384 66386 66388 66390 66392 66394 66396 66398 66400 66402 66404 66406 66408 66410 66412 66414 66416 66418 66420 66422 66424 66426 66428 66430 115456 17280 17282 17284 17286 17288 17290 17292 17294 17296 17298 17300 17302 17304 17306 17308 17310 17312 17314 17316 17318 17320 17322 17324 17326 17328 17330 17332 17334 17336 17338 17340 17342 17344 17346 17348 17350 17352 17354 17356 17358 17360 17362 17364 17366 17368 17370 17372 17374 17376 17378 17380 17382 17384 17386 17388 17390 17392 17394 17396 17398 17400 17402 17404 17406 66432 66434 66436 66438 66440 66442 66444 66446 66448 66450 66452 66454 66456 66458 66460 66462 66464 66466 66468 66470 66472 66474 66476 66478 66480 66482 66484 66486 66488 66490 66492 66494 66496 66498 66500 66502 66504 66506 66508 66510 66512 66514 66516 66518 66520 66522 66524 66526 66528 66530 66532 66534 66536 66538 66540 66542 66544 66546 66548 66550 66552 66554 66556 66558 115584 17408 17410 17412 17414 17416 17418 17420 17422 17424 17426 17428 17430 17432 17434 17436 17438 17440 17442 17444 17446 17448 17450 17452 17454 17456 17458 17460 17462 17464 17466 17468 17470 17472 17474 17476 17478 17480 17482 17484 17486 17488 17490 17492 17494 17496 17498 17500 17502 17504 17506 17508 17510 17512 17514 17516 17518 17520 17522 17524 17526 17528 17530 17532 17534 66560 66562 66564 66566 66568 66570 66572 66574 66576 66578 66580 66582 66584 66586 66588 66590 66592 66594 66596 66598 66600 66602 66604 66606 66608 66610 66612 66614 66616 66618 66620 66622 66624 66626 66628 66630 66632 66634 66636 66638 66640 66642 66644 66646 66648 66650 66652 66654 66656 66658 66660 66662 66664 66666 66668 66670 66672 66674 66676 66678 66680 66682 66684 66686 115712 17536 17538 17540 17542 17544 17546 17548 17550 17552 17554 17556 17558 17560 17562 17564 17566 17568 17570 17572 17574 17576 17578 17580 17582 17584 17586 17588 17590 17592 17594 17596 17598 17600 17602 17604 17606 17608 17610 17612 17614 17616 17618 17620 17622 17624 17626 17628 17630 17632 17634 17636 17638 17640 17642 17644 17646 17648 17650 17652 17654 17656 17658 17660 17662 66688 66690 66692 66694 66696 66698 66700 66702 66704 66706 66708 66710 66712 66714 66716 66718 66720 66722 66724 66726 66728 66730 66732 66734 66736 66738 66740 66742 66744 66746 66748 66750 66752 66754 66756 66758 66760 66762 66764 66766 66768 66770 66772 66774 66776 66778 66780 66782 66784 66786 66788 66790 66792 66794 66796 66798 66800 66802 66804 66806 66808 66810 66812 66814 115840 17664 17666 17668 17670 17672 17674 17676 17678 17680 17682 17684 17686 17688 17690 17692 17694 17696 17698 17700 17702 17704 17706 17708 17710 17712 17714 17716 17718 17720 17722 17724 17726 17728 17730 17732 17734 17736 17738 17740 17742 17744 17746 17748 17750 17752 17754 17756 17758 17760 17762 17764 17766 17768 17770 17772 17774 17776 17778 17780 17782 17784 17786 17788 17790 66816 66818 66820 66822 66824 66826 66828 66830 66832 66834 66836 66838 66840 66842 66844 66846 66848 66850 66852 66854 66856 66858 66860 66862 66864 66866 66868 66870 66872 66874 66876 66878 66880 66882 66884 66886 66888 66890 66892 66894 66896 66898 66900 66902 66904 66906 66908 66910 66912 66914 66916 66918 66920 66922 66924 66926 66928 66930 66932 66934 66936 66938 66940 66942 115968 17792 17794 17796 17798 17800 17802 17804 17806 17808 17810 17812 17814 17816 17818 17820 17822 17824 17826 17828 17830 17832 17834 17836 17838 17840 17842 17844 17846 17848 17850 17852 17854 17856 17858 17860 17862 17864 17866 17868 17870 17872 17874 17876 17878 17880 17882 17884 17886 17888 17890 17892 17894 17896 17898 17900 17902 17904 17906 17908 17910 17912 17914 17916 17918 66944 66946 66948 66950 66952 66954 66956 66958 66960 66962 66964 66966 66968 66970 66972 66974 66976 66978 66980 66982 66984 66986 66988 66990 66992 66994 66996 66998 67000 67002 67004 67006 67008 67010 67012 67014 67016 67018 67020 67022 67024 67026 67028 67030 67032 67034 67036 67038 67040 67042 67044 67046 67048 67050 67052 67054 67056 67058 67060 67062 67064 67066 67068 67070 116096 17920 17922 17924 17926 17928 17930 17932 17934 17936 17938 17940 17942 17944 17946 17948 17950 17952 17954 17956 17958 17960 17962 17964 17966 17968 17970 17972 17974 17976 17978 17980 17982 17984 17986 17988 17990 17992 17994 17996 17998 18000 18002 18004 18006 18008 18010 18012 18014 18016 18018 18020 18022 18024 18026 18028 18030 18032 18034 18036 18038 18040 18042 18044 18046 67072 67074 67076 67078 67080 67082 67084 67086 67088 67090 67092 67094 67096 67098 67100 67102 67104 67106 67108 67110 67112 67114 67116 67118 67120 67122 67124 67126 67128 67130 67132 67134 67136 67138 67140 67142 67144 67146 67148 67150 67152 67154 67156 67158 67160 67162 67164 67166 67168 67170 67172 67174 67176 67178 67180 67182 67184 67186 67188 67190 67192 67194 67196 67198 116224 18048 18050 18052 18054 18056 18058 18060 18062 18064 18066 18068 18070 18072 18074 18076 18078 18080 18082 18084 18086 18088 18090 18092 18094 18096 18098 18100 18102 18104 18106 18108 18110 18112 18114 18116 18118 18120 18122 18124 18126 18128 18130 18132 18134 18136 18138 18140 18142 18144 18146 18148 18150 18152 18154 18156 18158 18160 18162 18164 18166 18168 18170 18172 18174 67200 67202 67204 67206 67208 67210 67212 67214 67216 67218 67220 67222 67224 67226 67228 67230 67232 67234 67236 67238 67240 67242 67244 67246 67248 67250 67252 67254 67256 67258 67260 67262 67264 67266 67268 67270 67272 67274 67276 67278 67280 67282 67284 67286 67288 67290 67292 67294 67296 67298 67300 67302 67304 67306 67308 67310 67312 67314 67316 67318 67320 67322 67324 67326 116352 18176 18178 18180 18182 18184 18186 18188 18190 18192 18194 18196 18198 18200 18202 18204 18206 18208 18210 18212 18214 18216 18218 18220 18222 18224 18226 18228 18230 18232 18234 18236 18238 18240 18242 18244 18246 18248 18250 18252 18254 18256 18258 18260 18262 18264 18266 18268 18270 18272 18274 18276 18278 18280 18282 18284 18286 18288 18290 18292 18294 18296 18298 18300 18302 67328 67330 67332 67334 67336 67338 67340 67342 67344 67346 67348 67350 67352 67354 67356 67358 67360 67362 67364 67366 67368 67370 67372 67374 67376 67378 67380 67382 67384 67386 67388 67390 67392 67394 67396 67398 67400 67402 67404 67406 67408 67410 67412 67414 67416 67418 67420 67422 67424 67426 67428 67430 67432 67434 67436 67438 67440 67442 67444 67446 67448 67450 67452 67454 116480 18304 18306 18308 18310 18312 18314 18316 18318 18320 18322 18324 18326 18328 18330 18332 18334 18336 18338 18340 18342 18344 18346 18348 18350 18352 18354 18356 18358 18360 18362 18364 18366 18368 18370 18372 18374 18376 18378 18380 18382 18384 18386 18388 18390 18392 18394 18396 18398 18400 18402 18404 18406 18408 18410 18412 18414 18416 18418 18420 18422 18424 18426 18428 18430 67456 67458 67460 67462 67464 67466 67468 67470 67472 67474 67476 67478 67480 67482 67484 67486 67488 67490 67492 67494 67496 67498 67500 67502 67504 67506 67508 67510 67512 67514 67516 67518 67520 67522 67524 67526 67528 67530 67532 67534 67536 67538 67540 67542 67544 67546 67548 67550 67552 67554 67556 67558 67560 67562 67564 67566 67568 67570 67572 67574 67576 67578 67580 67582 116608 18432 18434 18436 18438 18440 18442 18444 18446 18448 18450 18452 18454 18456 18458 18460 18462 18464 18466 18468 18470 18472 18474 18476 18478 18480 18482 18484 18486 18488 18490 18492 18494 18496 18498 18500 18502 18504 18506 18508 18510 18512 18514 18516 18518 18520 18522 18524 18526 18528 18530 18532 18534 18536 18538 18540 18542 18544 18546 18548 18550 18552 18554 18556 18558 67584 67586 67588 67590 67592 67594 67596 67598 67600 67602 67604 67606 67608 67610 67612 67614 67616 67618 67620 67622 67624 67626 67628 67630 67632 67634 67636 67638 67640 67642 67644 67646 67648 67650 67652 67654 67656 67658 67660 67662 67664 67666 67668 67670 67672 67674 67676 67678 67680 67682 67684 67686 67688 67690 67692 67694 67696 67698 67700 67702 67704 67706 67708 67710 116736 18560 18562 18564 18566 18568 18570 18572 18574 18576 18578 18580 18582 18584 18586 18588 18590 18592 18594 18596 18598 18600 18602 18604 18606 18608 18610 18612 18614 18616 18618 18620 18622 18624 18626 18628 18630 18632 18634 18636 18638 18640 18642 18644 18646 18648 18650 18652 18654 18656 18658 18660 18662 18664 18666 18668 18670 18672 18674 18676 18678 18680 18682 18684 18686 67712 67714 67716 67718 67720 67722 67724 67726 67728 67730 67732 67734 67736 67738 67740 67742 67744 67746 67748 67750 67752 67754 67756 67758 67760 67762 67764 67766 67768 67770 67772 67774 67776 67778 67780 67782 67784 67786 67788 67790 67792 67794 67796 67798 67800 67802 67804 67806 67808 67810 67812 67814 67816 67818 67820 67822 67824 67826 67828 67830 67832 67834 67836 67838 116864 18688 18690 18692 18694 18696 18698 18700 18702 18704 18706 18708 18710 18712 18714 18716 18718 18720 18722 18724 18726 18728 18730 18732 18734 18736 18738 18740 18742 18744 18746 18748 18750 18752 18754 18756 18758 18760 18762 18764 18766 18768 18770 18772 18774 18776 18778 18780 18782 18784 18786 18788 18790 18792 18794 18796 18798 18800 18802 18804 18806 18808 18810 18812 18814 67840 67842 67844 67846 67848 67850 67852 67854 67856 67858 67860 67862 67864 67866 67868 67870 67872 67874 67876 67878 67880 67882 67884 67886 67888 67890 67892 67894 67896 67898 67900 67902 67904 67906 67908 67910 67912 67914 67916 67918 67920 67922 67924 67926 67928 67930 67932 67934 67936 67938 67940 67942 67944 67946 67948 67950 67952 67954 67956 67958 67960 67962 67964 67966 116992 18816 18818 18820 18822 18824 18826 18828 18830 18832 18834 18836 18838 18840 18842 18844 18846 18848 18850 18852 18854 18856 18858 18860 18862 18864 18866 18868 18870 18872 18874 18876 18878 18880 18882 18884 18886 18888 18890 18892 18894 18896 18898 18900 18902 18904 18906 18908 18910 18912 18914 18916 18918 18920 18922 18924 18926 18928 18930 18932 18934 18936 18938 18940 18942 67968 67970 67972 67974 67976 67978 67980 67982 67984 67986 67988 67990 67992 67994 67996 67998 68000 68002 68004 68006 68008 68010 68012 68014 68016 68018 68020 68022 68024 68026 68028 68030 68032 68034 68036 68038 68040 68042 68044 68046 68048 68050 68052 68054 68056 68058 68060 68062 68064 68066 68068 68070 68072 68074 68076 68078 68080 68082 68084 68086 68088 68090 68092 68094 117120 18944 18946 18948 18950 18952 18954 18956 18958 18960 18962 18964 18966 18968 18970 18972 18974 18976 18978 18980 18982 18984 18986 18988 18990 18992 18994 18996 18998 19000 19002 19004 19006 19008 19010 19012 19014 19016 19018 19020 19022 19024 19026 19028 19030 19032 19034 19036 19038 19040 19042 19044 19046 19048 19050 19052 19054 19056 19058 19060 19062 19064 19066 19068 19070 68096 68098 68100 68102 68104 68106 68108 68110 68112 68114 68116 68118 68120 68122 68124 68126 68128 68130 68132 68134 68136 68138 68140 68142 68144 68146 68148 68150 68152 68154 68156 68158 68160 68162 68164 68166 68168 68170 68172 68174 68176 68178 68180 68182 68184 68186 68188 68190 68192 68194 68196 68198 68200 68202 68204 68206 68208 68210 68212 68214 68216 68218 68220 68222 117248 19072 19074 19076 19078 19080 19082 19084 19086 19088 19090 19092 19094 19096 19098 19100 19102 19104 19106 19108 19110 19112 19114 19116 19118 19120 19122 19124 19126 19128 19130 19132 19134 19136 19138 19140 19142 19144 19146 19148 19150 19152 19154 19156 19158 19160 19162 19164 19166 19168 19170 19172 19174 19176 19178 19180 19182 19184 19186 19188 19190 19192 19194 19196 19198 68224 68226 68228 68230 68232 68234 68236 68238 68240 68242 68244 68246 68248 68250 68252 68254 68256 68258 68260 68262 68264 68266 68268 68270 68272 68274 68276 68278 68280 68282 68284 68286 68288 68290 68292 68294 68296 68298 68300 68302 68304 68306 68308 68310 68312 68314 68316 68318 68320 68322 68324 68326 68328 68330 68332 68334 68336 68338 68340 68342 68344 68346 68348 68350 117376 19200 19202 19204 19206 19208 19210 19212 19214 19216 19218 19220 19222 19224 19226 19228 19230 19232 19234 19236 19238 19240 19242 19244 19246 19248 19250 19252 19254 19256 19258 19260 19262 19264 19266 19268 19270 19272 19274 19276 19278 19280 19282 19284 19286 19288 19290 19292 19294 19296 19298 19300 19302 19304 19306 19308 19310 19312 19314 19316 19318 19320 19322 19324 19326 68352 68354 68356 68358 68360 68362 68364 68366 68368 68370 68372 68374 68376 68378 68380 68382 68384 68386 68388 68390 68392 68394 68396 68398 68400 68402 68404 68406 68408 68410 68412 68414 68416 68418 68420 68422 68424 68426 68428 68430 68432 68434 68436 68438 68440 68442 68444 68446 68448 68450 68452 68454 68456 68458 68460 68462 68464 68466 68468 68470 68472 68474 68476 68478 117504 19328 19330 19332 19334 19336 19338 19340 19342 19344 19346 19348 19350 19352 19354 19356 19358 19360 19362 19364 19366 19368 19370 19372 19374 19376 19378 19380 19382 19384 19386 19388 19390 19392 19394 19396 19398 19400 19402 19404 19406 19408 19410 19412 19414 19416 19418 19420 19422 19424 19426 19428 19430 19432 19434 19436 19438 19440 19442 19444 19446 19448 19450 19452 19454 68480 68482 68484 68486 68488 68490 68492 68494 68496 68498 68500 68502 68504 68506 68508 68510 68512 68514 68516 68518 68520 68522 68524 68526 68528 68530 68532 68534 68536 68538 68540 68542 68544 68546 68548 68550 68552 68554 68556 68558 68560 68562 68564 68566 68568 68570 68572 68574 68576 68578 68580 68582 68584 68586 68588 68590 68592 68594 68596 68598 68600 68602 68604 68606 117632 19456 19458 19460 19462 19464 19466 19468 19470 19472 19474 19476 19478 19480 19482 19484 19486 19488 19490 19492 19494 19496 19498 19500 19502 19504 19506 19508 19510 19512 19514 19516 19518 19520 19522 19524 19526 19528 19530 19532 19534 19536 19538 19540 19542 19544 19546 19548 19550 19552 19554 19556 19558 19560 19562 19564 19566 19568 19570 19572 19574 19576 19578 19580 19582 68608 68610 68612 68614 68616 68618 68620 68622 68624 68626 68628 68630 68632 68634 68636 68638 68640 68642 68644 68646 68648 68650 68652 68654 68656 68658 68660 68662 68664 68666 68668 68670 68672 68674 68676 68678 68680 68682 68684 68686 68688 68690 68692 68694 68696 68698 68700 68702 68704 68706 68708 68710 68712 68714 68716 68718 68720 68722 68724 68726 68728 68730 68732 68734 117760 19584 19586 19588 19590 19592 19594 19596 19598 19600 19602 19604 19606 19608 19610 19612 19614 19616 19618 19620 19622 19624 19626 19628 19630 19632 19634 19636 19638 19640 19642 19644 19646 19648 19650 19652 19654 19656 19658 19660 19662 19664 19666 19668 19670 19672 19674 19676 19678 19680 19682 19684 19686 19688 19690 19692 19694 19696 19698 19700 19702 19704 19706 19708 19710 68736 68738 68740 68742 68744 68746 68748 68750 68752 68754 68756 68758 68760 68762 68764 68766 68768 68770 68772 68774 68776 68778 68780 68782 68784 68786 68788 68790 68792 68794 68796 68798 68800 68802 68804 68806 68808 68810 68812 68814 68816 68818 68820 68822 68824 68826 68828 68830 68832 68834 68836 68838 68840 68842 68844 68846 68848 68850 68852 68854 68856 68858 68860 68862 117888 19712 19714 19716 19718 19720 19722 19724 19726 19728 19730 19732 19734 19736 19738 19740 19742 19744 19746 19748 19750 19752 19754 19756 19758 19760 19762 19764 19766 19768 19770 19772 19774 19776 19778 19780 19782 19784 19786 19788 19790 19792 19794 19796 19798 19800 19802 19804 19806 19808 19810 19812 19814 19816 19818 19820 19822 19824 19826 19828 19830 19832 19834 19836 19838 68864 68866 68868 68870 68872 68874 68876 68878 68880 68882 68884 68886 68888 68890 68892 68894 68896 68898 68900 68902 68904 68906 68908 68910 68912 68914 68916 68918 68920 68922 68924 68926 68928 68930 68932 68934 68936 68938 68940 68942 68944 68946 68948 68950 68952 68954 68956 68958 68960 68962 68964 68966 68968 68970 68972 68974 68976 68978 68980 68982 68984 68986 68988 68990 118016 19840 19842 19844 19846 19848 19850 19852 19854 19856 19858 19860 19862 19864 19866 19868 19870 19872 19874 19876 19878 19880 19882 19884 19886 19888 19890 19892 19894 19896 19898 19900 19902 19904 19906 19908 19910 19912 19914 19916 19918 19920 19922 19924 19926 19928 19930 19932 19934 19936 19938 19940 19942 19944 19946 19948 19950 19952 19954 19956 19958 19960 19962 19964 19966 68992 68994 68996 68998 69000 69002 69004 69006 69008 69010 69012 69014 69016 69018 69020 69022 69024 69026 69028 69030 69032 69034 69036 69038 69040 69042 69044 69046 69048 69050 69052 69054 69056 69058 69060 69062 69064 69066 69068 69070 69072 69074 69076 69078 69080 69082 69084 69086 69088 69090 69092 69094 69096 69098 69100 69102 69104 69106 69108 69110 69112 69114 69116 69118 118144 19968 19970 19972 19974 19976 19978 19980 19982 19984 19986 19988 19990 19992 19994 19996 19998 20000 20002 20004 20006 20008 20010 20012 20014 20016 20018 20020 20022 20024 20026 20028 20030 20032 20034 20036 20038 20040 20042 20044 20046 20048 20050 20052 20054 20056 20058 20060 20062 20064 20066 20068 20070 20072 20074 20076 20078 20080 20082 20084 20086 20088 20090 20092 20094 69120 69122 69124 69126 69128 69130 69132 69134 69136 69138 69140 69142 69144 69146 69148 69150 69152 69154 69156 69158 69160 69162 69164 69166 69168 69170 69172 69174 69176 69178 69180 69182 69184 69186 69188 69190 69192 69194 69196 69198 69200 69202 69204 69206 69208 69210 69212 69214 69216 69218 69220 69222 69224 69226 69228 69230 69232 69234 69236 69238 69240 69242 69244 69246 118272 20096 20098 20100 20102 20104 20106 20108 20110 20112 20114 20116 20118 20120 20122 20124 20126 20128 20130 20132 20134 20136 20138 20140 20142 20144 20146 20148 20150 20152 20154 20156 20158 20160 20162 20164 20166 20168 20170 20172 20174 20176 20178 20180 20182 20184 20186 20188 20190 20192 20194 20196 20198 20200 20202 20204 20206 20208 20210 20212 20214 20216 20218 20220 20222 69248 69250 69252 69254 69256 69258 69260 69262 69264 69266 69268 69270 69272 69274 69276 69278 69280 69282 69284 69286 69288 69290 69292 69294 69296 69298 69300 69302 69304 69306 69308 69310 69312 69314 69316 69318 69320 69322 69324 69326 69328 69330 69332 69334 69336 69338 69340 69342 69344 69346 69348 69350 69352 69354 69356 69358 69360 69362 69364 69366 69368 69370 69372 69374 118400 20224 20226 20228 20230 20232 20234 20236 20238 20240 20242 20244 20246 20248 20250 20252 20254 20256 20258 20260 20262 20264 20266 20268 20270 20272 20274 20276 20278 20280 20282 20284 20286 20288 20290 20292 20294 20296 20298 20300 20302 20304 20306 20308 20310 20312 20314 20316 20318 20320 20322 20324 20326 20328 20330 20332 20334 20336 20338 20340 20342 20344 20346 20348 20350 69376 69378 69380 69382 69384 69386 69388 69390 69392 69394 69396 69398 69400 69402 69404 69406 69408 69410 69412 69414 69416 69418 69420 69422 69424 69426 69428 69430 69432 69434 69436 69438 69440 69442 69444 69446 69448 69450 69452 69454 69456 69458 69460 69462 69464 69466 69468 69470 69472 69474 69476 69478 69480 69482 69484 69486 69488 69490 69492 69494 69496 69498 69500 69502 118528 20352 20354 20356 20358 20360 20362 20364 20366 20368 20370 20372 20374 20376 20378 20380 20382 20384 20386 20388 20390 20392 20394 20396 20398 20400 20402 20404 20406 20408 20410 20412 20414 20416 20418 20420 20422 20424 20426 20428 20430 20432 20434 20436 20438 20440 20442 20444 20446 20448 20450 20452 20454 20456 20458 20460 20462 20464 20466 20468 20470 20472 20474 20476 20478 69504 69506 69508 69510 69512 69514 69516 69518 69520 69522 69524 69526 69528 69530 69532 69534 69536 69538 69540 69542 69544 69546 69548 69550 69552 69554 69556 69558 69560 69562 69564 69566 69568 69570 69572 69574 69576 69578 69580 69582 69584 69586 69588 69590 69592 69594 69596 69598 69600 69602 69604 69606 69608 69610 69612 69614 69616 69618 69620 69622 69624 69626 69628 69630 118656 20480 20482 20484 20486 20488 20490 20492 20494 20496 20498 20500 20502 20504 20506 20508 20510 20512 20514 20516 20518 20520 20522 20524 20526 20528 20530 20532 20534 20536 20538 20540 20542 20544 20546 20548 20550 20552 20554 20556 20558 20560 20562 20564 20566 20568 20570 20572 20574 20576 20578 20580 20582 20584 20586 20588 20590 20592 20594 20596 20598 20600 20602 20604 20606 69632 69634 69636 69638 69640 69642 69644 69646 69648 69650 69652 69654 69656 69658 69660 69662 69664 69666 69668 69670 69672 69674 69676 69678 69680 69682 69684 69686 69688 69690 69692 69694 69696 69698 69700 69702 69704 69706 69708 69710 69712 69714 69716 69718 69720 69722 69724 69726 69728 69730 69732 69734 69736 69738 69740 69742 69744 69746 69748 69750 69752 69754 69756 69758 118784 24576 24578 24580 24582 24584 24586 24588 24590 24592 24594 24596 24598 24600 24602 24604 24606 24608 24610 24612 24614 24616 24618 24620 24622 24624 24626 24628 24630 24632 24634 24636 24638 24640 24642 24644 24646 24648 24650 24652 24654 24656 24658 24660 24662 24664 24666 24668 24670 24672 24674 24676 24678 24680 24682 24684 24686 24688 24690 24692 24694 24696 24698 24700 24702 73728 73730 73732 73734 73736 73738 73740 73742 73744 73746 73748 73750 73752 73754 73756 73758 73760 73762 73764 73766 73768 73770 73772 73774 73776 73778 73780 73782 73784 73786 73788 73790 73792 73794 73796 73798 73800 73802 73804 73806 73808 73810 73812 73814 73816 73818 73820 73822 73824 73826 73828 73830 73832 73834 73836 73838 73840 73842 73844 73846 73848 73850 73852 73854 122880 24704 24706 24708 24710 24712 24714 24716 24718 24720 24722 24724 24726 24728 24730 24732 24734 24736 24738 24740 24742 24744 24746 24748 24750 24752 24754 24756 24758 24760 24762 24764 24766 24768 24770 24772 24774 24776 24778 24780 24782 24784 24786 24788 24790 24792 24794 24796 24798 24800 24802 24804 24806 24808 24810 24812 24814 24816 24818 24820 24822 24824 24826 24828 24830 73856 73858 73860 73862 73864 73866 73868 73870 73872 73874 73876 73878 73880 73882 73884 73886 73888 73890 73892 73894 73896 73898 73900 73902 73904 73906 73908 73910 73912 73914 73916 73918 73920 73922 73924 73926 73928 73930 73932 73934 73936 73938 73940 73942 73944 73946 73948 73950 73952 73954 73956 73958 73960 73962 73964 73966 73968 73970 73972 73974 73976 73978 73980 73982 123008 24832 24834 24836 24838 24840 24842 24844 24846 24848 24850 24852 24854 24856 24858 24860 24862 24864 24866 24868 24870 24872 24874 24876 24878 24880 24882 24884 24886 24888 24890 24892 24894 24896 24898 24900 24902 24904 24906 24908 24910 24912 24914 24916 24918 24920 24922 24924 24926 24928 24930 24932 24934 24936 24938 24940 24942 24944 24946 24948 24950 24952 24954 24956 24958 73984 73986 73988 73990 73992 73994 73996 73998 74000 74002 74004 74006 74008 74010 74012 74014 74016 74018 74020 74022 74024 74026 74028 74030 74032 74034 74036 74038 74040 74042 74044 74046 74048 74050 74052 74054 74056 74058 74060 74062 74064 74066 74068 74070 74072 74074 74076 74078 74080 74082 74084 74086 74088 74090 74092 74094 74096 74098 74100 74102 74104 74106 74108 74110 123136 24960 24962 24964 24966 24968 24970 24972 24974 24976 24978 24980 24982 24984 24986 24988 24990 24992 24994 24996 24998 25000 25002 25004 25006 25008 25010 25012 25014 25016 25018 25020 25022 25024 25026 25028 25030 25032 25034 25036 25038 25040 25042 25044 25046 25048 25050 25052 25054 25056 25058 25060 25062 25064 25066 25068 25070 25072 25074 25076 25078 25080 25082 25084 25086 74112 74114 74116 74118 74120 74122 74124 74126 74128 74130 74132 74134 74136 74138 74140 74142 74144 74146 74148 74150 74152 74154 74156 74158 74160 74162 74164 74166 74168 74170 74172 74174 74176 74178 74180 74182 74184 74186 74188 74190 74192 74194 74196 74198 74200 74202 74204 74206 74208 74210 74212 74214 74216 74218 74220 74222 74224 74226 74228 74230 74232 74234 74236 74238 123264 25088 25090 25092 25094 25096 25098 25100 25102 25104 25106 25108 25110 25112 25114 25116 25118 25120 25122 25124 25126 25128 25130 25132 25134 25136 25138 25140 25142 25144 25146 25148 25150 25152 25154 25156 25158 25160 25162 25164 25166 25168 25170 25172 25174 25176 25178 25180 25182 25184 25186 25188 25190 25192 25194 25196 25198 25200 25202 25204 25206 25208 25210 25212 25214 74240 74242 74244 74246 74248 74250 74252 74254 74256 74258 74260 74262 74264 74266 74268 74270 74272 74274 74276 74278 74280 74282 74284 74286 74288 74290 74292 74294 74296 74298 74300 74302 74304 74306 74308 74310 74312 74314 74316 74318 74320 74322 74324 74326 74328 74330 74332 74334 74336 74338 74340 74342 74344 74346 74348 74350 74352 74354 74356 74358 74360 74362 74364 74366 123392 25216 25218 25220 25222 25224 25226 25228 25230 25232 25234 25236 25238 25240 25242 25244 25246 25248 25250 25252 25254 25256 25258 25260 25262 25264 25266 25268 25270 25272 25274 25276 25278 25280 25282 25284 25286 25288 25290 25292 25294 25296 25298 25300 25302 25304 25306 25308 25310 25312 25314 25316 25318 25320 25322 25324 25326 25328 25330 25332 25334 25336 25338 25340 25342 74368 74370 74372 74374 74376 74378 74380 74382 74384 74386 74388 74390 74392 74394 74396 74398 74400 74402 74404 74406 74408 74410 74412 74414 74416 74418 74420 74422 74424 74426 74428 74430 74432 74434 74436 74438 74440 74442 74444 74446 74448 74450 74452 74454 74456 74458 74460 74462 74464 74466 74468 74470 74472 74474 74476 74478 74480 74482 74484 74486 74488 74490 74492 74494 123520 25344 25346 25348 25350 25352 25354 25356 25358 25360 25362 25364 25366 25368 25370 25372 25374 25376 25378 25380 25382 25384 25386 25388 25390 25392 25394 25396 25398 25400 25402 25404 25406 25408 25410 25412 25414 25416 25418 25420 25422 25424 25426 25428 25430 25432 25434 25436 25438 25440 25442 25444 25446 25448 25450 25452 25454 25456 25458 25460 25462 25464 25466 25468 25470 74496 74498 74500 74502 74504 74506 74508 74510 74512 74514 74516 74518 74520 74522 74524 74526 74528 74530 74532 74534 74536 74538 74540 74542 74544 74546 74548 74550 74552 74554 74556 74558 74560 74562 74564 74566 74568 74570 74572 74574 74576 74578 74580 74582 74584 74586 74588 74590 74592 74594 74596 74598 74600 74602 74604 74606 74608 74610 74612 74614 74616 74618 74620 74622 123648 25472 25474 25476 25478 25480 25482 25484 25486 25488 25490 25492 25494 25496 25498 25500 25502 25504 25506 25508 25510 25512 25514 25516 25518 25520 25522 25524 25526 25528 25530 25532 25534 25536 25538 25540 25542 25544 25546 25548 25550 25552 25554 25556 25558 25560 25562 25564 25566 25568 25570 25572 25574 25576 25578 25580 25582 25584 25586 25588 25590 25592 25594 25596 25598 74624 74626 74628 74630 74632 74634 74636 74638 74640 74642 74644 74646 74648 74650 74652 74654 74656 74658 74660 74662 74664 74666 74668 74670 74672 74674 74676 74678 74680 74682 74684 74686 74688 74690 74692 74694 74696 74698 74700 74702 74704 74706 74708 74710 74712 74714 74716 74718 74720 74722 74724 74726 74728 74730 74732 74734 74736 74738 74740 74742 74744 74746 74748 74750 123776 25600 25602 25604 25606 25608 25610 25612 25614 25616 25618 25620 25622 25624 25626 25628 25630 25632 25634 25636 25638 25640 25642 25644 25646 25648 25650 25652 25654 25656 25658 25660 25662 25664 25666 25668 25670 25672 25674 25676 25678 25680 25682 25684 25686 25688 25690 25692 25694 25696 25698 25700 25702 25704 25706 25708 25710 25712 25714 25716 25718 25720 25722 25724 25726 74752 74754 74756 74758 74760 74762 74764 74766 74768 74770 74772 74774 74776 74778 74780 74782 74784 74786 74788 74790 74792 74794 74796 74798 74800 74802 74804 74806 74808 74810 74812 74814 74816 74818 74820 74822 74824 74826 74828 74830 74832 74834 74836 74838 74840 74842 74844 74846 74848 74850 74852 74854 74856 74858 74860 74862 74864 74866 74868 74870 74872 74874 74876 74878 123904 25728 25730 25732 25734 25736 25738 25740 25742 25744 25746 25748 25750 25752 25754 25756 25758 25760 25762 25764 25766 25768 25770 25772 25774 25776 25778 25780 25782 25784 25786 25788 25790 25792 25794 25796 25798 25800 25802 25804 25806 25808 25810 25812 25814 25816 25818 25820 25822 25824 25826 25828 25830 25832 25834 25836 25838 25840 25842 25844 25846 25848 25850 25852 25854 74880 74882 74884 74886 74888 74890 74892 74894 74896 74898 74900 74902 74904 74906 74908 74910 74912 74914 74916 74918 74920 74922 74924 74926 74928 74930 74932 74934 74936 74938 74940 74942 74944 74946 74948 74950 74952 74954 74956 74958 74960 74962 74964 74966 74968 74970 74972 74974 74976 74978 74980 74982 74984 74986 74988 74990 74992 74994 74996 74998 75000 75002 75004 75006 124032 25856 25858 25860 25862 25864 25866 25868 25870 25872 25874 25876 25878 25880 25882 25884 25886 25888 25890 25892 25894 25896 25898 25900 25902 25904 25906 25908 25910 25912 25914 25916 25918 25920 25922 25924 25926 25928 25930 25932 25934 25936 25938 25940 25942 25944 25946 25948 25950 25952 25954 25956 25958 25960 25962 25964 25966 25968 25970 25972 25974 25976 25978 25980 25982 75008 75010 75012 75014 75016 75018 75020 75022 75024 75026 75028 75030 75032 75034 75036 75038 75040 75042 75044 75046 75048 75050 75052 75054 75056 75058 75060 75062 75064 75066 75068 75070 75072 75074 75076 75078 75080 75082 75084 75086 75088 75090 75092 75094 75096 75098 75100 75102 75104 75106 75108 75110 75112 75114 75116 75118 75120 75122 75124 75126 75128 75130 75132 75134 124160 25984 25986 25988 25990 25992 25994 25996 25998 26000 26002 26004 26006 26008 26010 26012 26014 26016 26018 26020 26022 26024 26026 26028 26030 26032 26034 26036 26038 26040 26042 26044 26046 26048 26050 26052 26054 26056 26058 26060 26062 26064 26066 26068 26070 26072 26074 26076 26078 26080 26082 26084 26086 26088 26090 26092 26094 26096 26098 26100 26102 26104 26106 26108 26110 75136 75138 75140 75142 75144 75146 75148 75150 75152 75154 75156 75158 75160 75162 75164 75166 75168 75170 75172 75174 75176 75178 75180 75182 75184 75186 75188 75190 75192 75194 75196 75198 75200 75202 75204 75206 75208 75210 75212 75214 75216 75218 75220 75222 75224 75226 75228 75230 75232 75234 75236 75238 75240 75242 75244 75246 75248 75250 75252 75254 75256 75258 75260 75262 124288 26112 26114 26116 26118 26120 26122 26124 26126 26128 26130 26132 26134 26136 26138 26140 26142 26144 26146 26148 26150 26152 26154 26156 26158 26160 26162 26164 26166 26168 26170 26172 26174 26176 26178 26180 26182 26184 26186 26188 26190 26192 26194 26196 26198 26200 26202 26204 26206 26208 26210 26212 26214 26216 26218 26220 26222 26224 26226 26228 26230 26232 26234 26236 26238 75264 75266 75268 75270 75272 75274 75276 75278 75280 75282 75284 75286 75288 75290 75292 75294 75296 75298 75300 75302 75304 75306 75308 75310 75312 75314 75316 75318 75320 75322 75324 75326 75328 75330 75332 75334 75336 75338 75340 75342 75344 75346 75348 75350 75352 75354 75356 75358 75360 75362 75364 75366 75368 75370 75372 75374 75376 75378 75380 75382 75384 75386 75388 75390 124416 26240 26242 26244 26246 26248 26250 26252 26254 26256 26258 26260 26262 26264 26266 26268 26270 26272 26274 26276 26278 26280 26282 26284 26286 26288 26290 26292 26294 26296 26298 26300 26302 26304 26306 26308 26310 26312 26314 26316 26318 26320 26322 26324 26326 26328 26330 26332 26334 26336 26338 26340 26342 26344 26346 26348 26350 26352 26354 26356 26358 26360 26362 26364 26366 75392 75394 75396 75398 75400 75402 75404 75406 75408 75410 75412 75414 75416 75418 75420 75422 75424 75426 75428 75430 75432 75434 75436 75438 75440 75442 75444 75446 75448 75450 75452 75454 75456 75458 75460 75462 75464 75466 75468 75470 75472 75474 75476 75478 75480 75482 75484 75486 75488 75490 75492 75494 75496 75498 75500 75502 75504 75506 75508 75510 75512 75514 75516 75518 124544 26368 26370 26372 26374 26376 26378 26380 26382 26384 26386 26388 26390 26392 26394 26396 26398 26400 26402 26404 26406 26408 26410 26412 26414 26416 26418 26420 26422 26424 26426 26428 26430 26432 26434 26436 26438 26440 26442 26444 26446 26448 26450 26452 26454 26456 26458 26460 26462 26464 26466 26468 26470 26472 26474 26476 26478 26480 26482 26484 26486 26488 26490 26492 26494 75520 75522 75524 75526 75528 75530 75532 75534 75536 75538 75540 75542 75544 75546 75548 75550 75552 75554 75556 75558 75560 75562 75564 75566 75568 75570 75572 75574 75576 75578 75580 75582 75584 75586 75588 75590 75592 75594 75596 75598 75600 75602 75604 75606 75608 75610 75612 75614 75616 75618 75620 75622 75624 75626 75628 75630 75632 75634 75636 75638 75640 75642 75644 75646 124672 26496 26498 26500 26502 26504 26506 26508 26510 26512 26514 26516 26518 26520 26522 26524 26526 26528 26530 26532 26534 26536 26538 26540 26542 26544 26546 26548 26550 26552 26554 26556 26558 26560 26562 26564 26566 26568 26570 26572 26574 26576 26578 26580 26582 26584 26586 26588 26590 26592 26594 26596 26598 26600 26602 26604 26606 26608 26610 26612 26614 26616 26618 26620 26622 75648 75650 75652 75654 75656 75658 75660 75662 75664 75666 75668 75670 75672 75674 75676 75678 75680 75682 75684 75686 75688 75690 75692 75694 75696 75698 75700 75702 75704 75706 75708 75710 75712 75714 75716 75718 75720 75722 75724 75726 75728 75730 75732 75734 75736 75738 75740 75742 75744 75746 75748 75750 75752 75754 75756 75758 75760 75762 75764 75766 75768 75770 75772 75774 124800 26624 26626 26628 26630 26632 26634 26636 26638 26640 26642 26644 26646 26648 26650 26652 26654 26656 26658 26660 26662 26664 26666 26668 26670 26672 26674 26676 26678 26680 26682 26684 26686 26688 26690 26692 26694 26696 26698 26700 26702 26704 26706 26708 26710 26712 26714 26716 26718 26720 26722 26724 26726 26728 26730 26732 26734 26736 26738 26740 26742 26744 26746 26748 26750 75776 75778 75780 75782 75784 75786 75788 75790 75792 75794 75796 75798 75800 75802 75804 75806 75808 75810 75812 75814 75816 75818 75820 75822 75824 75826 75828 75830 75832 75834 75836 75838 75840 75842 75844 75846 75848 75850 75852 75854 75856 75858 75860 75862 75864 75866 75868 75870 75872 75874 75876 75878 75880 75882 75884 75886 75888 75890 75892 75894 75896 75898 75900 75902 124928 26752 26754 26756 26758 26760 26762 26764 26766 26768 26770 26772 26774 26776 26778 26780 26782 26784 26786 26788 26790 26792 26794 26796 26798 26800 26802 26804 26806 26808 26810 26812 26814 26816 26818 26820 26822 26824 26826 26828 26830 26832 26834 26836 26838 26840 26842 26844 26846 26848 26850 26852 26854 26856 26858 26860 26862 26864 26866 26868 26870 26872 26874 26876 26878 75904 75906 75908 75910 75912 75914 75916 75918 75920 75922 75924 75926 75928 75930 75932 75934 75936 75938 75940 75942 75944 75946 75948 75950 75952 75954 75956 75958 75960 75962 75964 75966 75968 75970 75972 75974 75976 75978 75980 75982 75984 75986 75988 75990 75992 75994 75996 75998 76000 76002 76004 76006 76008 76010 76012 76014 76016 76018 76020 76022 76024 76026 76028 76030 125056 26880 26882 26884 26886 26888 26890 26892 26894 26896 26898 26900 26902 26904 26906 26908 26910 26912 26914 26916 26918 26920 26922 26924 26926 26928 26930 26932 26934 26936 26938 26940 26942 26944 26946 26948 26950 26952 26954 26956 26958 26960 26962 26964 26966 26968 26970 26972 26974 26976 26978 26980 26982 26984 26986 26988 26990 26992 26994 26996 26998 27000 27002 27004 27006 76032 76034 76036 76038 76040 76042 76044 76046 76048 76050 76052 76054 76056 76058 76060 76062 76064 76066 76068 76070 76072 76074 76076 76078 76080 76082 76084 76086 76088 76090 76092 76094 76096 76098 76100 76102 76104 76106 76108 76110 76112 76114 76116 76118 76120 76122 76124 76126 76128 76130 76132 76134 76136 76138 76140 76142 76144 76146 76148 76150 76152 76154 76156 76158 125184 27008 27010 27012 27014 27016 27018 27020 27022 27024 27026 27028 27030 27032 27034 27036 27038 27040 27042 27044 27046 27048 27050 27052 27054 27056 27058 27060 27062 27064 27066 27068 27070 27072 27074 27076 27078 27080 27082 27084 27086 27088 27090 27092 27094 27096 27098 27100 27102 27104 27106 27108 27110 27112 27114 27116 27118 27120 27122 27124 27126 27128 27130 27132 27134 76160 76162 76164 76166 76168 76170 76172 76174 76176 76178 76180 76182 76184 76186 76188 76190 76192 76194 76196 76198 76200 76202 76204 76206 76208 76210 76212 76214 76216 76218 76220 76222 76224 76226 76228 76230 76232 76234 76236 76238 76240 76242 76244 76246 76248 76250 76252 76254 76256 76258 76260 76262 76264 76266 76268 76270 76272 76274 76276 76278 76280 76282 76284 76286 125312 27136 27138 27140 27142 27144 27146 27148 27150 27152 27154 27156 27158 27160 27162 27164 27166 27168 27170 27172 27174 27176 27178 27180 27182 27184 27186 27188 27190 27192 27194 27196 27198 27200 27202 27204 27206 27208 27210 27212 27214 27216 27218 27220 27222 27224 27226 27228 27230 27232 27234 27236 27238 27240 27242 27244 27246 27248 27250 27252 27254 27256 27258 27260 27262 76288 76290 76292 76294 76296 76298 76300 76302 76304 76306 76308 76310 76312 76314 76316 76318 76320 76322 76324 76326 76328 76330 76332 76334 76336 76338 76340 76342 76344 76346 76348 76350 76352 76354 76356 76358 76360 76362 76364 76366 76368 76370 76372 76374 76376 76378 76380 76382 76384 76386 76388 76390 76392 76394 76396 76398 76400 76402 76404 76406 76408 76410 76412 76414 125440 27264 27266 27268 27270 27272 27274 27276 27278 27280 27282 27284 27286 27288 27290 27292 27294 27296 27298 27300 27302 27304 27306 27308 27310 27312 27314 27316 27318 27320 27322 27324 27326 27328 27330 27332 27334 27336 27338 27340 27342 27344 27346 27348 27350 27352 27354 27356 27358 27360 27362 27364 27366 27368 27370 27372 27374 27376 27378 27380 27382 27384 27386 27388 27390 76416 76418 76420 76422 76424 76426 76428 76430 76432 76434 76436 76438 76440 76442 76444 76446 76448 76450 76452 76454 76456 76458 76460 76462 76464 76466 76468 76470 76472 76474 76476 76478 76480 76482 76484 76486 76488 76490 76492 76494 76496 76498 76500 76502 76504 76506 76508 76510 76512 76514 76516 76518 76520 76522 76524 76526 76528 76530 76532 76534 76536 76538 76540 76542 125568 27392 27394 27396 27398 27400 27402 27404 27406 27408 27410 27412 27414 27416 27418 27420 27422 27424 27426 27428 27430 27432 27434 27436 27438 27440 27442 27444 27446 27448 27450 27452 27454 27456 27458 27460 27462 27464 27466 27468 27470 27472 27474 27476 27478 27480 27482 27484 27486 27488 27490 27492 27494 27496 27498 27500 27502 27504 27506 27508 27510 27512 27514 27516 27518 76544 76546 76548 76550 76552 76554 76556 76558 76560 76562 76564 76566 76568 76570 76572 76574 76576 76578 76580 76582 76584 76586 76588 76590 76592 76594 76596 76598 76600 76602 76604 76606 76608 76610 76612 76614 76616 76618 76620 76622 76624 76626 76628 76630 76632 76634 76636 76638 76640 76642 76644 76646 76648 76650 76652 76654 76656 76658 76660 76662 76664 76666 76668 76670 125696 27520 27522 27524 27526 27528 27530 27532 27534 27536 27538 27540 27542 27544 27546 27548 27550 27552 27554 27556 27558 27560 27562 27564 27566 27568 27570 27572 27574 27576 27578 27580 27582 27584 27586 27588 27590 27592 27594 27596 27598 27600 27602 27604 27606 27608 27610 27612 27614 27616 27618 27620 27622 27624 27626 27628 27630 27632 27634 27636 27638 27640 27642 27644 27646 76672 76674 76676 76678 76680 76682 76684 76686 76688 76690 76692 76694 76696 76698 76700 76702 76704 76706 76708 76710 76712 76714 76716 76718 76720 76722 76724 76726 76728 76730 76732 76734 76736 76738 76740 76742 76744 76746 76748 76750 76752 76754 76756 76758 76760 76762 76764 76766 76768 76770 76772 76774 76776 76778 76780 76782 76784 76786 76788 76790 76792 76794 76796 76798 125824 27648 27650 27652 27654 27656 27658 27660 27662 27664 27666 27668 27670 27672 27674 27676 27678 27680 27682 27684 27686 27688 27690 27692 27694 27696 27698 27700 27702 27704 27706 27708 27710 27712 27714 27716 27718 27720 27722 27724 27726 27728 27730 27732 27734 27736 27738 27740 27742 27744 27746 27748 27750 27752 27754 27756 27758 27760 27762 27764 27766 27768 27770 27772 27774 76800 76802 76804 76806 76808 76810 76812 76814 76816 76818 76820 76822 76824 76826 76828 76830 76832 76834 76836 76838 76840 76842 76844 76846 76848 76850 76852 76854 76856 76858 76860 76862 76864 76866 76868 76870 76872 76874 76876 76878 76880 76882 76884 76886 76888 76890 76892 76894 76896 76898 76900 76902 76904 76906 76908 76910 76912 76914 76916 76918 76920 76922 76924 76926 125952 27776 27778 27780 27782 27784 27786 27788 27790 27792 27794 27796 27798 27800 27802 27804 27806 27808 27810 27812 27814 27816 27818 27820 27822 27824 27826 27828 27830 27832 27834 27836 27838 27840 27842 27844 27846 27848 27850 27852 27854 27856 27858 27860 27862 27864 27866 27868 27870 27872 27874 27876 27878 27880 27882 27884 27886 27888 27890 27892 27894 27896 27898 27900 27902 76928 76930 76932 76934 76936 76938 76940 76942 76944 76946 76948 76950 76952 76954 76956 76958 76960 76962 76964 76966 76968 76970 76972 76974 76976 76978 76980 76982 76984 76986 76988 76990 76992 76994 76996 76998 77000 77002 77004 77006 77008 77010 77012 77014 77016 77018 77020 77022 77024 77026 77028 77030 77032 77034 77036 77038 77040 77042 77044 77046 77048 77050 77052 77054 126080 27904 27906 27908 27910 27912 27914 27916 27918 27920 27922 27924 27926 27928 27930 27932 27934 27936 27938 27940 27942 27944 27946 27948 27950 27952 27954 27956 27958 27960 27962 27964 27966 27968 27970 27972 27974 27976 27978 27980 27982 27984 27986 27988 27990 27992 27994 27996 27998 28000 28002 28004 28006 28008 28010 28012 28014 28016 28018 28020 28022 28024 28026 28028 28030 77056 77058 77060 77062 77064 77066 77068 77070 77072 77074 77076 77078 77080 77082 77084 77086 77088 77090 77092 77094 77096 77098 77100 77102 77104 77106 77108 77110 77112 77114 77116 77118 77120 77122 77124 77126 77128 77130 77132 77134 77136 77138 77140 77142 77144 77146 77148 77150 77152 77154 77156 77158 77160 77162 77164 77166 77168 77170 77172 77174 77176 77178 77180 77182 126208 28032 28034 28036 28038 28040 28042 28044 28046 28048 28050 28052 28054 28056 28058 28060 28062 28064 28066 28068 28070 28072 28074 28076 28078 28080 28082 28084 28086 28088 28090 28092 28094 28096 28098 28100 28102 28104 28106 28108 28110 28112 28114 28116 28118 28120 28122 28124 28126 28128 28130 28132 28134 28136 28138 28140 28142 28144 28146 28148 28150 28152 28154 28156 28158 77184 77186 77188 77190 77192 77194 77196 77198 77200 77202 77204 77206 77208 77210 77212 77214 77216 77218 77220 77222 77224 77226 77228 77230 77232 77234 77236 77238 77240 77242 77244 77246 77248 77250 77252 77254 77256 77258 77260 77262 77264 77266 77268 77270 77272 77274 77276 77278 77280 77282 77284 77286 77288 77290 77292 77294 77296 77298 77300 77302 77304 77306 77308 77310 126336 28160 28162 28164 28166 28168 28170 28172 28174 28176 28178 28180 28182 28184 28186 28188 28190 28192 28194 28196 28198 28200 28202 28204 28206 28208 28210 28212 28214 28216 28218 28220 28222 28224 28226 28228 28230 28232 28234 28236 28238 28240 28242 28244 28246 28248 28250 28252 28254 28256 28258 28260 28262 28264 28266 28268 28270 28272 28274 28276 28278 28280 28282 28284 28286 77312 77314 77316 77318 77320 77322 77324 77326 77328 77330 77332 77334 77336 77338 77340 77342 77344 77346 77348 77350 77352 77354 77356 77358 77360 77362 77364 77366 77368 77370 77372 77374 77376 77378 77380 77382 77384 77386 77388 77390 77392 77394 77396 77398 77400 77402 77404 77406 77408 77410 77412 77414 77416 77418 77420 77422 77424 77426 77428 77430 77432 77434 77436 77438 126464 28288 28290 28292 28294 28296 28298 28300 28302 28304 28306 28308 28310 28312 28314 28316 28318 28320 28322 28324 28326 28328 28330 28332 28334 28336 28338 28340 28342 28344 28346 28348 28350 28352 28354 28356 28358 28360 28362 28364 28366 28368 28370 28372 28374 28376 28378 28380 28382 28384 28386 28388 28390 28392 28394 28396 28398 28400 28402 28404 28406 28408 28410 28412 28414 77440 77442 77444 77446 77448 77450 77452 77454 77456 77458 77460 77462 77464 77466 77468 77470 77472 77474 77476 77478 77480 77482 77484 77486 77488 77490 77492 77494 77496 77498 77500 77502 77504 77506 77508 77510 77512 77514 77516 77518 77520 77522 77524 77526 77528 77530 77532 77534 77536 77538 77540 77542 77544 77546 77548 77550 77552 77554 77556 77558 77560 77562 77564 77566 126592 28416 28418 28420 28422 28424 28426 28428 28430 28432 28434 28436 28438 28440 28442 28444 28446 28448 28450 28452 28454 28456 28458 28460 28462 28464 28466 28468 28470 28472 28474 28476 28478 28480 28482 28484 28486 28488 28490 28492 28494 28496 28498 28500 28502 28504 28506 28508 28510 28512 28514 28516 28518 28520 28522 28524 28526 28528 28530 28532 28534 28536 28538 28540 28542 77568 77570 77572 77574 77576 77578 77580 77582 77584 77586 77588 77590 77592 77594 77596 77598 77600 77602 77604 77606 77608 77610 77612 77614 77616 77618 77620 77622 77624 77626 77628 77630 77632 77634 77636 77638 77640 77642 77644 77646 77648 77650 77652 77654 77656 77658 77660 77662 77664 77666 77668 77670 77672 77674 77676 77678 77680 77682 77684 77686 77688 77690 77692 77694 126720 28544 28546 28548 28550 28552 28554 28556 28558 28560 28562 28564 28566 28568 28570 28572 28574 28576 28578 28580 28582 28584 28586 28588 28590 28592 28594 28596 28598 28600 28602 28604 28606 28608 28610 28612 28614 28616 28618 28620 28622 28624 28626 28628 28630 28632 28634 28636 28638 28640 28642 28644 28646 28648 28650 28652 28654 28656 28658 28660 28662 28664 28666 28668 28670 77696 77698 77700 77702 77704 77706 77708 77710 77712 77714 77716 77718 77720 77722 77724 77726 77728 77730 77732 77734 77736 77738 77740 77742 77744 77746 77748 77750 77752 77754 77756 77758 77760 77762 77764 77766 77768 77770 77772 77774 77776 77778 77780 77782 77784 77786 77788 77790 77792 77794 77796 77798 77800 77802 77804 77806 77808 77810 77812 77814 77816 77818 77820 77822 126848 28672 28674 28676 28678 28680 28682 28684 28686 28688 28690 28692 28694 28696 28698 28700 28702 28704 28706 28708 28710 28712 28714 28716 28718 28720 28722 28724 28726 28728 28730 28732 28734 28736 28738 28740 28742 28744 28746 28748 28750 28752 28754 28756 28758 28760 28762 28764 28766 28768 28770 28772 28774 28776 28778 28780 28782 28784 28786 28788 28790 28792 28794 28796 28798 77824 77826 77828 77830 77832 77834 77836 77838 77840 77842 77844 77846 77848 77850 77852 77854 77856 77858 77860 77862 77864 77866 77868 77870 77872 77874 77876 77878 77880 77882 77884 77886 77888 77890 77892 77894 77896 77898 77900 77902 77904 77906 77908 77910 77912 77914 77916 77918 77920 77922 77924 77926 77928 77930 77932 77934 77936 77938 77940 77942 77944 77946 77948 77950 126976 32768 32770 32772 32774 32776 32778 32780 32782 32784 32786 32788 32790 32792 32794 32796 32798 32800 32802 32804 32806 32808 32810 32812 32814 32816 32818 32820 32822 32824 32826 32828 32830 32832 32834 32836 32838 32840 32842 32844 32846 32848 32850 32852 32854 32856 32858 32860 32862 32864 32866 32868 32870 32872 32874 32876 32878 32880 32882 32884 32886 32888 32890 32892 32894 81920 81922 81924 81926 81928 81930 81932 81934 81936 81938 81940 81942 81944 81946 81948 81950 81952 81954 81956 81958 81960 81962 81964 81966 81968 81970 81972 81974 81976 81978 81980 81982 81984 81986 81988 81990 81992 81994 81996 81998 82000 82002 82004 82006 82008 82010 82012 82014 82016 82018 82020 82022 82024 82026 82028 82030 82032 82034 82036 82038 82040 82042 82044 82046 131072 32896 32898 32900 32902 32904 32906 32908 32910 32912 32914 32916 32918 32920 32922 32924 32926 32928 32930 32932 32934 32936 32938 32940 32942 32944 32946 32948 32950 32952 32954 32956 32958 32960 32962 32964 32966 32968 32970 32972 32974 32976 32978 32980 32982 32984 32986 32988 32990 32992 32994 32996 32998 33000 33002 33004 33006 33008 33010 33012 33014 33016 33018 33020 33022 82048 82050 82052 82054 82056 82058 82060 82062 82064 82066 82068 82070 82072 82074 82076 82078 82080 82082 82084 82086 82088 82090 82092 82094 82096 82098 82100 82102 82104 82106 82108 82110 82112 82114 82116 82118 82120 82122 82124 82126 82128 82130 82132 82134 82136 82138 82140 82142 82144 82146 82148 82150 82152 82154 82156 82158 82160 82162 82164 82166 82168 82170 82172 82174 131200 33024 33026 33028 33030 33032 33034 33036 33038 33040 33042 33044 33046 33048 33050 33052 33054 33056 33058 33060 33062 33064 33066 33068 33070 33072 33074 33076 33078 33080 33082 33084 33086 33088 33090 33092 33094 33096 33098 33100 33102 33104 33106 33108 33110 33112 33114 33116 33118 33120 33122 33124 33126 33128 33130 33132 33134 33136 33138 33140 33142 33144 33146 33148 33150 82176 82178 82180 82182 82184 82186 82188 82190 82192 82194 82196 82198 82200 82202 82204 82206 82208 82210 82212 82214 82216 82218 82220 82222 82224 82226 82228 82230 82232 82234 82236 82238 82240 82242 82244 82246 82248 82250 82252 82254 82256 82258 82260 82262 82264 82266 82268 82270 82272 82274 82276 82278 82280 82282 82284 82286 82288 82290 82292 82294 82296 82298 82300 82302 131328 33152 33154 33156 33158 33160 33162 33164 33166 33168 33170 33172 33174 33176 33178 33180 33182 33184 33186 33188 33190 33192 33194 33196 33198 33200 33202 33204 33206 33208 33210 33212 33214 33216 33218 33220 33222 33224 33226 33228 33230 33232 33234 33236 33238 33240 33242 33244 33246 33248 33250 33252 33254 33256 33258 33260 33262 33264 33266 33268 33270 33272 33274 33276 33278 82304 82306 82308 82310 82312 82314 82316 82318 82320 82322 82324 82326 82328 82330 82332 82334 82336 82338 82340 82342 82344 82346 82348 82350 82352 82354 82356 82358 82360 82362 82364 82366 82368 82370 82372 82374 82376 82378 82380 82382 82384 82386 82388 82390 82392 82394 82396 82398 82400 82402 82404 82406 82408 82410 82412 82414 82416 82418 82420 82422 82424 82426 82428 82430 131456 33280 33282 33284 33286 33288 33290 33292 33294 33296 33298 33300 33302 33304 33306 33308 33310 33312 33314 33316 33318 33320 33322 33324 33326 33328 33330 33332 33334 33336 33338 33340 33342 33344 33346 33348 33350 33352 33354 33356 33358 33360 33362 33364 33366 33368 33370 33372 33374 33376 33378 33380 33382 33384 33386 33388 33390 33392 33394 33396 33398 33400 33402 33404 33406 82432 82434 82436 82438 82440 82442 82444 82446 82448 82450 82452 82454 82456 82458 82460 82462 82464 82466 82468 82470 82472 82474 82476 82478 82480 82482 82484 82486 82488 82490 82492 82494 82496 82498 82500 82502 82504 82506 82508 82510 82512 82514 82516 82518 82520 82522 82524 82526 82528 82530 82532 82534 82536 82538 82540 82542 82544 82546 82548 82550 82552 82554 82556 82558 131584 33408 33410 33412 33414 33416 33418 33420 33422 33424 33426 33428 33430 33432 33434 33436 33438 33440 33442 33444 33446 33448 33450 33452 33454 33456 33458 33460 33462 33464 33466 33468 33470 33472 33474 33476 33478 33480 33482 33484 33486 33488 33490 33492 33494 33496 33498 33500 33502 33504 33506 33508 33510 33512 33514 33516 33518 33520 33522 33524 33526 33528 33530 33532 33534 82560 82562 82564 82566 82568 82570 82572 82574 82576 82578 82580 82582 82584 82586 82588 82590 82592 82594 82596 82598 82600 82602 82604 82606 82608 82610 82612 82614 82616 82618 82620 82622 82624 82626 82628 82630 82632 82634 82636 82638 82640 82642 82644 82646 82648 82650 82652 82654 82656 82658 82660 82662 82664 82666 82668 82670 82672 82674 82676 82678 82680 82682 82684 82686 131712 33536 33538 33540 33542 33544 33546 33548 33550 33552 33554 33556 33558 33560 33562 33564 33566 33568 33570 33572 33574 33576 33578 33580 33582 33584 33586 33588 33590 33592 33594 33596 33598 33600 33602 33604 33606 33608 33610 33612 33614 33616 33618 33620 33622 33624 33626 33628 33630 33632 33634 33636 33638 33640 33642 33644 33646 33648 33650 33652 33654 33656 33658 33660 33662 82688 82690 82692 82694 82696 82698 82700 82702 82704 82706 82708 82710 82712 82714 82716 82718 82720 82722 82724 82726 82728 82730 82732 82734 82736 82738 82740 82742 82744 82746 82748 82750 82752 82754 82756 82758 82760 82762 82764 82766 82768 82770 82772 82774 82776 82778 82780 82782 82784 82786 82788 82790 82792 82794 82796 82798 82800 82802 82804 82806 82808 82810 82812 82814 131840 33664 33666 33668 33670 33672 33674 33676 33678 33680 33682 33684 33686 33688 33690 33692 33694 33696 33698 33700 33702 33704 33706 33708 33710 33712 33714 33716 33718 33720 33722 33724 33726 33728 33730 33732 33734 33736 33738 33740 33742 33744 33746 33748 33750 33752 33754 33756 33758 33760 33762 33764 33766 33768 33770 33772 33774 33776 33778 33780 33782 33784 33786 33788 33790 82816 82818 82820 82822 82824 82826 82828 82830 82832 82834 82836 82838 82840 82842 82844 82846 82848 82850 82852 82854 82856 82858 82860 82862 82864 82866 82868 82870 82872 82874 82876 82878 82880 82882 82884 82886 82888 82890 82892 82894 82896 82898 82900 82902 82904 82906 82908 82910 82912 82914 82916 82918 82920 82922 82924 82926 82928 82930 82932 82934 82936 82938 82940 82942 131968 33792 33794 33796 33798 33800 33802 33804 33806 33808 33810 33812 33814 33816 33818 33820 33822 33824 33826 33828 33830 33832 33834 33836 33838 33840 33842 33844 33846 33848 33850 33852 33854 33856 33858 33860 33862 33864 33866 33868 33870 33872 33874 33876 33878 33880 33882 33884 33886 33888 33890 33892 33894 33896 33898 33900 33902 33904 33906 33908 33910 33912 33914 33916 33918 82944 82946 82948 82950 82952 82954 82956 82958 82960 82962 82964 82966 82968 82970 82972 82974 82976 82978 82980 82982 82984 82986 82988 82990 82992 82994 82996 82998 83000 83002 83004 83006 83008 83010 83012 83014 83016 83018 83020 83022 83024 83026 83028 83030 83032 83034 83036 83038 83040 83042 83044 83046 83048 83050 83052 83054 83056 83058 83060 83062 83064 83066 83068 83070 132096 33920 33922 33924 33926 33928 33930 33932 33934 33936 33938 33940 33942 33944 33946 33948 33950 33952 33954 33956 33958 33960 33962 33964 33966 33968 33970 33972 33974 33976 33978 33980 33982 33984 33986 33988 33990 33992 33994 33996 33998 34000 34002 34004 34006 34008 34010 34012 34014 34016 34018 34020 34022 34024 34026 34028 34030 34032 34034 34036 34038 34040 34042 34044 34046 83072 83074 83076 83078 83080 83082 83084 83086 83088 83090 83092 83094 83096 83098 83100 83102 83104 83106 83108 83110 83112 83114 83116 83118 83120 83122 83124 83126 83128 83130 83132 83134 83136 83138 83140 83142 83144 83146 83148 83150 83152 83154 83156 83158 83160 83162 83164 83166 83168 83170 83172 83174 83176 83178 83180 83182 83184 83186 83188 83190 83192 83194 83196 83198 132224 34048 34050 34052 34054 34056 34058 34060 34062 34064 34066 34068 34070 34072 34074 34076 34078 34080 34082 34084 34086 34088 34090 34092 34094 34096 34098 34100 34102 34104 34106 34108 34110 34112 34114 34116 34118 34120 34122 34124 34126 34128 34130 34132 34134 34136 34138 34140 34142 34144 34146 34148 34150 34152 34154 34156 34158 34160 34162 34164 34166 34168 34170 34172 34174 83200 83202 83204 83206 83208 83210 83212 83214 83216 83218 83220 83222 83224 83226 83228 83230 83232 83234 83236 83238 83240 83242 83244 83246 83248 83250 83252 83254 83256 83258 83260 83262 83264 83266 83268 83270 83272 83274 83276 83278 83280 83282 83284 83286 83288 83290 83292 83294 83296 83298 83300 83302 83304 83306 83308 83310 83312 83314 83316 83318 83320 83322 83324 83326 132352 34176 34178 34180 34182 34184 34186 34188 34190 34192 34194 34196 34198 34200 34202 34204 34206 34208 34210 34212 34214 34216 34218 34220 34222 34224 34226 34228 34230 34232 34234 34236 34238 34240 34242 34244 34246 34248 34250 34252 34254 34256 34258 34260 34262 34264 34266 34268 34270 34272 34274 34276 34278 34280 34282 34284 34286 34288 34290 34292 34294 34296 34298 34300 34302 83328 83330 83332 83334 83336 83338 83340 83342 83344 83346 83348 83350 83352 83354 83356 83358 83360 83362 83364 83366 83368 83370 83372 83374 83376 83378 83380 83382 83384 83386 83388 83390 83392 83394 83396 83398 83400 83402 83404 83406 83408 83410 83412 83414 83416 83418 83420 83422 83424 83426 83428 83430 83432 83434 83436 83438 83440 83442 83444 83446 83448 83450 83452 83454 132480 34304 34306 34308 34310 34312 34314 34316 34318 34320 34322 34324 34326 34328 34330 34332 34334 34336 34338 34340 34342 34344 34346 34348 34350 34352 34354 34356 34358 34360 34362 34364 34366 34368 34370 34372 34374 34376 34378 34380 34382 34384 34386 34388 34390 34392 34394 34396 34398 34400 34402 34404 34406 34408 34410 34412 34414 34416 34418 34420 34422 34424 34426 34428 34430 83456 83458 83460 83462 83464 83466 83468 83470 83472 83474 83476 83478 83480 83482 83484 83486 83488 83490 83492 83494 83496 83498 83500 83502 83504 83506 83508 83510 83512 83514 83516 83518 83520 83522 83524 83526 83528 83530 83532 83534 83536 83538 83540 83542 83544 83546 83548 83550 83552 83554 83556 83558 83560 83562 83564 83566 83568 83570 83572 83574 83576 83578 83580 83582 132608 34432 34434 34436 34438 34440 34442 34444 34446 34448 34450 34452 34454 34456 34458 34460 34462 34464 34466 34468 34470 34472 34474 34476 34478 34480 34482 34484 34486 34488 34490 34492 34494 34496 34498 34500 34502 34504 34506 34508 34510 34512 34514 34516 34518 34520 34522 34524 34526 34528 34530 34532 34534 34536 34538 34540 34542 34544 34546 34548 34550 34552 34554 34556 34558 83584 83586 83588 83590 83592 83594 83596 83598 83600 83602 83604 83606 83608 83610 83612 83614 83616 83618 83620 83622 83624 83626 83628 83630 83632 83634 83636 83638 83640 83642 83644 83646 83648 83650 83652 83654 83656 83658 83660 83662 83664 83666 83668 83670 83672 83674 83676 83678 83680 83682 83684 83686 83688 83690 83692 83694 83696 83698 83700 83702 83704 83706 83708 83710 132736 34560 34562 34564 34566 34568 34570 34572 34574 34576 34578 34580 34582 34584 34586 34588 34590 34592 34594 34596 34598 34600 34602 34604 34606 34608 34610 34612 34614 34616 34618 34620 34622 34624 34626 34628 34630 34632 34634 34636 34638 34640 34642 34644 34646 34648 34650 34652 34654 34656 34658 34660 34662 34664 34666 34668 34670 34672 34674 34676 34678 34680 34682 34684 34686 83712 83714 83716 83718 83720 83722 83724 83726 83728 83730 83732 83734 83736 83738 83740 83742 83744 83746 83748 83750 83752 83754 83756 83758 83760 83762 83764 83766 83768 83770 83772 83774 83776 83778 83780 83782 83784 83786 83788 83790 83792 83794 83796 83798 83800 83802 83804 83806 83808 83810 83812 83814 83816 83818 83820 83822 83824 83826 83828 83830 83832 83834 83836 83838 132864 34688 34690 34692 34694 34696 34698 34700 34702 34704 34706 34708 34710 34712 34714 34716 34718 34720 34722 34724 34726 34728 34730 34732 34734 34736 34738 34740 34742 34744 34746 34748 34750 34752 34754 34756 34758 34760 34762 34764 34766 34768 34770 34772 34774 34776 34778 34780 34782 34784 34786 34788 34790 34792 34794 34796 34798 34800 34802 34804 34806 34808 34810 34812 34814 83840 83842 83844 83846 83848 83850 83852 83854 83856 83858 83860 83862 83864 83866 83868 83870 83872 83874 83876 83878 83880 83882 83884 83886 83888 83890 83892 83894 83896 83898 83900 83902 83904 83906 83908 83910 83912 83914 83916 83918 83920 83922 83924 83926 83928 83930 83932 83934 83936 83938 83940 83942 83944 83946 83948 83950 83952 83954 83956 83958 83960 83962 83964 83966 132992 34816 34818 34820 34822 34824 34826 34828 34830 34832 34834 34836 34838 34840 34842 34844 34846 34848 34850 34852 34854 34856 34858 34860 34862 34864 34866 34868 34870 34872 34874 34876 34878 34880 34882 34884 34886 34888 34890 34892 34894 34896 34898 34900 34902 34904 34906 34908 34910 34912 34914 34916 34918 34920 34922 34924 34926 34928 34930 34932 34934 34936 34938 34940 34942 83968 83970 83972 83974 83976 83978 83980 83982 83984 83986 83988 83990 83992 83994 83996 83998 84000 84002 84004 84006 84008 84010 84012 84014 84016 84018 84020 84022 84024 84026 84028 84030 84032 84034 84036 84038 84040 84042 84044 84046 84048 84050 84052 84054 84056 84058 84060 84062 84064 84066 84068 84070 84072 84074 84076 84078 84080 84082 84084 84086 84088 84090 84092 84094 133120 34944 34946 34948 34950 34952 34954 34956 34958 34960 34962 34964 34966 34968 34970 34972 34974 34976 34978 34980 34982 34984 34986 34988 34990 34992 34994 34996 34998 35000 35002 35004 35006 35008 35010 35012 35014 35016 35018 35020 35022 35024 35026 35028 35030 35032 35034 35036 35038 35040 35042 35044 35046 35048 35050 35052 35054 35056 35058 35060 35062 35064 35066 35068 35070 84096 84098 84100 84102 84104 84106 84108 84110 84112 84114 84116 84118 84120 84122 84124 84126 84128 84130 84132 84134 84136 84138 84140 84142 84144 84146 84148 84150 84152 84154 84156 84158 84160 84162 84164 84166 84168 84170 84172 84174 84176 84178 84180 84182 84184 84186 84188 84190 84192 84194 84196 84198 84200 84202 84204 84206 84208 84210 84212 84214 84216 84218 84220 84222 133248 35072 35074 35076 35078 35080 35082 35084 35086 35088 35090 35092 35094 35096 35098 35100 35102 35104 35106 35108 35110 35112 35114 35116 35118 35120 35122 35124 35126 35128 35130 35132 35134 35136 35138 35140 35142 35144 35146 35148 35150 35152 35154 35156 35158 35160 35162 35164 35166 35168 35170 35172 35174 35176 35178 35180 35182 35184 35186 35188 35190 35192 35194 35196 35198 84224 84226 84228 84230 84232 84234 84236 84238 84240 84242 84244 84246 84248 84250 84252 84254 84256 84258 84260 84262 84264 84266 84268 84270 84272 84274 84276 84278 84280 84282 84284 84286 84288 84290 84292 84294 84296 84298 84300 84302 84304 84306 84308 84310 84312 84314 84316 84318 84320 84322 84324 84326 84328 84330 84332 84334 84336 84338 84340 84342 84344 84346 84348 84350 133376 35200 35202 35204 35206 35208 35210 35212 35214 35216 35218 35220 35222 35224 35226 35228 35230 35232 35234 35236 35238 35240 35242 35244 35246 35248 35250 35252 35254 35256 35258 35260 35262 35264 35266 35268 35270 35272 35274 35276 35278 35280 35282 35284 35286 35288 35290 35292 35294 35296 35298 35300 35302 35304 35306 35308 35310 35312 35314 35316 35318 35320 35322 35324 35326 84352 84354 84356 84358 84360 84362 84364 84366 84368 84370 84372 84374 84376 84378 84380 84382 84384 84386 84388 84390 84392 84394 84396 84398 84400 84402 84404 84406 84408 84410 84412 84414 84416 84418 84420 84422 84424 84426 84428 84430 84432 84434 84436 84438 84440 84442 84444 84446 84448 84450 84452 84454 84456 84458 84460 84462 84464 84466 84468 84470 84472 84474 84476 84478 133504 35328 35330 35332 35334 35336 35338 35340 35342 35344 35346 35348 35350 35352 35354 35356 35358 35360 35362 35364 35366 35368 35370 35372 35374 35376 35378 35380 35382 35384 35386 35388 35390 35392 35394 35396 35398 35400 35402 35404 35406 35408 35410 35412 35414 35416 35418 35420 35422 35424 35426 35428 35430 35432 35434 35436 35438 35440 35442 35444 35446 35448 35450 35452 35454 84480 84482 84484 84486 84488 84490 84492 84494 84496 84498 84500 84502 84504 84506 84508 84510 84512 84514 84516 84518 84520 84522 84524 84526 84528 84530 84532 84534 84536 84538 84540 84542 84544 84546 84548 84550 84552 84554 84556 84558 84560 84562 84564 84566 84568 84570 84572 84574 84576 84578 84580 84582 84584 84586 84588 84590 84592 84594 84596 84598 84600 84602 84604 84606 133632 35456 35458 35460 35462 35464 35466 35468 35470 35472 35474 35476 35478 35480 35482 35484 35486 35488 35490 35492 35494 35496 35498 35500 35502 35504 35506 35508 35510 35512 35514 35516 35518 35520 35522 35524 35526 35528 35530 35532 35534 35536 35538 35540 35542 35544 35546 35548 35550 35552 35554 35556 35558 35560 35562 35564 35566 35568 35570 35572 35574 35576 35578 35580 35582 84608 84610 84612 84614 84616 84618 84620 84622 84624 84626 84628 84630 84632 84634 84636 84638 84640 84642 84644 84646 84648 84650 84652 84654 84656 84658 84660 84662 84664 84666 84668 84670 84672 84674 84676 84678 84680 84682 84684 84686 84688 84690 84692 84694 84696 84698 84700 84702 84704 84706 84708 84710 84712 84714 84716 84718 84720 84722 84724 84726 84728 84730 84732 84734 133760 35584 35586 35588 35590 35592 35594 35596 35598 35600 35602 35604 35606 35608 35610 35612 35614 35616 35618 35620 35622 35624 35626 35628 35630 35632 35634 35636 35638 35640 35642 35644 35646 35648 35650 35652 35654 35656 35658 35660 35662 35664 35666 35668 35670 35672 35674 35676 35678 35680 35682 35684 35686 35688 35690 35692 35694 35696 35698 35700 35702 35704 35706 35708 35710 84736 84738 84740 84742 84744 84746 84748 84750 84752 84754 84756 84758 84760 84762 84764 84766 84768 84770 84772 84774 84776 84778 84780 84782 84784 84786 84788 84790 84792 84794 84796 84798 84800 84802 84804 84806 84808 84810 84812 84814 84816 84818 84820 84822 84824 84826 84828 84830 84832 84834 84836 84838 84840 84842 84844 84846 84848 84850 84852 84854 84856 84858 84860 84862 133888 35712 35714 35716 35718 35720 35722 35724 35726 35728 35730 35732 35734 35736 35738 35740 35742 35744 35746 35748 35750 35752 35754 35756 35758 35760 35762 35764 35766 35768 35770 35772 35774 35776 35778 35780 35782 35784 35786 35788 35790 35792 35794 35796 35798 35800 35802 35804 35806 35808 35810 35812 35814 35816 35818 35820 35822 35824 35826 35828 35830 35832 35834 35836 35838 84864 84866 84868 84870 84872 84874 84876 84878 84880 84882 84884 84886 84888 84890 84892 84894 84896 84898 84900 84902 84904 84906 84908 84910 84912 84914 84916 84918 84920 84922 84924 84926 84928 84930 84932 84934 84936 84938 84940 84942 84944 84946 84948 84950 84952 84954 84956 84958 84960 84962 84964 84966 84968 84970 84972 84974 84976 84978 84980 84982 84984 84986 84988 84990 134016 35840 35842 35844 35846 35848 35850 35852 35854 35856 35858 35860 35862 35864 35866 35868 35870 35872 35874 35876 35878 35880 35882 35884 35886 35888 35890 35892 35894 35896 35898 35900 35902 35904 35906 35908 35910 35912 35914 35916 35918 35920 35922 35924 35926 35928 35930 35932 35934 35936 35938 35940 35942 35944 35946 35948 35950 35952 35954 35956 35958 35960 35962 35964 35966 84992 84994 84996 84998 85000 85002 85004 85006 85008 85010 85012 85014 85016 85018 85020 85022 85024 85026 85028 85030 85032 85034 85036 85038 85040 85042 85044 85046 85048 85050 85052 85054 85056 85058 85060 85062 85064 85066 85068 85070 85072 85074 85076 85078 85080 85082 85084 85086 85088 85090 85092 85094 85096 85098 85100 85102 85104 85106 85108 85110 85112 85114 85116 85118 134144 35968 35970 35972 35974 35976 35978 35980 35982 35984 35986 35988 35990 35992 35994 35996 35998 36000 36002 36004 36006 36008 36010 36012 36014 36016 36018 36020 36022 36024 36026 36028 36030 36032 36034 36036 36038 36040 36042 36044 36046 36048 36050 36052 36054 36056 36058 36060 36062 36064 36066 36068 36070 36072 36074 36076 36078 36080 36082 36084 36086 36088 36090 36092 36094 85120 85122 85124 85126 85128 85130 85132 85134 85136 85138 85140 85142 85144 85146 85148 85150 85152 85154 85156 85158 85160 85162 85164 85166 85168 85170 85172 85174 85176 85178 85180 85182 85184 85186 85188 85190 85192 85194 85196 85198 85200 85202 85204 85206 85208 85210 85212 85214 85216 85218 85220 85222 85224 85226 85228 85230 85232 85234 85236 85238 85240 85242 85244 85246 134272 36096 36098 36100 36102 36104 36106 36108 36110 36112 36114 36116 36118 36120 36122 36124 36126 36128 36130 36132 36134 36136 36138 36140 36142 36144 36146 36148 36150 36152 36154 36156 36158 36160 36162 36164 36166 36168 36170 36172 36174 36176 36178 36180 36182 36184 36186 36188 36190 36192 36194 36196 36198 36200 36202 36204 36206 36208 36210 36212 36214 36216 36218 36220 36222 85248 85250 85252 85254 85256 85258 85260 85262 85264 85266 85268 85270 85272 85274 85276 85278 85280 85282 85284 85286 85288 85290 85292 85294 85296 85298 85300 85302 85304 85306 85308 85310 85312 85314 85316 85318 85320 85322 85324 85326 85328 85330 85332 85334 85336 85338 85340 85342 85344 85346 85348 85350 85352 85354 85356 85358 85360 85362 85364 85366 85368 85370 85372 85374 134400 36224 36226 36228 36230 36232 36234 36236 36238 36240 36242 36244 36246 36248 36250 36252 36254 36256 36258 36260 36262 36264 36266 36268 36270 36272 36274 36276 36278 36280 36282 36284 36286 36288 36290 36292 36294 36296 36298 36300 36302 36304 36306 36308 36310 36312 36314 36316 36318 36320 36322 36324 36326 36328 36330 36332 36334 36336 36338 36340 36342 36344 36346 36348 36350 85376 85378 85380 85382 85384 85386 85388 85390 85392 85394 85396 85398 85400 85402 85404 85406 85408 85410 85412 85414 85416 85418 85420 85422 85424 85426 85428 85430 85432 85434 85436 85438 85440 85442 85444 85446 85448 85450 85452 85454 85456 85458 85460 85462 85464 85466 85468 85470 85472 85474 85476 85478 85480 85482 85484 85486 85488 85490 85492 85494 85496 85498 85500 85502 134528 36352 36354 36356 36358 36360 36362 36364 36366 36368 36370 36372 36374 36376 36378 36380 36382 36384 36386 36388 36390 36392 36394 36396 36398 36400 36402 36404 36406 36408 36410 36412 36414 36416 36418 36420 36422 36424 36426 36428 36430 36432 36434 36436 36438 36440 36442 36444 36446 36448 36450 36452 36454 36456 36458 36460 36462 36464 36466 36468 36470 36472 36474 36476 36478 85504 85506 85508 85510 85512 85514 85516 85518 85520 85522 85524 85526 85528 85530 85532 85534 85536 85538 85540 85542 85544 85546 85548 85550 85552 85554 85556 85558 85560 85562 85564 85566 85568 85570 85572 85574 85576 85578 85580 85582 85584 85586 85588 85590 85592 85594 85596 85598 85600 85602 85604 85606 85608 85610 85612 85614 85616 85618 85620 85622 85624 85626 85628 85630 134656 36480 36482 36484 36486 36488 36490 36492 36494 36496 36498 36500 36502 36504 36506 36508 36510 36512 36514 36516 36518 36520 36522 36524 36526 36528 36530 36532 36534 36536 36538 36540 36542 36544 36546 36548 36550 36552 36554 36556 36558 36560 36562 36564 36566 36568 36570 36572 36574 36576 36578 36580 36582 36584 36586 36588 36590 36592 36594 36596 36598 36600 36602 36604 36606 85632 85634 85636 85638 85640 85642 85644 85646 85648 85650 85652 85654 85656 85658 85660 85662 85664 85666 85668 85670 85672 85674 85676 85678 85680 85682 85684 85686 85688 85690 85692 85694 85696 85698 85700 85702 85704 85706 85708 85710 85712 85714 85716 85718 85720 85722 85724 85726 85728 85730 85732 85734 85736 85738 85740 85742 85744 85746 85748 85750 85752 85754 85756 85758 134784 36608 36610 36612 36614 36616 36618 36620 36622 36624 36626 36628 36630 36632 36634 36636 36638 36640 36642 36644 36646 36648 36650 36652 36654 36656 36658 36660 36662 36664 36666 36668 36670 36672 36674 36676 36678 36680 36682 36684 36686 36688 36690 36692 36694 36696 36698 36700 36702 36704 36706 36708 36710 36712 36714 36716 36718 36720 36722 36724 36726 36728 36730 36732 36734 85760 85762 85764 85766 85768 85770 85772 85774 85776 85778 85780 85782 85784 85786 85788 85790 85792 85794 85796 85798 85800 85802 85804 85806 85808 85810 85812 85814 85816 85818 85820 85822 85824 85826 85828 85830 85832 85834 85836 85838 85840 85842 85844 85846 85848 85850 85852 85854 85856 85858 85860 85862 85864 85866 85868 85870 85872 85874 85876 85878 85880 85882 85884 85886 134912 36736 36738 36740 36742 36744 36746 36748 36750 36752 36754 36756 36758 36760 36762 36764 36766 36768 36770 36772 36774 36776 36778 36780 36782 36784 36786 36788 36790 36792 36794 36796 36798 36800 36802 36804 36806 36808 36810 36812 36814 36816 36818 36820 36822 36824 36826 36828 36830 36832 36834 36836 36838 36840 36842 36844 36846 36848 36850 36852 36854 36856 36858 36860 36862 85888 85890 85892 85894 85896 85898 85900 85902 85904 85906 85908 85910 85912 85914 85916 85918 85920 85922 85924 85926 85928 85930 85932 85934 85936 85938 85940 85942 85944 85946 85948 85950 85952 85954 85956 85958 85960 85962 85964 85966 85968 85970 85972 85974 85976 85978 85980 85982 85984 85986 85988 85990 85992 85994 85996 85998 86000 86002 86004 86006 86008 86010 86012 86014 135040 36864 36866 36868 36870 36872 36874 36876 36878 36880 36882 36884 36886 36888 36890 36892 36894 36896 36898 36900 36902 36904 36906 36908 36910 36912 36914 36916 36918 36920 36922 36924 36926 36928 36930 36932 36934 36936 36938 36940 36942 36944 36946 36948 36950 36952 36954 36956 36958 36960 36962 36964 36966 36968 36970 36972 36974 36976 36978 36980 36982 36984 36986 36988 36990 86016 86018 86020 86022 86024 86026 86028 86030 86032 86034 86036 86038 86040 86042 86044 86046 86048 86050 86052 86054 86056 86058 86060 86062 86064 86066 86068 86070 86072 86074 86076 86078 86080 86082 86084 86086 86088 86090 86092 86094 86096 86098 86100 86102 86104 86106 86108 86110 86112 86114 86116 86118 86120 86122 86124 86126 86128 86130 86132 86134 86136 86138 86140 86142 135168 40960 40962 40964 40966 40968 40970 40972 40974 40976 40978 40980 40982 40984 40986 40988 40990 40992 40994 40996 40998 41000 41002 41004 41006 41008 41010 41012 41014 41016 41018 41020 41022 41024 41026 41028 41030 41032 41034 41036 41038 41040 41042 41044 41046 41048 41050 41052 41054 41056 41058 41060 41062 41064 41066 41068 41070 41072 41074 41076 41078 41080 41082 41084 41086 90112 90114 90116 90118 90120 90122 90124 90126 90128 90130 90132 90134 90136 90138 90140 90142 90144 90146 90148 90150 90152 90154 90156 90158 90160 90162 90164 90166 90168 90170 90172 90174 90176 90178 90180 90182 90184 90186 90188 90190 90192 90194 90196 90198 90200 90202 90204 90206 90208 90210 90212 90214 90216 90218 90220 90222 90224 90226 90228 90230 90232 90234 90236 90238 139264 41088 41090 41092 41094 41096 41098 41100 41102 41104 41106 41108 41110 41112 41114 41116 41118 41120 41122 41124 41126 41128 41130 41132 41134 41136 41138 41140 41142 41144 41146 41148 41150 41152 41154 41156 41158 41160 41162 41164 41166 41168 41170 41172 41174 41176 41178 41180 41182 41184 41186 41188 41190 41192 41194 41196 41198 41200 41202 41204 41206 41208 41210 41212 41214 90240 90242 90244 90246 90248 90250 90252 90254 90256 90258 90260 90262 90264 90266 90268 90270 90272 90274 90276 90278 90280 90282 90284 90286 90288 90290 90292 90294 90296 90298 90300 90302 90304 90306 90308 90310 90312 90314 90316 90318 90320 90322 90324 90326 90328 90330 90332 90334 90336 90338 90340 90342 90344 90346 90348 90350 90352 90354 90356 90358 90360 90362 90364 90366 139392 41216 41218 41220 41222 41224 41226 41228 41230 41232 41234 41236 41238 41240 41242 41244 41246 41248 41250 41252 41254 41256 41258 41260 41262 41264 41266 41268 41270 41272 41274 41276 41278 41280 41282 41284 41286 41288 41290 41292 41294 41296 41298 41300 41302 41304 41306 41308 41310 41312 41314 41316 41318 41320 41322 41324 41326 41328 41330 41332 41334 41336 41338 41340 41342 90368 90370 90372 90374 90376 90378 90380 90382 90384 90386 90388 90390 90392 90394 90396 90398 90400 90402 90404 90406 90408 90410 90412 90414 90416 90418 90420 90422 90424 90426 90428 90430 90432 90434 90436 90438 90440 90442 90444 90446 90448 90450 90452 90454 90456 90458 90460 90462 90464 90466 90468 90470 90472 90474 90476 90478 90480 90482 90484 90486 90488 90490 90492 90494 139520 41344 41346 41348 41350 41352 41354 41356 41358 41360 41362 41364 41366 41368 41370 41372 41374 41376 41378 41380 41382 41384 41386 41388 41390 41392 41394 41396 41398 41400 41402 41404 41406 41408 41410 41412 41414 41416 41418 41420 41422 41424 41426 41428 41430 41432 41434 41436 41438 41440 41442 41444 41446 41448 41450 41452 41454 41456 41458 41460 41462 41464 41466 41468 41470 90496 90498 90500 90502 90504 90506 90508 90510 90512 90514 90516 90518 90520 90522 90524 90526 90528 90530 90532 90534 90536 90538 90540 90542 90544 90546 90548 90550 90552 90554 90556 90558 90560 90562 90564 90566 90568 90570 90572 90574 90576 90578 90580 90582 90584 90586 90588 90590 90592 90594 90596 90598 90600 90602 90604 90606 90608 90610 90612 90614 90616 90618 90620 90622 139648 41472 41474 41476 41478 41480 41482 41484 41486 41488 41490 41492 41494 41496 41498 41500 41502 41504 41506 41508 41510 41512 41514 41516 41518 41520 41522 41524 41526 41528 41530 41532 41534 41536 41538 41540 41542 41544 41546 41548 41550 41552 41554 41556 41558 41560 41562 41564 41566 41568 41570 41572 41574 41576 41578 41580 41582 41584 41586 41588 41590 41592 41594 41596 41598 90624 90626 90628 90630 90632 90634 90636 90638 90640 90642 90644 90646 90648 90650 90652 90654 90656 90658 90660 90662 90664 90666 90668 90670 90672 90674 90676 90678 90680 90682 90684 90686 90688 90690 90692 90694 90696 90698 90700 90702 90704 90706 90708 90710 90712 90714 90716 90718 90720 90722 90724 90726 90728 90730 90732 90734 90736 90738 90740 90742 90744 90746 90748 90750 139776 41600 41602 41604 41606 41608 41610 41612 41614 41616 41618 41620 41622 41624 41626 41628 41630 41632 41634 41636 41638 41640 41642 41644 41646 41648 41650 41652 41654 41656 41658 41660 41662 41664 41666 41668 41670 41672 41674 41676 41678 41680 41682 41684 41686 41688 41690 41692 41694 41696 41698 41700 41702 41704 41706 41708 41710 41712 41714 41716 41718 41720 41722 41724 41726 90752 90754 90756 90758 90760 90762 90764 90766 90768 90770 90772 90774 90776 90778 90780 90782 90784 90786 90788 90790 90792 90794 90796 90798 90800 90802 90804 90806 90808 90810 90812 90814 90816 90818 90820 90822 90824 90826 90828 90830 90832 90834 90836 90838 90840 90842 90844 90846 90848 90850 90852 90854 90856 90858 90860 90862 90864 90866 90868 90870 90872 90874 90876 90878 139904 41728 41730 41732 41734 41736 41738 41740 41742 41744 41746 41748 41750 41752 41754 41756 41758 41760 41762 41764 41766 41768 41770 41772 41774 41776 41778 41780 41782 41784 41786 41788 41790 41792 41794 41796 41798 41800 41802 41804 41806 41808 41810 41812 41814 41816 41818 41820 41822 41824 41826 41828 41830 41832 41834 41836 41838 41840 41842 41844 41846 41848 41850 41852 41854 90880 90882 90884 90886 90888 90890 90892 90894 90896 90898 90900 90902 90904 90906 90908 90910 90912 90914 90916 90918 90920 90922 90924 90926 90928 90930 90932 90934 90936 90938 90940 90942 90944 90946 90948 90950 90952 90954 90956 90958 90960 90962 90964 90966 90968 90970 90972 90974 90976 90978 90980 90982 90984 90986 90988 90990 90992 90994 90996 90998 91000 91002 91004 91006 140032 41856 41858 41860 41862 41864 41866 41868 41870 41872 41874 41876 41878 41880 41882 41884 41886 41888 41890 41892 41894 41896 41898 41900 41902 41904 41906 41908 41910 41912 41914 41916 41918 41920 41922 41924 41926 41928 41930 41932 41934 41936 41938 41940 41942 41944 41946 41948 41950 41952 41954 41956 41958 41960 41962 41964 41966 41968 41970 41972 41974 41976 41978 41980 41982 91008 91010 91012 91014 91016 91018 91020 91022 91024 91026 91028 91030 91032 91034 91036 91038 91040 91042 91044 91046 91048 91050 91052 91054 91056 91058 91060 91062 91064 91066 91068 91070 91072 91074 91076 91078 91080 91082 91084 91086 91088 91090 91092 91094 91096 91098 91100 91102 91104 91106 91108 91110 91112 91114 91116 91118 91120 91122 91124 91126 91128 91130 91132 91134 140160 41984 41986 41988 41990 41992 41994 41996 41998 42000 42002 42004 42006 42008 42010 42012 42014 42016 42018 42020 42022 42024 42026 42028 42030 42032 42034 42036 42038 42040 42042 42044 42046 42048 42050 42052 42054 42056 42058 42060 42062 42064 42066 42068 42070 42072 42074 42076 42078 42080 42082 42084 42086 42088 42090 42092 42094 42096 42098 42100 42102 42104 42106 42108 42110 91136 91138 91140 91142 91144 91146 91148 91150 91152 91154 91156 91158 91160 91162 91164 91166 91168 91170 91172 91174 91176 91178 91180 91182 91184 91186 91188 91190 91192 91194 91196 91198 91200 91202 91204 91206 91208 91210 91212 91214 91216 91218 91220 91222 91224 91226 91228 91230 91232 91234 91236 91238 91240 91242 91244 91246 91248 91250 91252 91254 91256 91258 91260 91262 140288 42112 42114 42116 42118 42120 42122 42124 42126 42128 42130 42132 42134 42136 42138 42140 42142 42144 42146 42148 42150 42152 42154 42156 42158 42160 42162 42164 42166 42168 42170 42172 42174 42176 42178 42180 42182 42184 42186 42188 42190 42192 42194 42196 42198 42200 42202 42204 42206 42208 42210 42212 42214 42216 42218 42220 42222 42224 42226 42228 42230 42232 42234 42236 42238 91264 91266 91268 91270 91272 91274 91276 91278 91280 91282 91284 91286 91288 91290 91292 91294 91296 91298 91300 91302 91304 91306 91308 91310 91312 91314 91316 91318 91320 91322 91324 91326 91328 91330 91332 91334 91336 91338 91340 91342 91344 91346 91348 91350 91352 91354 91356 91358 91360 91362 91364 91366 91368 91370 91372 91374 91376 91378 91380 91382 91384 91386 91388 91390 140416 42240 42242 42244 42246 42248 42250 42252 42254 42256 42258 42260 42262 42264 42266 42268 42270 42272 42274 42276 42278 42280 42282 42284 42286 42288 42290 42292 42294 42296 42298 42300 42302 42304 42306 42308 42310 42312 42314 42316 42318 42320 42322 42324 42326 42328 42330 42332 42334 42336 42338 42340 42342 42344 42346 42348 42350 42352 42354 42356 42358 42360 42362 42364 42366 91392 91394 91396 91398 91400 91402 91404 91406 91408 91410 91412 91414 91416 91418 91420 91422 91424 91426 91428 91430 91432 91434 91436 91438 91440 91442 91444 91446 91448 91450 91452 91454 91456 91458 91460 91462 91464 91466 91468 91470 91472 91474 91476 91478 91480 91482 91484 91486 91488 91490 91492 91494 91496 91498 91500 91502 91504 91506 91508 91510 91512 91514 91516 91518 140544 42368 42370 42372 42374 42376 42378 42380 42382 42384 42386 42388 42390 42392 42394 42396 42398 42400 42402 42404 42406 42408 42410 42412 42414 42416 42418 42420 42422 42424 42426 42428 42430 42432 42434 42436 42438 42440 42442 42444 42446 42448 42450 42452 42454 42456 42458 42460 42462 42464 42466 42468 42470 42472 42474 42476 42478 42480 42482 42484 42486 42488 42490 42492 42494 91520 91522 91524 91526 91528 91530 91532 91534 91536 91538 91540 91542 91544 91546 91548 91550 91552 91554 91556 91558 91560 91562 91564 91566 91568 91570 91572 91574 91576 91578 91580 91582 91584 91586 91588 91590 91592 91594 91596 91598 91600 91602 91604 91606 91608 91610 91612 91614 91616 91618 91620 91622 91624 91626 91628 91630 91632 91634 91636 91638 91640 91642 91644 91646 140672 42496 42498 42500 42502 42504 42506 42508 42510 42512 42514 42516 42518 42520 42522 42524 42526 42528 42530 42532 42534 42536 42538 42540 42542 42544 42546 42548 42550 42552 42554 42556 42558 42560 42562 42564 42566 42568 42570 42572 42574 42576 42578 42580 42582 42584 42586 42588 42590 42592 42594 42596 42598 42600 42602 42604 42606 42608 42610 42612 42614 42616 42618 42620 42622 91648 91650 91652 91654 91656 91658 91660 91662 91664 91666 91668 91670 91672 91674 91676 91678 91680 91682 91684 91686 91688 91690 91692 91694 91696 91698 91700 91702 91704 91706 91708 91710 91712 91714 91716 91718 91720 91722 91724 91726 91728 91730 91732 91734 91736 91738 91740 91742 91744 91746 91748 91750 91752 91754 91756 91758 91760 91762 91764 91766 91768 91770 91772 91774 140800 42624 42626 42628 42630 42632 42634 42636 42638 42640 42642 42644 42646 42648 42650 42652 42654 42656 42658 42660 42662 42664 42666 42668 42670 42672 42674 42676 42678 42680 42682 42684 42686 42688 42690 42692 42694 42696 42698 42700 42702 42704 42706 42708 42710 42712 42714 42716 42718 42720 42722 42724 42726 42728 42730 42732 42734 42736 42738 42740 42742 42744 42746 42748 42750 91776 91778 91780 91782 91784 91786 91788 91790 91792 91794 91796 91798 91800 91802 91804 91806 91808 91810 91812 91814 91816 91818 91820 91822 91824 91826 91828 91830 91832 91834 91836 91838 91840 91842 91844 91846 91848 91850 91852 91854 91856 91858 91860 91862 91864 91866 91868 91870 91872 91874 91876 91878 91880 91882 91884 91886 91888 91890 91892 91894 91896 91898 91900 91902 140928 42752 42754 42756 42758 42760 42762 42764 42766 42768 42770 42772 42774 42776 42778 42780 42782 42784 42786 42788 42790 42792 42794 42796 42798 42800 42802 42804 42806 42808 42810 42812 42814 42816 42818 42820 42822 42824 42826 42828 42830 42832 42834 42836 42838 42840 42842 42844 42846 42848 42850 42852 42854 42856 42858 42860 42862 42864 42866 42868 42870 42872 42874 42876 42878 91904 91906 91908 91910 91912 91914 91916 91918 91920 91922 91924 91926 91928 91930 91932 91934 91936 91938 91940 91942 91944 91946 91948 91950 91952 91954 91956 91958 91960 91962 91964 91966 91968 91970 91972 91974 91976 91978 91980 91982 91984 91986 91988 91990 91992 91994 91996 91998 92000 92002 92004 92006 92008 92010 92012 92014 92016 92018 92020 92022 92024 92026 92028 92030 141056 42880 42882 42884 42886 42888 42890 42892 42894 42896 42898 42900 42902 42904 42906 42908 42910 42912 42914 42916 42918 42920 42922 42924 42926 42928 42930 42932 42934 42936 42938 42940 42942 42944 42946 42948 42950 42952 42954 42956 42958 42960 42962 42964 42966 42968 42970 42972 42974 42976 42978 42980 42982 42984 42986 42988 42990 42992 42994 42996 42998 43000 43002 43004 43006 92032 92034 92036 92038 92040 92042 92044 92046 92048 92050 92052 92054 92056 92058 92060 92062 92064 92066 92068 92070 92072 92074 92076 92078 92080 92082 92084 92086 92088 92090 92092 92094 92096 92098 92100 92102 92104 92106 92108 92110 92112 92114 92116 92118 92120 92122 92124 92126 92128 92130 92132 92134 92136 92138 92140 92142 92144 92146 92148 92150 92152 92154 92156 92158 141184 43008 43010 43012 43014 43016 43018 43020 43022 43024 43026 43028 43030 43032 43034 43036 43038 43040 43042 43044 43046 43048 43050 43052 43054 43056 43058 43060 43062 43064 43066 43068 43070 43072 43074 43076 43078 43080 43082 43084 43086 43088 43090 43092 43094 43096 43098 43100 43102 43104 43106 43108 43110 43112 43114 43116 43118 43120 43122 43124 43126 43128 43130 43132 43134 92160 92162 92164 92166 92168 92170 92172 92174 92176 92178 92180 92182 92184 92186 92188 92190 92192 92194 92196 92198 92200 92202 92204 92206 92208 92210 92212 92214 92216 92218 92220 92222 92224 92226 92228 92230 92232 92234 92236 92238 92240 92242 92244 92246 92248 92250 92252 92254 92256 92258 92260 92262 92264 92266 92268 92270 92272 92274 92276 92278 92280 92282 92284 92286 141312 43136 43138 43140 43142 43144 43146 43148 43150 43152 43154 43156 43158 43160 43162 43164 43166 43168 43170 43172 43174 43176 43178 43180 43182 43184 43186 43188 43190 43192 43194 43196 43198 43200 43202 43204 43206 43208 43210 43212 43214 43216 43218 43220 43222 43224 43226 43228 43230 43232 43234 43236 43238 43240 43242 43244 43246 43248 43250 43252 43254 43256 43258 43260 43262 92288 92290 92292 92294 92296 92298 92300 92302 92304 92306 92308 92310 92312 92314 92316 92318 92320 92322 92324 92326 92328 92330 92332 92334 92336 92338 92340 92342 92344 92346 92348 92350 92352 92354 92356 92358 92360 92362 92364 92366 92368 92370 92372 92374 92376 92378 92380 92382 92384 92386 92388 92390 92392 92394 92396 92398 92400 92402 92404 92406 92408 92410 92412 92414 141440 43264 43266 43268 43270 43272 43274 43276 43278 43280 43282 43284 43286 43288 43290 43292 43294 43296 43298 43300 43302 43304 43306 43308 43310 43312 43314 43316 43318 43320 43322 43324 43326 43328 43330 43332 43334 43336 43338 43340 43342 43344 43346 43348 43350 43352 43354 43356 43358 43360 43362 43364 43366 43368 43370 43372 43374 43376 43378 43380 43382 43384 43386 43388 43390 92416 92418 92420 92422 92424 92426 92428 92430 92432 92434 92436 92438 92440 92442 92444 92446 92448 92450 92452 92454 92456 92458 92460 92462 92464 92466 92468 92470 92472 92474 92476 92478 92480 92482 92484 92486 92488 92490 92492 92494 92496 92498 92500 92502 92504 92506 92508 92510 92512 92514 92516 92518 92520 92522 92524 92526 92528 92530 92532 92534 92536 92538 92540 92542 141568 43392 43394 43396 43398 43400 43402 43404 43406 43408 43410 43412 43414 43416 43418 43420 43422 43424 43426 43428 43430 43432 43434 43436 43438 43440 43442 43444 43446 43448 43450 43452 43454 43456 43458 43460 43462 43464 43466 43468 43470 43472 43474 43476 43478 43480 43482 43484 43486 43488 43490 43492 43494 43496 43498 43500 43502 43504 43506 43508 43510 43512 43514 43516 43518 92544 92546 92548 92550 92552 92554 92556 92558 92560 92562 92564 92566 92568 92570 92572 92574 92576 92578 92580 92582 92584 92586 92588 92590 92592 92594 92596 92598 92600 92602 92604 92606 92608 92610 92612 92614 92616 92618 92620 92622 92624 92626 92628 92630 92632 92634 92636 92638 92640 92642 92644 92646 92648 92650 92652 92654 92656 92658 92660 92662 92664 92666 92668 92670 141696 43520 43522 43524 43526 43528 43530 43532 43534 43536 43538 43540 43542 43544 43546 43548 43550 43552 43554 43556 43558 43560 43562 43564 43566 43568 43570 43572 43574 43576 43578 43580 43582 43584 43586 43588 43590 43592 43594 43596 43598 43600 43602 43604 43606 43608 43610 43612 43614 43616 43618 43620 43622 43624 43626 43628 43630 43632 43634 43636 43638 43640 43642 43644 43646 92672 92674 92676 92678 92680 92682 92684 92686 92688 92690 92692 92694 92696 92698 92700 92702 92704 92706 92708 92710 92712 92714 92716 92718 92720 92722 92724 92726 92728 92730 92732 92734 92736 92738 92740 92742 92744 92746 92748 92750 92752 92754 92756 92758 92760 92762 92764 92766 92768 92770 92772 92774 92776 92778 92780 92782 92784 92786 92788 92790 92792 92794 92796 92798 141824 43648 43650 43652 43654 43656 43658 43660 43662 43664 43666 43668 43670 43672 43674 43676 43678 43680 43682 43684 43686 43688 43690 43692 43694 43696 43698 43700 43702 43704 43706 43708 43710 43712 43714 43716 43718 43720 43722 43724 43726 43728 43730 43732 43734 43736 43738 43740 43742 43744 43746 43748 43750 43752 43754 43756 43758 43760 43762 43764 43766 43768 43770 43772 43774 92800 92802 92804 92806 92808 92810 92812 92814 92816 92818 92820 92822 92824 92826 92828 92830 92832 92834 92836 92838 92840 92842 92844 92846 92848 92850 92852 92854 92856 92858 92860 92862 92864 92866 92868 92870 92872 92874 92876 92878 92880 92882 92884 92886 92888 92890 92892 92894 92896 92898 92900 92902 92904 92906 92908 92910 92912 92914 92916 92918 92920 92922 92924 92926 141952 43776 43778 43780 43782 43784 43786 43788 43790 43792 43794 43796 43798 43800 43802 43804 43806 43808 43810 43812 43814 43816 43818 43820 43822 43824 43826 43828 43830 43832 43834 43836 43838 43840 43842 43844 43846 43848 43850 43852 43854 43856 43858 43860 43862 43864 43866 43868 43870 43872 43874 43876 43878 43880 43882 43884 43886 43888 43890 43892 43894 43896 43898 43900 43902 92928 92930 92932 92934 92936 92938 92940 92942 92944 92946 92948 92950 92952 92954 92956 92958 92960 92962 92964 92966 92968 92970 92972 92974 92976 92978 92980 92982 92984 92986 92988 92990 92992 92994 92996 92998 93000 93002 93004 93006 93008 93010 93012 93014 93016 93018 93020 93022 93024 93026 93028 93030 93032 93034 93036 93038 93040 93042 93044 93046 93048 93050 93052 93054 142080 43904 43906 43908 43910 43912 43914 43916 43918 43920 43922 43924 43926 43928 43930 43932 43934 43936 43938 43940 43942 43944 43946 43948 43950 43952 43954 43956 43958 43960 43962 43964 43966 43968 43970 43972 43974 43976 43978 43980 43982 43984 43986 43988 43990 43992 43994 43996 43998 44000 44002 44004 44006 44008 44010 44012 44014 44016 44018 44020 44022 44024 44026 44028 44030 93056 93058 93060 93062 93064 93066 93068 93070 93072 93074 93076 93078 93080 93082 93084 93086 93088 93090 93092 93094 93096 93098 93100 93102 93104 93106 93108 93110 93112 93114 93116 93118 93120 93122 93124 93126 93128 93130 93132 93134 93136 93138 93140 93142 93144 93146 93148 93150 93152 93154 93156 93158 93160 93162 93164 93166 93168 93170 93172 93174 93176 93178 93180 93182 142208 44032 44034 44036 44038 44040 44042 44044 44046 44048 44050 44052 44054 44056 44058 44060 44062 44064 44066 44068 44070 44072 44074 44076 44078 44080 44082 44084 44086 44088 44090 44092 44094 44096 44098 44100 44102 44104 44106 44108 44110 44112 44114 44116 44118 44120 44122 44124 44126 44128 44130 44132 44134 44136 44138 44140 44142 44144 44146 44148 44150 44152 44154 44156 44158 93184 93186 93188 93190 93192 93194 93196 93198 93200 93202 93204 93206 93208 93210 93212 93214 93216 93218 93220 93222 93224 93226 93228 93230 93232 93234 93236 93238 93240 93242 93244 93246 93248 93250 93252 93254 93256 93258 93260 93262 93264 93266 93268 93270 93272 93274 93276 93278 93280 93282 93284 93286 93288 93290 93292 93294 93296 93298 93300 93302 93304 93306 93308 93310 142336 44160 44162 44164 44166 44168 44170 44172 44174 44176 44178 44180 44182 44184 44186 44188 44190 44192 44194 44196 44198 44200 44202 44204 44206 44208 44210 44212 44214 44216 44218 44220 44222 44224 44226 44228 44230 44232 44234 44236 44238 44240 44242 44244 44246 44248 44250 44252 44254 44256 44258 44260 44262 44264 44266 44268 44270 44272 44274 44276 44278 44280 44282 44284 44286 93312 93314 93316 93318 93320 93322 93324 93326 93328 93330 93332 93334 93336 93338 93340 93342 93344 93346 93348 93350 93352 93354 93356 93358 93360 93362 93364 93366 93368 93370 93372 93374 93376 93378 93380 93382 93384 93386 93388 93390 93392 93394 93396 93398 93400 93402 93404 93406 93408 93410 93412 93414 93416 93418 93420 93422 93424 93426 93428 93430 93432 93434 93436 93438 142464 44288 44290 44292 44294 44296 44298 44300 44302 44304 44306 44308 44310 44312 44314 44316 44318 44320 44322 44324 44326 44328 44330 44332 44334 44336 44338 44340 44342 44344 44346 44348 44350 44352 44354 44356 44358 44360 44362 44364 44366 44368 44370 44372 44374 44376 44378 44380 44382 44384 44386 44388 44390 44392 44394 44396 44398 44400 44402 44404 44406 44408 44410 44412 44414 93440 93442 93444 93446 93448 93450 93452 93454 93456 93458 93460 93462 93464 93466 93468 93470 93472 93474 93476 93478 93480 93482 93484 93486 93488 93490 93492 93494 93496 93498 93500 93502 93504 93506 93508 93510 93512 93514 93516 93518 93520 93522 93524 93526 93528 93530 93532 93534 93536 93538 93540 93542 93544 93546 93548 93550 93552 93554 93556 93558 93560 93562 93564 93566 142592 44416 44418 44420 44422 44424 44426 44428 44430 44432 44434 44436 44438 44440 44442 44444 44446 44448 44450 44452 44454 44456 44458 44460 44462 44464 44466 44468 44470 44472 44474 44476 44478 44480 44482 44484 44486 44488 44490 44492 44494 44496 44498 44500 44502 44504 44506 44508 44510 44512 44514 44516 44518 44520 44522 44524 44526 44528 44530 44532 44534 44536 44538 44540 44542 93568 93570 93572 93574 93576 93578 93580 93582 93584 93586 93588 93590 93592 93594 93596 93598 93600 93602 93604 93606 93608 93610 93612 93614 93616 93618 93620 93622 93624 93626 93628 93630 93632 93634 93636 93638 93640 93642 93644 93646 93648 93650 93652 93654 93656 93658 93660 93662 93664 93666 93668 93670 93672 93674 93676 93678 93680 93682 93684 93686 93688 93690 93692 93694 142720 44544 44546 44548 44550 44552 44554 44556 44558 44560 44562 44564 44566 44568 44570 44572 44574 44576 44578 44580 44582 44584 44586 44588 44590 44592 44594 44596 44598 44600 44602 44604 44606 44608 44610 44612 44614 44616 44618 44620 44622 44624 44626 44628 44630 44632 44634 44636 44638 44640 44642 44644 44646 44648 44650 44652 44654 44656 44658 44660 44662 44664 44666 44668 44670 93696 93698 93700 93702 93704 93706 93708 93710 93712 93714 93716 93718 93720 93722 93724 93726 93728 93730 93732 93734 93736 93738 93740 93742 93744 93746 93748 93750 93752 93754 93756 93758 93760 93762 93764 93766 93768 93770 93772 93774 93776 93778 93780 93782 93784 93786 93788 93790 93792 93794 93796 93798 93800 93802 93804 93806 93808 93810 93812 93814 93816 93818 93820 93822 142848 44672 44674 44676 44678 44680 44682 44684 44686 44688 44690 44692 44694 44696 44698 44700 44702 44704 44706 44708 44710 44712 44714 44716 44718 44720 44722 44724 44726 44728 44730 44732 44734 44736 44738 44740 44742 44744 44746 44748 44750 44752 44754 44756 44758 44760 44762 44764 44766 44768 44770 44772 44774 44776 44778 44780 44782 44784 44786 44788 44790 44792 44794 44796 44798 93824 93826 93828 93830 93832 93834 93836 93838 93840 93842 93844 93846 93848 93850 93852 93854 93856 93858 93860 93862 93864 93866 93868 93870 93872 93874 93876 93878 93880 93882 93884 93886 93888 93890 93892 93894 93896 93898 93900 93902 93904 93906 93908 93910 93912 93914 93916 93918 93920 93922 93924 93926 93928 93930 93932 93934 93936 93938 93940 93942 93944 93946 93948 93950 142976 44800 44802 44804 44806 44808 44810 44812 44814 44816 44818 44820 44822 44824 44826 44828 44830 44832 44834 44836 44838 44840 44842 44844 44846 44848 44850 44852 44854 44856 44858 44860 44862 44864 44866 44868 44870 44872 44874 44876 44878 44880 44882 44884 44886 44888 44890 44892 44894 44896 44898 44900 44902 44904 44906 44908 44910 44912 44914 44916 44918 44920 44922 44924 44926 93952 93954 93956 93958 93960 93962 93964 93966 93968 93970 93972 93974 93976 93978 93980 93982 93984 93986 93988 93990 93992 93994 93996 93998 94000 94002 94004 94006 94008 94010 94012 94014 94016 94018 94020 94022 94024 94026 94028 94030 94032 94034 94036 94038 94040 94042 94044 94046 94048 94050 94052 94054 94056 94058 94060 94062 94064 94066 94068 94070 94072 94074 94076 94078 143104 44928 44930 44932 44934 44936 44938 44940 44942 44944 44946 44948 44950 44952 44954 44956 44958 44960 44962 44964 44966 44968 44970 44972 44974 44976 44978 44980 44982 44984 44986 44988 44990 44992 44994 44996 44998 45000 45002 45004 45006 45008 45010 45012 45014 45016 45018 45020 45022 45024 45026 45028 45030 45032 45034 45036 45038 45040 45042 45044 45046 45048 45050 45052 45054 94080 94082 94084 94086 94088 94090 94092 94094 94096 94098 94100 94102 94104 94106 94108 94110 94112 94114 94116 94118 94120 94122 94124 94126 94128 94130 94132 94134 94136 94138 94140 94142 94144 94146 94148 94150 94152 94154 94156 94158 94160 94162 94164 94166 94168 94170 94172 94174 94176 94178 94180 94182 94184 94186 94188 94190 94192 94194 94196 94198 94200 94202 94204 94206 143232 45056 45058 45060 45062 45064 45066 45068 45070 45072 45074 45076 45078 45080 45082 45084 45086 45088 45090 45092 45094 45096 45098 45100 45102 45104 45106 45108 45110 45112 45114 45116 45118 45120 45122 45124 45126 45128 45130 45132 45134 45136 45138 45140 45142 45144 45146 45148 45150 45152 45154 45156 45158 45160 45162 45164 45166 45168 45170 45172 45174 45176 45178 45180 45182 94208 94210 94212 94214 94216 94218 94220 94222 94224 94226 94228 94230 94232 94234 94236 94238 94240 94242 94244 94246 94248 94250 94252 94254 94256 94258 94260 94262 94264 94266 94268 94270 94272 94274 94276 94278 94280 94282 94284 94286 94288 94290 94292 94294 94296 94298 94300 94302 94304 94306 94308 94310 94312 94314 94316 94318 94320 94322 94324 94326 94328 94330 94332 94334 143360 �������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x127x1x4.txt������������������������������������������0000664�0000000�0000000�00000004265�14364043643�0023253�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 2 130 258 386 4 132 260 388 6 134 262 390 8 136 264 392 10 138 266 394 12 140 268 396 14 142 270 398 16 144 272 400 18 146 274 402 20 148 276 404 22 150 278 406 24 152 280 408 26 154 282 410 28 156 284 412 30 158 286 414 32 160 288 416 34 162 290 418 36 164 292 420 38 166 294 422 40 168 296 424 42 170 298 426 44 172 300 428 46 174 302 430 48 176 304 432 50 178 306 434 52 180 308 436 54 182 310 438 56 184 312 440 58 186 314 442 60 188 316 444 62 190 318 446 64 192 320 448 66 194 322 450 68 196 324 452 70 198 326 454 72 200 328 456 74 202 330 458 76 204 332 460 78 206 334 462 80 208 336 464 82 210 338 466 84 212 340 468 86 214 342 470 88 216 344 472 90 218 346 474 92 220 348 476 94 222 350 478 96 224 352 480 98 226 354 482 100 228 356 484 102 230 358 486 104 232 360 488 106 234 362 490 108 236 364 492 110 238 366 494 112 240 368 496 114 242 370 498 116 244 372 500 118 246 374 502 120 248 376 504 122 250 378 506 124 252 380 508 126 254 382 510 4096 4224 4352 4480 4098 4226 4354 4482 4100 4228 4356 4484 4102 4230 4358 4486 4104 4232 4360 4488 4106 4234 4362 4490 4108 4236 4364 4492 4110 4238 4366 4494 4112 4240 4368 4496 4114 4242 4370 4498 4116 4244 4372 4500 4118 4246 4374 4502 4120 4248 4376 4504 4122 4250 4378 4506 4124 4252 4380 4508 4126 4254 4382 4510 4128 4256 4384 4512 4130 4258 4386 4514 4132 4260 4388 4516 4134 4262 4390 4518 4136 4264 4392 4520 4138 4266 4394 4522 4140 4268 4396 4524 4142 4270 4398 4526 4144 4272 4400 4528 4146 4274 4402 4530 4148 4276 4404 4532 4150 4278 4406 4534 4152 4280 4408 4536 4154 4282 4410 4538 4156 4284 4412 4540 4158 4286 4414 4542 4160 4288 4416 4544 4162 4290 4418 4546 4164 4292 4420 4548 4166 4294 4422 4550 4168 4296 4424 4552 4170 4298 4426 4554 4172 4300 4428 4556 4174 4302 4430 4558 4176 4304 4432 4560 4178 4306 4434 4562 4180 4308 4436 4564 4182 4310 4438 4566 4184 4312 4440 4568 4186 4314 4442 4570 4188 4316 4444 4572 4190 4318 4446 4574 4192 4320 4448 4576 4194 4322 4450 4578 4196 4324 4452 4580 4198 4326 4454 4582 4200 4328 4456 4584 4202 4330 4458 4586 4204 4332 4460 4588 4206 4334 4462 4590 4208 4336 4464 4592 4210 4338 4466 4594 4212 4340 4468 4596 4214 4342 4470 4598 4216 4344 4472 4600 4218 4346 4474 4602 4220 4348 4476 4604 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x128x1x4.txt������������������������������������������0000664�0000000�0000000�00000004311�14364043643�0023244�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 2 130 258 386 4 132 260 388 6 134 262 390 8 136 264 392 10 138 266 394 12 140 268 396 14 142 270 398 16 144 272 400 18 146 274 402 20 148 276 404 22 150 278 406 24 152 280 408 26 154 282 410 28 156 284 412 30 158 286 414 32 160 288 416 34 162 290 418 36 164 292 420 38 166 294 422 40 168 296 424 42 170 298 426 44 172 300 428 46 174 302 430 48 176 304 432 50 178 306 434 52 180 308 436 54 182 310 438 56 184 312 440 58 186 314 442 60 188 316 444 62 190 318 446 64 192 320 448 66 194 322 450 68 196 324 452 70 198 326 454 72 200 328 456 74 202 330 458 76 204 332 460 78 206 334 462 80 208 336 464 82 210 338 466 84 212 340 468 86 214 342 470 88 216 344 472 90 218 346 474 92 220 348 476 94 222 350 478 96 224 352 480 98 226 354 482 100 228 356 484 102 230 358 486 104 232 360 488 106 234 362 490 108 236 364 492 110 238 366 494 112 240 368 496 114 242 370 498 116 244 372 500 118 246 374 502 120 248 376 504 122 250 378 506 124 252 380 508 126 254 382 510 4096 4224 4352 4480 4098 4226 4354 4482 4100 4228 4356 4484 4102 4230 4358 4486 4104 4232 4360 4488 4106 4234 4362 4490 4108 4236 4364 4492 4110 4238 4366 4494 4112 4240 4368 4496 4114 4242 4370 4498 4116 4244 4372 4500 4118 4246 4374 4502 4120 4248 4376 4504 4122 4250 4378 4506 4124 4252 4380 4508 4126 4254 4382 4510 4128 4256 4384 4512 4130 4258 4386 4514 4132 4260 4388 4516 4134 4262 4390 4518 4136 4264 4392 4520 4138 4266 4394 4522 4140 4268 4396 4524 4142 4270 4398 4526 4144 4272 4400 4528 4146 4274 4402 4530 4148 4276 4404 4532 4150 4278 4406 4534 4152 4280 4408 4536 4154 4282 4410 4538 4156 4284 4412 4540 4158 4286 4414 4542 4160 4288 4416 4544 4162 4290 4418 4546 4164 4292 4420 4548 4166 4294 4422 4550 4168 4296 4424 4552 4170 4298 4426 4554 4172 4300 4428 4556 4174 4302 4430 4558 4176 4304 4432 4560 4178 4306 4434 4562 4180 4308 4436 4564 4182 4310 4438 4566 4184 4312 4440 4568 4186 4314 4442 4570 4188 4316 4444 4572 4190 4318 4446 4574 4192 4320 4448 4576 4194 4322 4450 4578 4196 4324 4452 4580 4198 4326 4454 4582 4200 4328 4456 4584 4202 4330 4458 4586 4204 4332 4460 4588 4206 4334 4462 4590 4208 4336 4464 4592 4210 4338 4466 4594 4212 4340 4468 4596 4214 4342 4470 4598 4216 4344 4472 4600 4218 4346 4474 4602 4220 4348 4476 4604 4222 4350 4478 4606 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x129x1x4.txt������������������������������������������0000664�0000000�0000000�00000004335�14364043643�0023253�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 2 130 258 386 4 132 260 388 6 134 262 390 8 136 264 392 10 138 266 394 12 140 268 396 14 142 270 398 16 144 272 400 18 146 274 402 20 148 276 404 22 150 278 406 24 152 280 408 26 154 282 410 28 156 284 412 30 158 286 414 32 160 288 416 34 162 290 418 36 164 292 420 38 166 294 422 40 168 296 424 42 170 298 426 44 172 300 428 46 174 302 430 48 176 304 432 50 178 306 434 52 180 308 436 54 182 310 438 56 184 312 440 58 186 314 442 60 188 316 444 62 190 318 446 64 192 320 448 66 194 322 450 68 196 324 452 70 198 326 454 72 200 328 456 74 202 330 458 76 204 332 460 78 206 334 462 80 208 336 464 82 210 338 466 84 212 340 468 86 214 342 470 88 216 344 472 90 218 346 474 92 220 348 476 94 222 350 478 96 224 352 480 98 226 354 482 100 228 356 484 102 230 358 486 104 232 360 488 106 234 362 490 108 236 364 492 110 238 366 494 112 240 368 496 114 242 370 498 116 244 372 500 118 246 374 502 120 248 376 504 122 250 378 506 124 252 380 508 126 254 382 510 4096 4224 4352 4480 4098 4226 4354 4482 4100 4228 4356 4484 4102 4230 4358 4486 4104 4232 4360 4488 4106 4234 4362 4490 4108 4236 4364 4492 4110 4238 4366 4494 4112 4240 4368 4496 4114 4242 4370 4498 4116 4244 4372 4500 4118 4246 4374 4502 4120 4248 4376 4504 4122 4250 4378 4506 4124 4252 4380 4508 4126 4254 4382 4510 4128 4256 4384 4512 4130 4258 4386 4514 4132 4260 4388 4516 4134 4262 4390 4518 4136 4264 4392 4520 4138 4266 4394 4522 4140 4268 4396 4524 4142 4270 4398 4526 4144 4272 4400 4528 4146 4274 4402 4530 4148 4276 4404 4532 4150 4278 4406 4534 4152 4280 4408 4536 4154 4282 4410 4538 4156 4284 4412 4540 4158 4286 4414 4542 4160 4288 4416 4544 4162 4290 4418 4546 4164 4292 4420 4548 4166 4294 4422 4550 4168 4296 4424 4552 4170 4298 4426 4554 4172 4300 4428 4556 4174 4302 4430 4558 4176 4304 4432 4560 4178 4306 4434 4562 4180 4308 4436 4564 4182 4310 4438 4566 4184 4312 4440 4568 4186 4314 4442 4570 4188 4316 4444 4572 4190 4318 4446 4574 4192 4320 4448 4576 4194 4322 4450 4578 4196 4324 4452 4580 4198 4326 4454 4582 4200 4328 4456 4584 4202 4330 4458 4586 4204 4332 4460 4588 4206 4334 4462 4590 4208 4336 4464 4592 4210 4338 4466 4594 4212 4340 4468 4596 4214 4342 4470 4598 4216 4344 4472 4600 4218 4346 4474 4602 4220 4348 4476 4604 4222 4350 4478 4606 8192 8320 8448 8576 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x1x4x4.txt��������������������������������������������0000664�0000000�0000000�00000000116�14364043643�0023074�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 4096 4224 4352 4480 8192 8320 8448 8576 12288 12416 12544 12672 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x3x32x32.txt������������������������������������������0000664�0000000�0000000�00000044713�14364043643�0023253�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 3968 4096 4224 4352 4480 4608 4736 4864 4992 5120 5248 5376 5504 5632 5760 5888 6016 6144 6272 6400 6528 6656 6784 6912 7040 7168 7296 7424 7552 7680 7808 7936 8064 8192 8320 8448 8576 8704 8832 8960 9088 9216 9344 9472 9600 9728 9856 9984 10112 10240 10368 10496 10624 10752 10880 11008 11136 11264 11392 11520 11648 11776 11904 12032 12160 12288 12416 12544 12672 12800 12928 13056 13184 13312 13440 13568 13696 13824 13952 14080 14208 14336 14464 14592 14720 14848 14976 15104 15232 15360 15488 15616 15744 15872 16000 16128 16256 16384 16512 16640 16768 16896 17024 17152 17280 17408 17536 17664 17792 17920 18048 18176 18304 18432 18560 18688 18816 18944 19072 19200 19328 19456 19584 19712 19840 19968 20096 20224 20352 20480 20608 20736 20864 20992 21120 21248 21376 21504 21632 21760 21888 22016 22144 22272 22400 22528 22656 22784 22912 23040 23168 23296 23424 23552 23680 23808 23936 24064 24192 24320 24448 24576 24704 24832 24960 25088 25216 25344 25472 25600 25728 25856 25984 26112 26240 26368 26496 26624 26752 26880 27008 27136 27264 27392 27520 27648 27776 27904 28032 28160 28288 28416 28544 28672 28800 28928 29056 29184 29312 29440 29568 29696 29824 29952 30080 30208 30336 30464 30592 30720 30848 30976 31104 31232 31360 31488 31616 31744 31872 32000 32128 32256 32384 32512 32640 32768 32896 33024 33152 33280 33408 33536 33664 33792 33920 34048 34176 34304 34432 34560 34688 34816 34944 35072 35200 35328 35456 35584 35712 35840 35968 36096 36224 36352 36480 36608 36736 36864 36992 37120 37248 37376 37504 37632 37760 37888 38016 38144 38272 38400 38528 38656 38784 38912 39040 39168 39296 39424 39552 39680 39808 39936 40064 40192 40320 40448 40576 40704 40832 40960 41088 41216 41344 41472 41600 41728 41856 41984 42112 42240 42368 42496 42624 42752 42880 43008 43136 43264 43392 43520 43648 43776 43904 44032 44160 44288 44416 44544 44672 44800 44928 45056 45184 45312 45440 45568 45696 45824 45952 46080 46208 46336 46464 46592 46720 46848 46976 47104 47232 47360 47488 47616 47744 47872 48000 48128 48256 48384 48512 48640 48768 48896 49024 49152 49280 49408 49536 49664 49792 49920 50048 50176 50304 50432 50560 50688 50816 50944 51072 51200 51328 51456 51584 51712 51840 51968 52096 52224 52352 52480 52608 52736 52864 52992 53120 53248 53376 53504 53632 53760 53888 54016 54144 54272 54400 54528 54656 54784 54912 55040 55168 55296 55424 55552 55680 55808 55936 56064 56192 56320 56448 56576 56704 56832 56960 57088 57216 57344 57472 57600 57728 57856 57984 58112 58240 58368 58496 58624 58752 58880 59008 59136 59264 59392 59520 59648 59776 59904 60032 60160 60288 60416 60544 60672 60800 60928 61056 61184 61312 61440 61568 61696 61824 61952 62080 62208 62336 62464 62592 62720 62848 62976 63104 63232 63360 63488 63616 63744 63872 64000 64128 64256 64384 64512 64640 64768 64896 65024 65152 65280 65408 65536 65664 65792 65920 66048 66176 66304 66432 66560 66688 66816 66944 67072 67200 67328 67456 67584 67712 67840 67968 68096 68224 68352 68480 68608 68736 68864 68992 69120 69248 69376 69504 69632 69760 69888 70016 70144 70272 70400 70528 70656 70784 70912 71040 71168 71296 71424 71552 71680 71808 71936 72064 72192 72320 72448 72576 72704 72832 72960 73088 73216 73344 73472 73600 73728 73856 73984 74112 74240 74368 74496 74624 74752 74880 75008 75136 75264 75392 75520 75648 75776 75904 76032 76160 76288 76416 76544 76672 76800 76928 77056 77184 77312 77440 77568 77696 77824 77952 78080 78208 78336 78464 78592 78720 78848 78976 79104 79232 79360 79488 79616 79744 79872 80000 80128 80256 80384 80512 80640 80768 80896 81024 81152 81280 81408 81536 81664 81792 81920 82048 82176 82304 82432 82560 82688 82816 82944 83072 83200 83328 83456 83584 83712 83840 83968 84096 84224 84352 84480 84608 84736 84864 84992 85120 85248 85376 85504 85632 85760 85888 86016 86144 86272 86400 86528 86656 86784 86912 87040 87168 87296 87424 87552 87680 87808 87936 88064 88192 88320 88448 88576 88704 88832 88960 89088 89216 89344 89472 89600 89728 89856 89984 90112 90240 90368 90496 90624 90752 90880 91008 91136 91264 91392 91520 91648 91776 91904 92032 92160 92288 92416 92544 92672 92800 92928 93056 93184 93312 93440 93568 93696 93824 93952 94080 94208 94336 94464 94592 94720 94848 94976 95104 95232 95360 95488 95616 95744 95872 96000 96128 96256 96384 96512 96640 96768 96896 97024 97152 97280 97408 97536 97664 97792 97920 98048 98176 98304 98432 98560 98688 98816 98944 99072 99200 99328 99456 99584 99712 99840 99968 100096 100224 100352 100480 100608 100736 100864 100992 101120 101248 101376 101504 101632 101760 101888 102016 102144 102272 102400 102528 102656 102784 102912 103040 103168 103296 103424 103552 103680 103808 103936 104064 104192 104320 104448 104576 104704 104832 104960 105088 105216 105344 105472 105600 105728 105856 105984 106112 106240 106368 106496 106624 106752 106880 107008 107136 107264 107392 107520 107648 107776 107904 108032 108160 108288 108416 108544 108672 108800 108928 109056 109184 109312 109440 109568 109696 109824 109952 110080 110208 110336 110464 110592 110720 110848 110976 111104 111232 111360 111488 111616 111744 111872 112000 112128 112256 112384 112512 112640 112768 112896 113024 113152 113280 113408 113536 113664 113792 113920 114048 114176 114304 114432 114560 114688 114816 114944 115072 115200 115328 115456 115584 115712 115840 115968 116096 116224 116352 116480 116608 116736 116864 116992 117120 117248 117376 117504 117632 117760 117888 118016 118144 118272 118400 118528 118656 118784 118912 119040 119168 119296 119424 119552 119680 119808 119936 120064 120192 120320 120448 120576 120704 120832 120960 121088 121216 121344 121472 121600 121728 121856 121984 122112 122240 122368 122496 122624 122752 122880 123008 123136 123264 123392 123520 123648 123776 123904 124032 124160 124288 124416 124544 124672 124800 124928 125056 125184 125312 125440 125568 125696 125824 125952 126080 126208 126336 126464 126592 126720 126848 126976 127104 127232 127360 127488 127616 127744 127872 128000 128128 128256 128384 128512 128640 128768 128896 129024 129152 129280 129408 129536 129664 129792 129920 130048 130176 130304 130432 130560 130688 130816 130944 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 3970 4098 4226 4354 4482 4610 4738 4866 4994 5122 5250 5378 5506 5634 5762 5890 6018 6146 6274 6402 6530 6658 6786 6914 7042 7170 7298 7426 7554 7682 7810 7938 8066 8194 8322 8450 8578 8706 8834 8962 9090 9218 9346 9474 9602 9730 9858 9986 10114 10242 10370 10498 10626 10754 10882 11010 11138 11266 11394 11522 11650 11778 11906 12034 12162 12290 12418 12546 12674 12802 12930 13058 13186 13314 13442 13570 13698 13826 13954 14082 14210 14338 14466 14594 14722 14850 14978 15106 15234 15362 15490 15618 15746 15874 16002 16130 16258 16386 16514 16642 16770 16898 17026 17154 17282 17410 17538 17666 17794 17922 18050 18178 18306 18434 18562 18690 18818 18946 19074 19202 19330 19458 19586 19714 19842 19970 20098 20226 20354 20482 20610 20738 20866 20994 21122 21250 21378 21506 21634 21762 21890 22018 22146 22274 22402 22530 22658 22786 22914 23042 23170 23298 23426 23554 23682 23810 23938 24066 24194 24322 24450 24578 24706 24834 24962 25090 25218 25346 25474 25602 25730 25858 25986 26114 26242 26370 26498 26626 26754 26882 27010 27138 27266 27394 27522 27650 27778 27906 28034 28162 28290 28418 28546 28674 28802 28930 29058 29186 29314 29442 29570 29698 29826 29954 30082 30210 30338 30466 30594 30722 30850 30978 31106 31234 31362 31490 31618 31746 31874 32002 32130 32258 32386 32514 32642 32770 32898 33026 33154 33282 33410 33538 33666 33794 33922 34050 34178 34306 34434 34562 34690 34818 34946 35074 35202 35330 35458 35586 35714 35842 35970 36098 36226 36354 36482 36610 36738 36866 36994 37122 37250 37378 37506 37634 37762 37890 38018 38146 38274 38402 38530 38658 38786 38914 39042 39170 39298 39426 39554 39682 39810 39938 40066 40194 40322 40450 40578 40706 40834 40962 41090 41218 41346 41474 41602 41730 41858 41986 42114 42242 42370 42498 42626 42754 42882 43010 43138 43266 43394 43522 43650 43778 43906 44034 44162 44290 44418 44546 44674 44802 44930 45058 45186 45314 45442 45570 45698 45826 45954 46082 46210 46338 46466 46594 46722 46850 46978 47106 47234 47362 47490 47618 47746 47874 48002 48130 48258 48386 48514 48642 48770 48898 49026 49154 49282 49410 49538 49666 49794 49922 50050 50178 50306 50434 50562 50690 50818 50946 51074 51202 51330 51458 51586 51714 51842 51970 52098 52226 52354 52482 52610 52738 52866 52994 53122 53250 53378 53506 53634 53762 53890 54018 54146 54274 54402 54530 54658 54786 54914 55042 55170 55298 55426 55554 55682 55810 55938 56066 56194 56322 56450 56578 56706 56834 56962 57090 57218 57346 57474 57602 57730 57858 57986 58114 58242 58370 58498 58626 58754 58882 59010 59138 59266 59394 59522 59650 59778 59906 60034 60162 60290 60418 60546 60674 60802 60930 61058 61186 61314 61442 61570 61698 61826 61954 62082 62210 62338 62466 62594 62722 62850 62978 63106 63234 63362 63490 63618 63746 63874 64002 64130 64258 64386 64514 64642 64770 64898 65026 65154 65282 65410 65538 65666 65794 65922 66050 66178 66306 66434 66562 66690 66818 66946 67074 67202 67330 67458 67586 67714 67842 67970 68098 68226 68354 68482 68610 68738 68866 68994 69122 69250 69378 69506 69634 69762 69890 70018 70146 70274 70402 70530 70658 70786 70914 71042 71170 71298 71426 71554 71682 71810 71938 72066 72194 72322 72450 72578 72706 72834 72962 73090 73218 73346 73474 73602 73730 73858 73986 74114 74242 74370 74498 74626 74754 74882 75010 75138 75266 75394 75522 75650 75778 75906 76034 76162 76290 76418 76546 76674 76802 76930 77058 77186 77314 77442 77570 77698 77826 77954 78082 78210 78338 78466 78594 78722 78850 78978 79106 79234 79362 79490 79618 79746 79874 80002 80130 80258 80386 80514 80642 80770 80898 81026 81154 81282 81410 81538 81666 81794 81922 82050 82178 82306 82434 82562 82690 82818 82946 83074 83202 83330 83458 83586 83714 83842 83970 84098 84226 84354 84482 84610 84738 84866 84994 85122 85250 85378 85506 85634 85762 85890 86018 86146 86274 86402 86530 86658 86786 86914 87042 87170 87298 87426 87554 87682 87810 87938 88066 88194 88322 88450 88578 88706 88834 88962 89090 89218 89346 89474 89602 89730 89858 89986 90114 90242 90370 90498 90626 90754 90882 91010 91138 91266 91394 91522 91650 91778 91906 92034 92162 92290 92418 92546 92674 92802 92930 93058 93186 93314 93442 93570 93698 93826 93954 94082 94210 94338 94466 94594 94722 94850 94978 95106 95234 95362 95490 95618 95746 95874 96002 96130 96258 96386 96514 96642 96770 96898 97026 97154 97282 97410 97538 97666 97794 97922 98050 98178 98306 98434 98562 98690 98818 98946 99074 99202 99330 99458 99586 99714 99842 99970 100098 100226 100354 100482 100610 100738 100866 100994 101122 101250 101378 101506 101634 101762 101890 102018 102146 102274 102402 102530 102658 102786 102914 103042 103170 103298 103426 103554 103682 103810 103938 104066 104194 104322 104450 104578 104706 104834 104962 105090 105218 105346 105474 105602 105730 105858 105986 106114 106242 106370 106498 106626 106754 106882 107010 107138 107266 107394 107522 107650 107778 107906 108034 108162 108290 108418 108546 108674 108802 108930 109058 109186 109314 109442 109570 109698 109826 109954 110082 110210 110338 110466 110594 110722 110850 110978 111106 111234 111362 111490 111618 111746 111874 112002 112130 112258 112386 112514 112642 112770 112898 113026 113154 113282 113410 113538 113666 113794 113922 114050 114178 114306 114434 114562 114690 114818 114946 115074 115202 115330 115458 115586 115714 115842 115970 116098 116226 116354 116482 116610 116738 116866 116994 117122 117250 117378 117506 117634 117762 117890 118018 118146 118274 118402 118530 118658 118786 118914 119042 119170 119298 119426 119554 119682 119810 119938 120066 120194 120322 120450 120578 120706 120834 120962 121090 121218 121346 121474 121602 121730 121858 121986 122114 122242 122370 122498 122626 122754 122882 123010 123138 123266 123394 123522 123650 123778 123906 124034 124162 124290 124418 124546 124674 124802 124930 125058 125186 125314 125442 125570 125698 125826 125954 126082 126210 126338 126466 126594 126722 126850 126978 127106 127234 127362 127490 127618 127746 127874 128002 128130 128258 128386 128514 128642 128770 128898 129026 129154 129282 129410 129538 129666 129794 129922 130050 130178 130306 130434 130562 130690 130818 130946 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 3972 4100 4228 4356 4484 4612 4740 4868 4996 5124 5252 5380 5508 5636 5764 5892 6020 6148 6276 6404 6532 6660 6788 6916 7044 7172 7300 7428 7556 7684 7812 7940 8068 8196 8324 8452 8580 8708 8836 8964 9092 9220 9348 9476 9604 9732 9860 9988 10116 10244 10372 10500 10628 10756 10884 11012 11140 11268 11396 11524 11652 11780 11908 12036 12164 12292 12420 12548 12676 12804 12932 13060 13188 13316 13444 13572 13700 13828 13956 14084 14212 14340 14468 14596 14724 14852 14980 15108 15236 15364 15492 15620 15748 15876 16004 16132 16260 16388 16516 16644 16772 16900 17028 17156 17284 17412 17540 17668 17796 17924 18052 18180 18308 18436 18564 18692 18820 18948 19076 19204 19332 19460 19588 19716 19844 19972 20100 20228 20356 20484 20612 20740 20868 20996 21124 21252 21380 21508 21636 21764 21892 22020 22148 22276 22404 22532 22660 22788 22916 23044 23172 23300 23428 23556 23684 23812 23940 24068 24196 24324 24452 24580 24708 24836 24964 25092 25220 25348 25476 25604 25732 25860 25988 26116 26244 26372 26500 26628 26756 26884 27012 27140 27268 27396 27524 27652 27780 27908 28036 28164 28292 28420 28548 28676 28804 28932 29060 29188 29316 29444 29572 29700 29828 29956 30084 30212 30340 30468 30596 30724 30852 30980 31108 31236 31364 31492 31620 31748 31876 32004 32132 32260 32388 32516 32644 32772 32900 33028 33156 33284 33412 33540 33668 33796 33924 34052 34180 34308 34436 34564 34692 34820 34948 35076 35204 35332 35460 35588 35716 35844 35972 36100 36228 36356 36484 36612 36740 36868 36996 37124 37252 37380 37508 37636 37764 37892 38020 38148 38276 38404 38532 38660 38788 38916 39044 39172 39300 39428 39556 39684 39812 39940 40068 40196 40324 40452 40580 40708 40836 40964 41092 41220 41348 41476 41604 41732 41860 41988 42116 42244 42372 42500 42628 42756 42884 43012 43140 43268 43396 43524 43652 43780 43908 44036 44164 44292 44420 44548 44676 44804 44932 45060 45188 45316 45444 45572 45700 45828 45956 46084 46212 46340 46468 46596 46724 46852 46980 47108 47236 47364 47492 47620 47748 47876 48004 48132 48260 48388 48516 48644 48772 48900 49028 49156 49284 49412 49540 49668 49796 49924 50052 50180 50308 50436 50564 50692 50820 50948 51076 51204 51332 51460 51588 51716 51844 51972 52100 52228 52356 52484 52612 52740 52868 52996 53124 53252 53380 53508 53636 53764 53892 54020 54148 54276 54404 54532 54660 54788 54916 55044 55172 55300 55428 55556 55684 55812 55940 56068 56196 56324 56452 56580 56708 56836 56964 57092 57220 57348 57476 57604 57732 57860 57988 58116 58244 58372 58500 58628 58756 58884 59012 59140 59268 59396 59524 59652 59780 59908 60036 60164 60292 60420 60548 60676 60804 60932 61060 61188 61316 61444 61572 61700 61828 61956 62084 62212 62340 62468 62596 62724 62852 62980 63108 63236 63364 63492 63620 63748 63876 64004 64132 64260 64388 64516 64644 64772 64900 65028 65156 65284 65412 65540 65668 65796 65924 66052 66180 66308 66436 66564 66692 66820 66948 67076 67204 67332 67460 67588 67716 67844 67972 68100 68228 68356 68484 68612 68740 68868 68996 69124 69252 69380 69508 69636 69764 69892 70020 70148 70276 70404 70532 70660 70788 70916 71044 71172 71300 71428 71556 71684 71812 71940 72068 72196 72324 72452 72580 72708 72836 72964 73092 73220 73348 73476 73604 73732 73860 73988 74116 74244 74372 74500 74628 74756 74884 75012 75140 75268 75396 75524 75652 75780 75908 76036 76164 76292 76420 76548 76676 76804 76932 77060 77188 77316 77444 77572 77700 77828 77956 78084 78212 78340 78468 78596 78724 78852 78980 79108 79236 79364 79492 79620 79748 79876 80004 80132 80260 80388 80516 80644 80772 80900 81028 81156 81284 81412 81540 81668 81796 81924 82052 82180 82308 82436 82564 82692 82820 82948 83076 83204 83332 83460 83588 83716 83844 83972 84100 84228 84356 84484 84612 84740 84868 84996 85124 85252 85380 85508 85636 85764 85892 86020 86148 86276 86404 86532 86660 86788 86916 87044 87172 87300 87428 87556 87684 87812 87940 88068 88196 88324 88452 88580 88708 88836 88964 89092 89220 89348 89476 89604 89732 89860 89988 90116 90244 90372 90500 90628 90756 90884 91012 91140 91268 91396 91524 91652 91780 91908 92036 92164 92292 92420 92548 92676 92804 92932 93060 93188 93316 93444 93572 93700 93828 93956 94084 94212 94340 94468 94596 94724 94852 94980 95108 95236 95364 95492 95620 95748 95876 96004 96132 96260 96388 96516 96644 96772 96900 97028 97156 97284 97412 97540 97668 97796 97924 98052 98180 98308 98436 98564 98692 98820 98948 99076 99204 99332 99460 99588 99716 99844 99972 100100 100228 100356 100484 100612 100740 100868 100996 101124 101252 101380 101508 101636 101764 101892 102020 102148 102276 102404 102532 102660 102788 102916 103044 103172 103300 103428 103556 103684 103812 103940 104068 104196 104324 104452 104580 104708 104836 104964 105092 105220 105348 105476 105604 105732 105860 105988 106116 106244 106372 106500 106628 106756 106884 107012 107140 107268 107396 107524 107652 107780 107908 108036 108164 108292 108420 108548 108676 108804 108932 109060 109188 109316 109444 109572 109700 109828 109956 110084 110212 110340 110468 110596 110724 110852 110980 111108 111236 111364 111492 111620 111748 111876 112004 112132 112260 112388 112516 112644 112772 112900 113028 113156 113284 113412 113540 113668 113796 113924 114052 114180 114308 114436 114564 114692 114820 114948 115076 115204 115332 115460 115588 115716 115844 115972 116100 116228 116356 116484 116612 116740 116868 116996 117124 117252 117380 117508 117636 117764 117892 118020 118148 118276 118404 118532 118660 118788 118916 119044 119172 119300 119428 119556 119684 119812 119940 120068 120196 120324 120452 120580 120708 120836 120964 121092 121220 121348 121476 121604 121732 121860 121988 122116 122244 122372 122500 122628 122756 122884 123012 123140 123268 123396 123524 123652 123780 123908 124036 124164 124292 124420 124548 124676 124804 124932 125060 125188 125316 125444 125572 125700 125828 125956 126084 126212 126340 126468 126596 126724 126852 126980 127108 127236 127364 127492 127620 127748 127876 128004 128132 128260 128388 128516 128644 128772 128900 129028 129156 129284 129412 129540 129668 129796 129924 130052 130180 130308 130436 130564 130692 130820 130948 �����������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x4x1x63.txt�������������������������������������������0000664�0000000�0000000�00000002304�14364043643�0023162�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 3968 4096 4224 4352 4480 4608 4736 4864 4992 5120 5248 5376 5504 5632 5760 5888 6016 6144 6272 6400 6528 6656 6784 6912 7040 7168 7296 7424 7552 7680 7808 7936 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 3970 4098 4226 4354 4482 4610 4738 4866 4994 5122 5250 5378 5506 5634 5762 5890 6018 6146 6274 6402 6530 6658 6786 6914 7042 7170 7298 7426 7554 7682 7810 7938 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 3972 4100 4228 4356 4484 4612 4740 4868 4996 5124 5252 5380 5508 5636 5764 5892 6020 6148 6276 6404 6532 6660 6788 6916 7044 7172 7300 7428 7556 7684 7812 7940 6 134 262 390 518 646 774 902 1030 1158 1286 1414 1542 1670 1798 1926 2054 2182 2310 2438 2566 2694 2822 2950 3078 3206 3334 3462 3590 3718 3846 3974 4102 4230 4358 4486 4614 4742 4870 4998 5126 5254 5382 5510 5638 5766 5894 6022 6150 6278 6406 6534 6662 6790 6918 7046 7174 7302 7430 7558 7686 7814 7942 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x4x1x64.txt�������������������������������������������0000664�0000000�0000000�00000002330�14364043643�0023162�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 3968 4096 4224 4352 4480 4608 4736 4864 4992 5120 5248 5376 5504 5632 5760 5888 6016 6144 6272 6400 6528 6656 6784 6912 7040 7168 7296 7424 7552 7680 7808 7936 8064 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 3970 4098 4226 4354 4482 4610 4738 4866 4994 5122 5250 5378 5506 5634 5762 5890 6018 6146 6274 6402 6530 6658 6786 6914 7042 7170 7298 7426 7554 7682 7810 7938 8066 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 3972 4100 4228 4356 4484 4612 4740 4868 4996 5124 5252 5380 5508 5636 5764 5892 6020 6148 6276 6404 6532 6660 6788 6916 7044 7172 7300 7428 7556 7684 7812 7940 8068 6 134 262 390 518 646 774 902 1030 1158 1286 1414 1542 1670 1798 1926 2054 2182 2310 2438 2566 2694 2822 2950 3078 3206 3334 3462 3590 3718 3846 3974 4102 4230 4358 4486 4614 4742 4870 4998 5126 5254 5382 5510 5638 5766 5894 6022 6150 6278 6406 6534 6662 6790 6918 7046 7174 7302 7430 7558 7686 7814 7942 8070 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x4x1x65.txt�������������������������������������������0000664�0000000�0000000�00000002354�14364043643�0023171�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 3968 4096 4224 4352 4480 4608 4736 4864 4992 5120 5248 5376 5504 5632 5760 5888 6016 6144 6272 6400 6528 6656 6784 6912 7040 7168 7296 7424 7552 7680 7808 7936 8064 8192 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 3970 4098 4226 4354 4482 4610 4738 4866 4994 5122 5250 5378 5506 5634 5762 5890 6018 6146 6274 6402 6530 6658 6786 6914 7042 7170 7298 7426 7554 7682 7810 7938 8066 8194 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 3972 4100 4228 4356 4484 4612 4740 4868 4996 5124 5252 5380 5508 5636 5764 5892 6020 6148 6276 6404 6532 6660 6788 6916 7044 7172 7300 7428 7556 7684 7812 7940 8068 8196 6 134 262 390 518 646 774 902 1030 1158 1286 1414 1542 1670 1798 1926 2054 2182 2310 2438 2566 2694 2822 2950 3078 3206 3334 3462 3590 3718 3846 3974 4102 4230 4358 4486 4614 4742 4870 4998 5126 5254 5382 5510 5638 5766 5894 6022 6150 6278 6406 6534 6662 6790 6918 7046 7174 7302 7430 7558 7686 7814 7942 8070 8198 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x4x2x3.txt��������������������������������������������0000664�0000000�0000000�00000000144�14364043643�0023075�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 4096 4224 4352 2 130 258 4098 4226 4354 4 132 260 4100 4228 4356 6 134 262 4102 4230 4358 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x63x1x32.txt������������������������������������������0000664�0000000�0000000�00000022474�14364043643�0023255�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 3968 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 3970 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 3972 6 134 262 390 518 646 774 902 1030 1158 1286 1414 1542 1670 1798 1926 2054 2182 2310 2438 2566 2694 2822 2950 3078 3206 3334 3462 3590 3718 3846 3974 8 136 264 392 520 648 776 904 1032 1160 1288 1416 1544 1672 1800 1928 2056 2184 2312 2440 2568 2696 2824 2952 3080 3208 3336 3464 3592 3720 3848 3976 10 138 266 394 522 650 778 906 1034 1162 1290 1418 1546 1674 1802 1930 2058 2186 2314 2442 2570 2698 2826 2954 3082 3210 3338 3466 3594 3722 3850 3978 12 140 268 396 524 652 780 908 1036 1164 1292 1420 1548 1676 1804 1932 2060 2188 2316 2444 2572 2700 2828 2956 3084 3212 3340 3468 3596 3724 3852 3980 14 142 270 398 526 654 782 910 1038 1166 1294 1422 1550 1678 1806 1934 2062 2190 2318 2446 2574 2702 2830 2958 3086 3214 3342 3470 3598 3726 3854 3982 16 144 272 400 528 656 784 912 1040 1168 1296 1424 1552 1680 1808 1936 2064 2192 2320 2448 2576 2704 2832 2960 3088 3216 3344 3472 3600 3728 3856 3984 18 146 274 402 530 658 786 914 1042 1170 1298 1426 1554 1682 1810 1938 2066 2194 2322 2450 2578 2706 2834 2962 3090 3218 3346 3474 3602 3730 3858 3986 20 148 276 404 532 660 788 916 1044 1172 1300 1428 1556 1684 1812 1940 2068 2196 2324 2452 2580 2708 2836 2964 3092 3220 3348 3476 3604 3732 3860 3988 22 150 278 406 534 662 790 918 1046 1174 1302 1430 1558 1686 1814 1942 2070 2198 2326 2454 2582 2710 2838 2966 3094 3222 3350 3478 3606 3734 3862 3990 24 152 280 408 536 664 792 920 1048 1176 1304 1432 1560 1688 1816 1944 2072 2200 2328 2456 2584 2712 2840 2968 3096 3224 3352 3480 3608 3736 3864 3992 26 154 282 410 538 666 794 922 1050 1178 1306 1434 1562 1690 1818 1946 2074 2202 2330 2458 2586 2714 2842 2970 3098 3226 3354 3482 3610 3738 3866 3994 28 156 284 412 540 668 796 924 1052 1180 1308 1436 1564 1692 1820 1948 2076 2204 2332 2460 2588 2716 2844 2972 3100 3228 3356 3484 3612 3740 3868 3996 30 158 286 414 542 670 798 926 1054 1182 1310 1438 1566 1694 1822 1950 2078 2206 2334 2462 2590 2718 2846 2974 3102 3230 3358 3486 3614 3742 3870 3998 32 160 288 416 544 672 800 928 1056 1184 1312 1440 1568 1696 1824 1952 2080 2208 2336 2464 2592 2720 2848 2976 3104 3232 3360 3488 3616 3744 3872 4000 34 162 290 418 546 674 802 930 1058 1186 1314 1442 1570 1698 1826 1954 2082 2210 2338 2466 2594 2722 2850 2978 3106 3234 3362 3490 3618 3746 3874 4002 36 164 292 420 548 676 804 932 1060 1188 1316 1444 1572 1700 1828 1956 2084 2212 2340 2468 2596 2724 2852 2980 3108 3236 3364 3492 3620 3748 3876 4004 38 166 294 422 550 678 806 934 1062 1190 1318 1446 1574 1702 1830 1958 2086 2214 2342 2470 2598 2726 2854 2982 3110 3238 3366 3494 3622 3750 3878 4006 40 168 296 424 552 680 808 936 1064 1192 1320 1448 1576 1704 1832 1960 2088 2216 2344 2472 2600 2728 2856 2984 3112 3240 3368 3496 3624 3752 3880 4008 42 170 298 426 554 682 810 938 1066 1194 1322 1450 1578 1706 1834 1962 2090 2218 2346 2474 2602 2730 2858 2986 3114 3242 3370 3498 3626 3754 3882 4010 44 172 300 428 556 684 812 940 1068 1196 1324 1452 1580 1708 1836 1964 2092 2220 2348 2476 2604 2732 2860 2988 3116 3244 3372 3500 3628 3756 3884 4012 46 174 302 430 558 686 814 942 1070 1198 1326 1454 1582 1710 1838 1966 2094 2222 2350 2478 2606 2734 2862 2990 3118 3246 3374 3502 3630 3758 3886 4014 48 176 304 432 560 688 816 944 1072 1200 1328 1456 1584 1712 1840 1968 2096 2224 2352 2480 2608 2736 2864 2992 3120 3248 3376 3504 3632 3760 3888 4016 50 178 306 434 562 690 818 946 1074 1202 1330 1458 1586 1714 1842 1970 2098 2226 2354 2482 2610 2738 2866 2994 3122 3250 3378 3506 3634 3762 3890 4018 52 180 308 436 564 692 820 948 1076 1204 1332 1460 1588 1716 1844 1972 2100 2228 2356 2484 2612 2740 2868 2996 3124 3252 3380 3508 3636 3764 3892 4020 54 182 310 438 566 694 822 950 1078 1206 1334 1462 1590 1718 1846 1974 2102 2230 2358 2486 2614 2742 2870 2998 3126 3254 3382 3510 3638 3766 3894 4022 56 184 312 440 568 696 824 952 1080 1208 1336 1464 1592 1720 1848 1976 2104 2232 2360 2488 2616 2744 2872 3000 3128 3256 3384 3512 3640 3768 3896 4024 58 186 314 442 570 698 826 954 1082 1210 1338 1466 1594 1722 1850 1978 2106 2234 2362 2490 2618 2746 2874 3002 3130 3258 3386 3514 3642 3770 3898 4026 60 188 316 444 572 700 828 956 1084 1212 1340 1468 1596 1724 1852 1980 2108 2236 2364 2492 2620 2748 2876 3004 3132 3260 3388 3516 3644 3772 3900 4028 62 190 318 446 574 702 830 958 1086 1214 1342 1470 1598 1726 1854 1982 2110 2238 2366 2494 2622 2750 2878 3006 3134 3262 3390 3518 3646 3774 3902 4030 64 192 320 448 576 704 832 960 1088 1216 1344 1472 1600 1728 1856 1984 2112 2240 2368 2496 2624 2752 2880 3008 3136 3264 3392 3520 3648 3776 3904 4032 66 194 322 450 578 706 834 962 1090 1218 1346 1474 1602 1730 1858 1986 2114 2242 2370 2498 2626 2754 2882 3010 3138 3266 3394 3522 3650 3778 3906 4034 68 196 324 452 580 708 836 964 1092 1220 1348 1476 1604 1732 1860 1988 2116 2244 2372 2500 2628 2756 2884 3012 3140 3268 3396 3524 3652 3780 3908 4036 70 198 326 454 582 710 838 966 1094 1222 1350 1478 1606 1734 1862 1990 2118 2246 2374 2502 2630 2758 2886 3014 3142 3270 3398 3526 3654 3782 3910 4038 72 200 328 456 584 712 840 968 1096 1224 1352 1480 1608 1736 1864 1992 2120 2248 2376 2504 2632 2760 2888 3016 3144 3272 3400 3528 3656 3784 3912 4040 74 202 330 458 586 714 842 970 1098 1226 1354 1482 1610 1738 1866 1994 2122 2250 2378 2506 2634 2762 2890 3018 3146 3274 3402 3530 3658 3786 3914 4042 76 204 332 460 588 716 844 972 1100 1228 1356 1484 1612 1740 1868 1996 2124 2252 2380 2508 2636 2764 2892 3020 3148 3276 3404 3532 3660 3788 3916 4044 78 206 334 462 590 718 846 974 1102 1230 1358 1486 1614 1742 1870 1998 2126 2254 2382 2510 2638 2766 2894 3022 3150 3278 3406 3534 3662 3790 3918 4046 80 208 336 464 592 720 848 976 1104 1232 1360 1488 1616 1744 1872 2000 2128 2256 2384 2512 2640 2768 2896 3024 3152 3280 3408 3536 3664 3792 3920 4048 82 210 338 466 594 722 850 978 1106 1234 1362 1490 1618 1746 1874 2002 2130 2258 2386 2514 2642 2770 2898 3026 3154 3282 3410 3538 3666 3794 3922 4050 84 212 340 468 596 724 852 980 1108 1236 1364 1492 1620 1748 1876 2004 2132 2260 2388 2516 2644 2772 2900 3028 3156 3284 3412 3540 3668 3796 3924 4052 86 214 342 470 598 726 854 982 1110 1238 1366 1494 1622 1750 1878 2006 2134 2262 2390 2518 2646 2774 2902 3030 3158 3286 3414 3542 3670 3798 3926 4054 88 216 344 472 600 728 856 984 1112 1240 1368 1496 1624 1752 1880 2008 2136 2264 2392 2520 2648 2776 2904 3032 3160 3288 3416 3544 3672 3800 3928 4056 90 218 346 474 602 730 858 986 1114 1242 1370 1498 1626 1754 1882 2010 2138 2266 2394 2522 2650 2778 2906 3034 3162 3290 3418 3546 3674 3802 3930 4058 92 220 348 476 604 732 860 988 1116 1244 1372 1500 1628 1756 1884 2012 2140 2268 2396 2524 2652 2780 2908 3036 3164 3292 3420 3548 3676 3804 3932 4060 94 222 350 478 606 734 862 990 1118 1246 1374 1502 1630 1758 1886 2014 2142 2270 2398 2526 2654 2782 2910 3038 3166 3294 3422 3550 3678 3806 3934 4062 96 224 352 480 608 736 864 992 1120 1248 1376 1504 1632 1760 1888 2016 2144 2272 2400 2528 2656 2784 2912 3040 3168 3296 3424 3552 3680 3808 3936 4064 98 226 354 482 610 738 866 994 1122 1250 1378 1506 1634 1762 1890 2018 2146 2274 2402 2530 2658 2786 2914 3042 3170 3298 3426 3554 3682 3810 3938 4066 100 228 356 484 612 740 868 996 1124 1252 1380 1508 1636 1764 1892 2020 2148 2276 2404 2532 2660 2788 2916 3044 3172 3300 3428 3556 3684 3812 3940 4068 102 230 358 486 614 742 870 998 1126 1254 1382 1510 1638 1766 1894 2022 2150 2278 2406 2534 2662 2790 2918 3046 3174 3302 3430 3558 3686 3814 3942 4070 104 232 360 488 616 744 872 1000 1128 1256 1384 1512 1640 1768 1896 2024 2152 2280 2408 2536 2664 2792 2920 3048 3176 3304 3432 3560 3688 3816 3944 4072 106 234 362 490 618 746 874 1002 1130 1258 1386 1514 1642 1770 1898 2026 2154 2282 2410 2538 2666 2794 2922 3050 3178 3306 3434 3562 3690 3818 3946 4074 108 236 364 492 620 748 876 1004 1132 1260 1388 1516 1644 1772 1900 2028 2156 2284 2412 2540 2668 2796 2924 3052 3180 3308 3436 3564 3692 3820 3948 4076 110 238 366 494 622 750 878 1006 1134 1262 1390 1518 1646 1774 1902 2030 2158 2286 2414 2542 2670 2798 2926 3054 3182 3310 3438 3566 3694 3822 3950 4078 112 240 368 496 624 752 880 1008 1136 1264 1392 1520 1648 1776 1904 2032 2160 2288 2416 2544 2672 2800 2928 3056 3184 3312 3440 3568 3696 3824 3952 4080 114 242 370 498 626 754 882 1010 1138 1266 1394 1522 1650 1778 1906 2034 2162 2290 2418 2546 2674 2802 2930 3058 3186 3314 3442 3570 3698 3826 3954 4082 116 244 372 500 628 756 884 1012 1140 1268 1396 1524 1652 1780 1908 2036 2164 2292 2420 2548 2676 2804 2932 3060 3188 3316 3444 3572 3700 3828 3956 4084 118 246 374 502 630 758 886 1014 1142 1270 1398 1526 1654 1782 1910 2038 2166 2294 2422 2550 2678 2806 2934 3062 3190 3318 3446 3574 3702 3830 3958 4086 120 248 376 504 632 760 888 1016 1144 1272 1400 1528 1656 1784 1912 2040 2168 2296 2424 2552 2680 2808 2936 3064 3192 3320 3448 3576 3704 3832 3960 4088 122 250 378 506 634 762 890 1018 1146 1274 1402 1530 1658 1786 1914 2042 2170 2298 2426 2554 2682 2810 2938 3066 3194 3322 3450 3578 3706 3834 3962 4090 124 252 380 508 636 764 892 1020 1148 1276 1404 1532 1660 1788 1916 2044 2172 2300 2428 2556 2684 2812 2940 3068 3196 3324 3452 3580 3708 3836 3964 4092 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x64x1x31.txt������������������������������������������0000664�0000000�0000000�00000022225�14364043643�0023247�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 6 134 262 390 518 646 774 902 1030 1158 1286 1414 1542 1670 1798 1926 2054 2182 2310 2438 2566 2694 2822 2950 3078 3206 3334 3462 3590 3718 3846 8 136 264 392 520 648 776 904 1032 1160 1288 1416 1544 1672 1800 1928 2056 2184 2312 2440 2568 2696 2824 2952 3080 3208 3336 3464 3592 3720 3848 10 138 266 394 522 650 778 906 1034 1162 1290 1418 1546 1674 1802 1930 2058 2186 2314 2442 2570 2698 2826 2954 3082 3210 3338 3466 3594 3722 3850 12 140 268 396 524 652 780 908 1036 1164 1292 1420 1548 1676 1804 1932 2060 2188 2316 2444 2572 2700 2828 2956 3084 3212 3340 3468 3596 3724 3852 14 142 270 398 526 654 782 910 1038 1166 1294 1422 1550 1678 1806 1934 2062 2190 2318 2446 2574 2702 2830 2958 3086 3214 3342 3470 3598 3726 3854 16 144 272 400 528 656 784 912 1040 1168 1296 1424 1552 1680 1808 1936 2064 2192 2320 2448 2576 2704 2832 2960 3088 3216 3344 3472 3600 3728 3856 18 146 274 402 530 658 786 914 1042 1170 1298 1426 1554 1682 1810 1938 2066 2194 2322 2450 2578 2706 2834 2962 3090 3218 3346 3474 3602 3730 3858 20 148 276 404 532 660 788 916 1044 1172 1300 1428 1556 1684 1812 1940 2068 2196 2324 2452 2580 2708 2836 2964 3092 3220 3348 3476 3604 3732 3860 22 150 278 406 534 662 790 918 1046 1174 1302 1430 1558 1686 1814 1942 2070 2198 2326 2454 2582 2710 2838 2966 3094 3222 3350 3478 3606 3734 3862 24 152 280 408 536 664 792 920 1048 1176 1304 1432 1560 1688 1816 1944 2072 2200 2328 2456 2584 2712 2840 2968 3096 3224 3352 3480 3608 3736 3864 26 154 282 410 538 666 794 922 1050 1178 1306 1434 1562 1690 1818 1946 2074 2202 2330 2458 2586 2714 2842 2970 3098 3226 3354 3482 3610 3738 3866 28 156 284 412 540 668 796 924 1052 1180 1308 1436 1564 1692 1820 1948 2076 2204 2332 2460 2588 2716 2844 2972 3100 3228 3356 3484 3612 3740 3868 30 158 286 414 542 670 798 926 1054 1182 1310 1438 1566 1694 1822 1950 2078 2206 2334 2462 2590 2718 2846 2974 3102 3230 3358 3486 3614 3742 3870 32 160 288 416 544 672 800 928 1056 1184 1312 1440 1568 1696 1824 1952 2080 2208 2336 2464 2592 2720 2848 2976 3104 3232 3360 3488 3616 3744 3872 34 162 290 418 546 674 802 930 1058 1186 1314 1442 1570 1698 1826 1954 2082 2210 2338 2466 2594 2722 2850 2978 3106 3234 3362 3490 3618 3746 3874 36 164 292 420 548 676 804 932 1060 1188 1316 1444 1572 1700 1828 1956 2084 2212 2340 2468 2596 2724 2852 2980 3108 3236 3364 3492 3620 3748 3876 38 166 294 422 550 678 806 934 1062 1190 1318 1446 1574 1702 1830 1958 2086 2214 2342 2470 2598 2726 2854 2982 3110 3238 3366 3494 3622 3750 3878 40 168 296 424 552 680 808 936 1064 1192 1320 1448 1576 1704 1832 1960 2088 2216 2344 2472 2600 2728 2856 2984 3112 3240 3368 3496 3624 3752 3880 42 170 298 426 554 682 810 938 1066 1194 1322 1450 1578 1706 1834 1962 2090 2218 2346 2474 2602 2730 2858 2986 3114 3242 3370 3498 3626 3754 3882 44 172 300 428 556 684 812 940 1068 1196 1324 1452 1580 1708 1836 1964 2092 2220 2348 2476 2604 2732 2860 2988 3116 3244 3372 3500 3628 3756 3884 46 174 302 430 558 686 814 942 1070 1198 1326 1454 1582 1710 1838 1966 2094 2222 2350 2478 2606 2734 2862 2990 3118 3246 3374 3502 3630 3758 3886 48 176 304 432 560 688 816 944 1072 1200 1328 1456 1584 1712 1840 1968 2096 2224 2352 2480 2608 2736 2864 2992 3120 3248 3376 3504 3632 3760 3888 50 178 306 434 562 690 818 946 1074 1202 1330 1458 1586 1714 1842 1970 2098 2226 2354 2482 2610 2738 2866 2994 3122 3250 3378 3506 3634 3762 3890 52 180 308 436 564 692 820 948 1076 1204 1332 1460 1588 1716 1844 1972 2100 2228 2356 2484 2612 2740 2868 2996 3124 3252 3380 3508 3636 3764 3892 54 182 310 438 566 694 822 950 1078 1206 1334 1462 1590 1718 1846 1974 2102 2230 2358 2486 2614 2742 2870 2998 3126 3254 3382 3510 3638 3766 3894 56 184 312 440 568 696 824 952 1080 1208 1336 1464 1592 1720 1848 1976 2104 2232 2360 2488 2616 2744 2872 3000 3128 3256 3384 3512 3640 3768 3896 58 186 314 442 570 698 826 954 1082 1210 1338 1466 1594 1722 1850 1978 2106 2234 2362 2490 2618 2746 2874 3002 3130 3258 3386 3514 3642 3770 3898 60 188 316 444 572 700 828 956 1084 1212 1340 1468 1596 1724 1852 1980 2108 2236 2364 2492 2620 2748 2876 3004 3132 3260 3388 3516 3644 3772 3900 62 190 318 446 574 702 830 958 1086 1214 1342 1470 1598 1726 1854 1982 2110 2238 2366 2494 2622 2750 2878 3006 3134 3262 3390 3518 3646 3774 3902 64 192 320 448 576 704 832 960 1088 1216 1344 1472 1600 1728 1856 1984 2112 2240 2368 2496 2624 2752 2880 3008 3136 3264 3392 3520 3648 3776 3904 66 194 322 450 578 706 834 962 1090 1218 1346 1474 1602 1730 1858 1986 2114 2242 2370 2498 2626 2754 2882 3010 3138 3266 3394 3522 3650 3778 3906 68 196 324 452 580 708 836 964 1092 1220 1348 1476 1604 1732 1860 1988 2116 2244 2372 2500 2628 2756 2884 3012 3140 3268 3396 3524 3652 3780 3908 70 198 326 454 582 710 838 966 1094 1222 1350 1478 1606 1734 1862 1990 2118 2246 2374 2502 2630 2758 2886 3014 3142 3270 3398 3526 3654 3782 3910 72 200 328 456 584 712 840 968 1096 1224 1352 1480 1608 1736 1864 1992 2120 2248 2376 2504 2632 2760 2888 3016 3144 3272 3400 3528 3656 3784 3912 74 202 330 458 586 714 842 970 1098 1226 1354 1482 1610 1738 1866 1994 2122 2250 2378 2506 2634 2762 2890 3018 3146 3274 3402 3530 3658 3786 3914 76 204 332 460 588 716 844 972 1100 1228 1356 1484 1612 1740 1868 1996 2124 2252 2380 2508 2636 2764 2892 3020 3148 3276 3404 3532 3660 3788 3916 78 206 334 462 590 718 846 974 1102 1230 1358 1486 1614 1742 1870 1998 2126 2254 2382 2510 2638 2766 2894 3022 3150 3278 3406 3534 3662 3790 3918 80 208 336 464 592 720 848 976 1104 1232 1360 1488 1616 1744 1872 2000 2128 2256 2384 2512 2640 2768 2896 3024 3152 3280 3408 3536 3664 3792 3920 82 210 338 466 594 722 850 978 1106 1234 1362 1490 1618 1746 1874 2002 2130 2258 2386 2514 2642 2770 2898 3026 3154 3282 3410 3538 3666 3794 3922 84 212 340 468 596 724 852 980 1108 1236 1364 1492 1620 1748 1876 2004 2132 2260 2388 2516 2644 2772 2900 3028 3156 3284 3412 3540 3668 3796 3924 86 214 342 470 598 726 854 982 1110 1238 1366 1494 1622 1750 1878 2006 2134 2262 2390 2518 2646 2774 2902 3030 3158 3286 3414 3542 3670 3798 3926 88 216 344 472 600 728 856 984 1112 1240 1368 1496 1624 1752 1880 2008 2136 2264 2392 2520 2648 2776 2904 3032 3160 3288 3416 3544 3672 3800 3928 90 218 346 474 602 730 858 986 1114 1242 1370 1498 1626 1754 1882 2010 2138 2266 2394 2522 2650 2778 2906 3034 3162 3290 3418 3546 3674 3802 3930 92 220 348 476 604 732 860 988 1116 1244 1372 1500 1628 1756 1884 2012 2140 2268 2396 2524 2652 2780 2908 3036 3164 3292 3420 3548 3676 3804 3932 94 222 350 478 606 734 862 990 1118 1246 1374 1502 1630 1758 1886 2014 2142 2270 2398 2526 2654 2782 2910 3038 3166 3294 3422 3550 3678 3806 3934 96 224 352 480 608 736 864 992 1120 1248 1376 1504 1632 1760 1888 2016 2144 2272 2400 2528 2656 2784 2912 3040 3168 3296 3424 3552 3680 3808 3936 98 226 354 482 610 738 866 994 1122 1250 1378 1506 1634 1762 1890 2018 2146 2274 2402 2530 2658 2786 2914 3042 3170 3298 3426 3554 3682 3810 3938 100 228 356 484 612 740 868 996 1124 1252 1380 1508 1636 1764 1892 2020 2148 2276 2404 2532 2660 2788 2916 3044 3172 3300 3428 3556 3684 3812 3940 102 230 358 486 614 742 870 998 1126 1254 1382 1510 1638 1766 1894 2022 2150 2278 2406 2534 2662 2790 2918 3046 3174 3302 3430 3558 3686 3814 3942 104 232 360 488 616 744 872 1000 1128 1256 1384 1512 1640 1768 1896 2024 2152 2280 2408 2536 2664 2792 2920 3048 3176 3304 3432 3560 3688 3816 3944 106 234 362 490 618 746 874 1002 1130 1258 1386 1514 1642 1770 1898 2026 2154 2282 2410 2538 2666 2794 2922 3050 3178 3306 3434 3562 3690 3818 3946 108 236 364 492 620 748 876 1004 1132 1260 1388 1516 1644 1772 1900 2028 2156 2284 2412 2540 2668 2796 2924 3052 3180 3308 3436 3564 3692 3820 3948 110 238 366 494 622 750 878 1006 1134 1262 1390 1518 1646 1774 1902 2030 2158 2286 2414 2542 2670 2798 2926 3054 3182 3310 3438 3566 3694 3822 3950 112 240 368 496 624 752 880 1008 1136 1264 1392 1520 1648 1776 1904 2032 2160 2288 2416 2544 2672 2800 2928 3056 3184 3312 3440 3568 3696 3824 3952 114 242 370 498 626 754 882 1010 1138 1266 1394 1522 1650 1778 1906 2034 2162 2290 2418 2546 2674 2802 2930 3058 3186 3314 3442 3570 3698 3826 3954 116 244 372 500 628 756 884 1012 1140 1268 1396 1524 1652 1780 1908 2036 2164 2292 2420 2548 2676 2804 2932 3060 3188 3316 3444 3572 3700 3828 3956 118 246 374 502 630 758 886 1014 1142 1270 1398 1526 1654 1782 1910 2038 2166 2294 2422 2550 2678 2806 2934 3062 3190 3318 3446 3574 3702 3830 3958 120 248 376 504 632 760 888 1016 1144 1272 1400 1528 1656 1784 1912 2040 2168 2296 2424 2552 2680 2808 2936 3064 3192 3320 3448 3576 3704 3832 3960 122 250 378 506 634 762 890 1018 1146 1274 1402 1530 1658 1786 1914 2042 2170 2298 2426 2554 2682 2810 2938 3066 3194 3322 3450 3578 3706 3834 3962 124 252 380 508 636 764 892 1020 1148 1276 1404 1532 1660 1788 1916 2044 2172 2300 2428 2556 2684 2812 2940 3068 3196 3324 3452 3580 3708 3836 3964 126 254 382 510 638 766 894 1022 1150 1278 1406 1534 1662 1790 1918 2046 2174 2302 2430 2558 2686 2814 2942 3070 3198 3326 3454 3582 3710 3838 3966 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x64x1x32.txt������������������������������������������0000664�0000000�0000000�00000022725�14364043643�0023255�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 3968 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 3970 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 3972 6 134 262 390 518 646 774 902 1030 1158 1286 1414 1542 1670 1798 1926 2054 2182 2310 2438 2566 2694 2822 2950 3078 3206 3334 3462 3590 3718 3846 3974 8 136 264 392 520 648 776 904 1032 1160 1288 1416 1544 1672 1800 1928 2056 2184 2312 2440 2568 2696 2824 2952 3080 3208 3336 3464 3592 3720 3848 3976 10 138 266 394 522 650 778 906 1034 1162 1290 1418 1546 1674 1802 1930 2058 2186 2314 2442 2570 2698 2826 2954 3082 3210 3338 3466 3594 3722 3850 3978 12 140 268 396 524 652 780 908 1036 1164 1292 1420 1548 1676 1804 1932 2060 2188 2316 2444 2572 2700 2828 2956 3084 3212 3340 3468 3596 3724 3852 3980 14 142 270 398 526 654 782 910 1038 1166 1294 1422 1550 1678 1806 1934 2062 2190 2318 2446 2574 2702 2830 2958 3086 3214 3342 3470 3598 3726 3854 3982 16 144 272 400 528 656 784 912 1040 1168 1296 1424 1552 1680 1808 1936 2064 2192 2320 2448 2576 2704 2832 2960 3088 3216 3344 3472 3600 3728 3856 3984 18 146 274 402 530 658 786 914 1042 1170 1298 1426 1554 1682 1810 1938 2066 2194 2322 2450 2578 2706 2834 2962 3090 3218 3346 3474 3602 3730 3858 3986 20 148 276 404 532 660 788 916 1044 1172 1300 1428 1556 1684 1812 1940 2068 2196 2324 2452 2580 2708 2836 2964 3092 3220 3348 3476 3604 3732 3860 3988 22 150 278 406 534 662 790 918 1046 1174 1302 1430 1558 1686 1814 1942 2070 2198 2326 2454 2582 2710 2838 2966 3094 3222 3350 3478 3606 3734 3862 3990 24 152 280 408 536 664 792 920 1048 1176 1304 1432 1560 1688 1816 1944 2072 2200 2328 2456 2584 2712 2840 2968 3096 3224 3352 3480 3608 3736 3864 3992 26 154 282 410 538 666 794 922 1050 1178 1306 1434 1562 1690 1818 1946 2074 2202 2330 2458 2586 2714 2842 2970 3098 3226 3354 3482 3610 3738 3866 3994 28 156 284 412 540 668 796 924 1052 1180 1308 1436 1564 1692 1820 1948 2076 2204 2332 2460 2588 2716 2844 2972 3100 3228 3356 3484 3612 3740 3868 3996 30 158 286 414 542 670 798 926 1054 1182 1310 1438 1566 1694 1822 1950 2078 2206 2334 2462 2590 2718 2846 2974 3102 3230 3358 3486 3614 3742 3870 3998 32 160 288 416 544 672 800 928 1056 1184 1312 1440 1568 1696 1824 1952 2080 2208 2336 2464 2592 2720 2848 2976 3104 3232 3360 3488 3616 3744 3872 4000 34 162 290 418 546 674 802 930 1058 1186 1314 1442 1570 1698 1826 1954 2082 2210 2338 2466 2594 2722 2850 2978 3106 3234 3362 3490 3618 3746 3874 4002 36 164 292 420 548 676 804 932 1060 1188 1316 1444 1572 1700 1828 1956 2084 2212 2340 2468 2596 2724 2852 2980 3108 3236 3364 3492 3620 3748 3876 4004 38 166 294 422 550 678 806 934 1062 1190 1318 1446 1574 1702 1830 1958 2086 2214 2342 2470 2598 2726 2854 2982 3110 3238 3366 3494 3622 3750 3878 4006 40 168 296 424 552 680 808 936 1064 1192 1320 1448 1576 1704 1832 1960 2088 2216 2344 2472 2600 2728 2856 2984 3112 3240 3368 3496 3624 3752 3880 4008 42 170 298 426 554 682 810 938 1066 1194 1322 1450 1578 1706 1834 1962 2090 2218 2346 2474 2602 2730 2858 2986 3114 3242 3370 3498 3626 3754 3882 4010 44 172 300 428 556 684 812 940 1068 1196 1324 1452 1580 1708 1836 1964 2092 2220 2348 2476 2604 2732 2860 2988 3116 3244 3372 3500 3628 3756 3884 4012 46 174 302 430 558 686 814 942 1070 1198 1326 1454 1582 1710 1838 1966 2094 2222 2350 2478 2606 2734 2862 2990 3118 3246 3374 3502 3630 3758 3886 4014 48 176 304 432 560 688 816 944 1072 1200 1328 1456 1584 1712 1840 1968 2096 2224 2352 2480 2608 2736 2864 2992 3120 3248 3376 3504 3632 3760 3888 4016 50 178 306 434 562 690 818 946 1074 1202 1330 1458 1586 1714 1842 1970 2098 2226 2354 2482 2610 2738 2866 2994 3122 3250 3378 3506 3634 3762 3890 4018 52 180 308 436 564 692 820 948 1076 1204 1332 1460 1588 1716 1844 1972 2100 2228 2356 2484 2612 2740 2868 2996 3124 3252 3380 3508 3636 3764 3892 4020 54 182 310 438 566 694 822 950 1078 1206 1334 1462 1590 1718 1846 1974 2102 2230 2358 2486 2614 2742 2870 2998 3126 3254 3382 3510 3638 3766 3894 4022 56 184 312 440 568 696 824 952 1080 1208 1336 1464 1592 1720 1848 1976 2104 2232 2360 2488 2616 2744 2872 3000 3128 3256 3384 3512 3640 3768 3896 4024 58 186 314 442 570 698 826 954 1082 1210 1338 1466 1594 1722 1850 1978 2106 2234 2362 2490 2618 2746 2874 3002 3130 3258 3386 3514 3642 3770 3898 4026 60 188 316 444 572 700 828 956 1084 1212 1340 1468 1596 1724 1852 1980 2108 2236 2364 2492 2620 2748 2876 3004 3132 3260 3388 3516 3644 3772 3900 4028 62 190 318 446 574 702 830 958 1086 1214 1342 1470 1598 1726 1854 1982 2110 2238 2366 2494 2622 2750 2878 3006 3134 3262 3390 3518 3646 3774 3902 4030 64 192 320 448 576 704 832 960 1088 1216 1344 1472 1600 1728 1856 1984 2112 2240 2368 2496 2624 2752 2880 3008 3136 3264 3392 3520 3648 3776 3904 4032 66 194 322 450 578 706 834 962 1090 1218 1346 1474 1602 1730 1858 1986 2114 2242 2370 2498 2626 2754 2882 3010 3138 3266 3394 3522 3650 3778 3906 4034 68 196 324 452 580 708 836 964 1092 1220 1348 1476 1604 1732 1860 1988 2116 2244 2372 2500 2628 2756 2884 3012 3140 3268 3396 3524 3652 3780 3908 4036 70 198 326 454 582 710 838 966 1094 1222 1350 1478 1606 1734 1862 1990 2118 2246 2374 2502 2630 2758 2886 3014 3142 3270 3398 3526 3654 3782 3910 4038 72 200 328 456 584 712 840 968 1096 1224 1352 1480 1608 1736 1864 1992 2120 2248 2376 2504 2632 2760 2888 3016 3144 3272 3400 3528 3656 3784 3912 4040 74 202 330 458 586 714 842 970 1098 1226 1354 1482 1610 1738 1866 1994 2122 2250 2378 2506 2634 2762 2890 3018 3146 3274 3402 3530 3658 3786 3914 4042 76 204 332 460 588 716 844 972 1100 1228 1356 1484 1612 1740 1868 1996 2124 2252 2380 2508 2636 2764 2892 3020 3148 3276 3404 3532 3660 3788 3916 4044 78 206 334 462 590 718 846 974 1102 1230 1358 1486 1614 1742 1870 1998 2126 2254 2382 2510 2638 2766 2894 3022 3150 3278 3406 3534 3662 3790 3918 4046 80 208 336 464 592 720 848 976 1104 1232 1360 1488 1616 1744 1872 2000 2128 2256 2384 2512 2640 2768 2896 3024 3152 3280 3408 3536 3664 3792 3920 4048 82 210 338 466 594 722 850 978 1106 1234 1362 1490 1618 1746 1874 2002 2130 2258 2386 2514 2642 2770 2898 3026 3154 3282 3410 3538 3666 3794 3922 4050 84 212 340 468 596 724 852 980 1108 1236 1364 1492 1620 1748 1876 2004 2132 2260 2388 2516 2644 2772 2900 3028 3156 3284 3412 3540 3668 3796 3924 4052 86 214 342 470 598 726 854 982 1110 1238 1366 1494 1622 1750 1878 2006 2134 2262 2390 2518 2646 2774 2902 3030 3158 3286 3414 3542 3670 3798 3926 4054 88 216 344 472 600 728 856 984 1112 1240 1368 1496 1624 1752 1880 2008 2136 2264 2392 2520 2648 2776 2904 3032 3160 3288 3416 3544 3672 3800 3928 4056 90 218 346 474 602 730 858 986 1114 1242 1370 1498 1626 1754 1882 2010 2138 2266 2394 2522 2650 2778 2906 3034 3162 3290 3418 3546 3674 3802 3930 4058 92 220 348 476 604 732 860 988 1116 1244 1372 1500 1628 1756 1884 2012 2140 2268 2396 2524 2652 2780 2908 3036 3164 3292 3420 3548 3676 3804 3932 4060 94 222 350 478 606 734 862 990 1118 1246 1374 1502 1630 1758 1886 2014 2142 2270 2398 2526 2654 2782 2910 3038 3166 3294 3422 3550 3678 3806 3934 4062 96 224 352 480 608 736 864 992 1120 1248 1376 1504 1632 1760 1888 2016 2144 2272 2400 2528 2656 2784 2912 3040 3168 3296 3424 3552 3680 3808 3936 4064 98 226 354 482 610 738 866 994 1122 1250 1378 1506 1634 1762 1890 2018 2146 2274 2402 2530 2658 2786 2914 3042 3170 3298 3426 3554 3682 3810 3938 4066 100 228 356 484 612 740 868 996 1124 1252 1380 1508 1636 1764 1892 2020 2148 2276 2404 2532 2660 2788 2916 3044 3172 3300 3428 3556 3684 3812 3940 4068 102 230 358 486 614 742 870 998 1126 1254 1382 1510 1638 1766 1894 2022 2150 2278 2406 2534 2662 2790 2918 3046 3174 3302 3430 3558 3686 3814 3942 4070 104 232 360 488 616 744 872 1000 1128 1256 1384 1512 1640 1768 1896 2024 2152 2280 2408 2536 2664 2792 2920 3048 3176 3304 3432 3560 3688 3816 3944 4072 106 234 362 490 618 746 874 1002 1130 1258 1386 1514 1642 1770 1898 2026 2154 2282 2410 2538 2666 2794 2922 3050 3178 3306 3434 3562 3690 3818 3946 4074 108 236 364 492 620 748 876 1004 1132 1260 1388 1516 1644 1772 1900 2028 2156 2284 2412 2540 2668 2796 2924 3052 3180 3308 3436 3564 3692 3820 3948 4076 110 238 366 494 622 750 878 1006 1134 1262 1390 1518 1646 1774 1902 2030 2158 2286 2414 2542 2670 2798 2926 3054 3182 3310 3438 3566 3694 3822 3950 4078 112 240 368 496 624 752 880 1008 1136 1264 1392 1520 1648 1776 1904 2032 2160 2288 2416 2544 2672 2800 2928 3056 3184 3312 3440 3568 3696 3824 3952 4080 114 242 370 498 626 754 882 1010 1138 1266 1394 1522 1650 1778 1906 2034 2162 2290 2418 2546 2674 2802 2930 3058 3186 3314 3442 3570 3698 3826 3954 4082 116 244 372 500 628 756 884 1012 1140 1268 1396 1524 1652 1780 1908 2036 2164 2292 2420 2548 2676 2804 2932 3060 3188 3316 3444 3572 3700 3828 3956 4084 118 246 374 502 630 758 886 1014 1142 1270 1398 1526 1654 1782 1910 2038 2166 2294 2422 2550 2678 2806 2934 3062 3190 3318 3446 3574 3702 3830 3958 4086 120 248 376 504 632 760 888 1016 1144 1272 1400 1528 1656 1784 1912 2040 2168 2296 2424 2552 2680 2808 2936 3064 3192 3320 3448 3576 3704 3832 3960 4088 122 250 378 506 634 762 890 1018 1146 1274 1402 1530 1658 1786 1914 2042 2170 2298 2426 2554 2682 2810 2938 3066 3194 3322 3450 3578 3706 3834 3962 4090 124 252 380 508 636 764 892 1020 1148 1276 1404 1532 1660 1788 1916 2044 2172 2300 2428 2556 2684 2812 2940 3068 3196 3324 3452 3580 3708 3836 3964 4092 126 254 382 510 638 766 894 1022 1150 1278 1406 1534 1662 1790 1918 2046 2174 2302 2430 2558 2686 2814 2942 3070 3198 3326 3454 3582 3710 3838 3966 4094 �������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x64x1x33.txt������������������������������������������0000664�0000000�0000000�00000023425�14364043643�0023254�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 3968 4096 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 3970 4098 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 3972 4100 6 134 262 390 518 646 774 902 1030 1158 1286 1414 1542 1670 1798 1926 2054 2182 2310 2438 2566 2694 2822 2950 3078 3206 3334 3462 3590 3718 3846 3974 4102 8 136 264 392 520 648 776 904 1032 1160 1288 1416 1544 1672 1800 1928 2056 2184 2312 2440 2568 2696 2824 2952 3080 3208 3336 3464 3592 3720 3848 3976 4104 10 138 266 394 522 650 778 906 1034 1162 1290 1418 1546 1674 1802 1930 2058 2186 2314 2442 2570 2698 2826 2954 3082 3210 3338 3466 3594 3722 3850 3978 4106 12 140 268 396 524 652 780 908 1036 1164 1292 1420 1548 1676 1804 1932 2060 2188 2316 2444 2572 2700 2828 2956 3084 3212 3340 3468 3596 3724 3852 3980 4108 14 142 270 398 526 654 782 910 1038 1166 1294 1422 1550 1678 1806 1934 2062 2190 2318 2446 2574 2702 2830 2958 3086 3214 3342 3470 3598 3726 3854 3982 4110 16 144 272 400 528 656 784 912 1040 1168 1296 1424 1552 1680 1808 1936 2064 2192 2320 2448 2576 2704 2832 2960 3088 3216 3344 3472 3600 3728 3856 3984 4112 18 146 274 402 530 658 786 914 1042 1170 1298 1426 1554 1682 1810 1938 2066 2194 2322 2450 2578 2706 2834 2962 3090 3218 3346 3474 3602 3730 3858 3986 4114 20 148 276 404 532 660 788 916 1044 1172 1300 1428 1556 1684 1812 1940 2068 2196 2324 2452 2580 2708 2836 2964 3092 3220 3348 3476 3604 3732 3860 3988 4116 22 150 278 406 534 662 790 918 1046 1174 1302 1430 1558 1686 1814 1942 2070 2198 2326 2454 2582 2710 2838 2966 3094 3222 3350 3478 3606 3734 3862 3990 4118 24 152 280 408 536 664 792 920 1048 1176 1304 1432 1560 1688 1816 1944 2072 2200 2328 2456 2584 2712 2840 2968 3096 3224 3352 3480 3608 3736 3864 3992 4120 26 154 282 410 538 666 794 922 1050 1178 1306 1434 1562 1690 1818 1946 2074 2202 2330 2458 2586 2714 2842 2970 3098 3226 3354 3482 3610 3738 3866 3994 4122 28 156 284 412 540 668 796 924 1052 1180 1308 1436 1564 1692 1820 1948 2076 2204 2332 2460 2588 2716 2844 2972 3100 3228 3356 3484 3612 3740 3868 3996 4124 30 158 286 414 542 670 798 926 1054 1182 1310 1438 1566 1694 1822 1950 2078 2206 2334 2462 2590 2718 2846 2974 3102 3230 3358 3486 3614 3742 3870 3998 4126 32 160 288 416 544 672 800 928 1056 1184 1312 1440 1568 1696 1824 1952 2080 2208 2336 2464 2592 2720 2848 2976 3104 3232 3360 3488 3616 3744 3872 4000 4128 34 162 290 418 546 674 802 930 1058 1186 1314 1442 1570 1698 1826 1954 2082 2210 2338 2466 2594 2722 2850 2978 3106 3234 3362 3490 3618 3746 3874 4002 4130 36 164 292 420 548 676 804 932 1060 1188 1316 1444 1572 1700 1828 1956 2084 2212 2340 2468 2596 2724 2852 2980 3108 3236 3364 3492 3620 3748 3876 4004 4132 38 166 294 422 550 678 806 934 1062 1190 1318 1446 1574 1702 1830 1958 2086 2214 2342 2470 2598 2726 2854 2982 3110 3238 3366 3494 3622 3750 3878 4006 4134 40 168 296 424 552 680 808 936 1064 1192 1320 1448 1576 1704 1832 1960 2088 2216 2344 2472 2600 2728 2856 2984 3112 3240 3368 3496 3624 3752 3880 4008 4136 42 170 298 426 554 682 810 938 1066 1194 1322 1450 1578 1706 1834 1962 2090 2218 2346 2474 2602 2730 2858 2986 3114 3242 3370 3498 3626 3754 3882 4010 4138 44 172 300 428 556 684 812 940 1068 1196 1324 1452 1580 1708 1836 1964 2092 2220 2348 2476 2604 2732 2860 2988 3116 3244 3372 3500 3628 3756 3884 4012 4140 46 174 302 430 558 686 814 942 1070 1198 1326 1454 1582 1710 1838 1966 2094 2222 2350 2478 2606 2734 2862 2990 3118 3246 3374 3502 3630 3758 3886 4014 4142 48 176 304 432 560 688 816 944 1072 1200 1328 1456 1584 1712 1840 1968 2096 2224 2352 2480 2608 2736 2864 2992 3120 3248 3376 3504 3632 3760 3888 4016 4144 50 178 306 434 562 690 818 946 1074 1202 1330 1458 1586 1714 1842 1970 2098 2226 2354 2482 2610 2738 2866 2994 3122 3250 3378 3506 3634 3762 3890 4018 4146 52 180 308 436 564 692 820 948 1076 1204 1332 1460 1588 1716 1844 1972 2100 2228 2356 2484 2612 2740 2868 2996 3124 3252 3380 3508 3636 3764 3892 4020 4148 54 182 310 438 566 694 822 950 1078 1206 1334 1462 1590 1718 1846 1974 2102 2230 2358 2486 2614 2742 2870 2998 3126 3254 3382 3510 3638 3766 3894 4022 4150 56 184 312 440 568 696 824 952 1080 1208 1336 1464 1592 1720 1848 1976 2104 2232 2360 2488 2616 2744 2872 3000 3128 3256 3384 3512 3640 3768 3896 4024 4152 58 186 314 442 570 698 826 954 1082 1210 1338 1466 1594 1722 1850 1978 2106 2234 2362 2490 2618 2746 2874 3002 3130 3258 3386 3514 3642 3770 3898 4026 4154 60 188 316 444 572 700 828 956 1084 1212 1340 1468 1596 1724 1852 1980 2108 2236 2364 2492 2620 2748 2876 3004 3132 3260 3388 3516 3644 3772 3900 4028 4156 62 190 318 446 574 702 830 958 1086 1214 1342 1470 1598 1726 1854 1982 2110 2238 2366 2494 2622 2750 2878 3006 3134 3262 3390 3518 3646 3774 3902 4030 4158 64 192 320 448 576 704 832 960 1088 1216 1344 1472 1600 1728 1856 1984 2112 2240 2368 2496 2624 2752 2880 3008 3136 3264 3392 3520 3648 3776 3904 4032 4160 66 194 322 450 578 706 834 962 1090 1218 1346 1474 1602 1730 1858 1986 2114 2242 2370 2498 2626 2754 2882 3010 3138 3266 3394 3522 3650 3778 3906 4034 4162 68 196 324 452 580 708 836 964 1092 1220 1348 1476 1604 1732 1860 1988 2116 2244 2372 2500 2628 2756 2884 3012 3140 3268 3396 3524 3652 3780 3908 4036 4164 70 198 326 454 582 710 838 966 1094 1222 1350 1478 1606 1734 1862 1990 2118 2246 2374 2502 2630 2758 2886 3014 3142 3270 3398 3526 3654 3782 3910 4038 4166 72 200 328 456 584 712 840 968 1096 1224 1352 1480 1608 1736 1864 1992 2120 2248 2376 2504 2632 2760 2888 3016 3144 3272 3400 3528 3656 3784 3912 4040 4168 74 202 330 458 586 714 842 970 1098 1226 1354 1482 1610 1738 1866 1994 2122 2250 2378 2506 2634 2762 2890 3018 3146 3274 3402 3530 3658 3786 3914 4042 4170 76 204 332 460 588 716 844 972 1100 1228 1356 1484 1612 1740 1868 1996 2124 2252 2380 2508 2636 2764 2892 3020 3148 3276 3404 3532 3660 3788 3916 4044 4172 78 206 334 462 590 718 846 974 1102 1230 1358 1486 1614 1742 1870 1998 2126 2254 2382 2510 2638 2766 2894 3022 3150 3278 3406 3534 3662 3790 3918 4046 4174 80 208 336 464 592 720 848 976 1104 1232 1360 1488 1616 1744 1872 2000 2128 2256 2384 2512 2640 2768 2896 3024 3152 3280 3408 3536 3664 3792 3920 4048 4176 82 210 338 466 594 722 850 978 1106 1234 1362 1490 1618 1746 1874 2002 2130 2258 2386 2514 2642 2770 2898 3026 3154 3282 3410 3538 3666 3794 3922 4050 4178 84 212 340 468 596 724 852 980 1108 1236 1364 1492 1620 1748 1876 2004 2132 2260 2388 2516 2644 2772 2900 3028 3156 3284 3412 3540 3668 3796 3924 4052 4180 86 214 342 470 598 726 854 982 1110 1238 1366 1494 1622 1750 1878 2006 2134 2262 2390 2518 2646 2774 2902 3030 3158 3286 3414 3542 3670 3798 3926 4054 4182 88 216 344 472 600 728 856 984 1112 1240 1368 1496 1624 1752 1880 2008 2136 2264 2392 2520 2648 2776 2904 3032 3160 3288 3416 3544 3672 3800 3928 4056 4184 90 218 346 474 602 730 858 986 1114 1242 1370 1498 1626 1754 1882 2010 2138 2266 2394 2522 2650 2778 2906 3034 3162 3290 3418 3546 3674 3802 3930 4058 4186 92 220 348 476 604 732 860 988 1116 1244 1372 1500 1628 1756 1884 2012 2140 2268 2396 2524 2652 2780 2908 3036 3164 3292 3420 3548 3676 3804 3932 4060 4188 94 222 350 478 606 734 862 990 1118 1246 1374 1502 1630 1758 1886 2014 2142 2270 2398 2526 2654 2782 2910 3038 3166 3294 3422 3550 3678 3806 3934 4062 4190 96 224 352 480 608 736 864 992 1120 1248 1376 1504 1632 1760 1888 2016 2144 2272 2400 2528 2656 2784 2912 3040 3168 3296 3424 3552 3680 3808 3936 4064 4192 98 226 354 482 610 738 866 994 1122 1250 1378 1506 1634 1762 1890 2018 2146 2274 2402 2530 2658 2786 2914 3042 3170 3298 3426 3554 3682 3810 3938 4066 4194 100 228 356 484 612 740 868 996 1124 1252 1380 1508 1636 1764 1892 2020 2148 2276 2404 2532 2660 2788 2916 3044 3172 3300 3428 3556 3684 3812 3940 4068 4196 102 230 358 486 614 742 870 998 1126 1254 1382 1510 1638 1766 1894 2022 2150 2278 2406 2534 2662 2790 2918 3046 3174 3302 3430 3558 3686 3814 3942 4070 4198 104 232 360 488 616 744 872 1000 1128 1256 1384 1512 1640 1768 1896 2024 2152 2280 2408 2536 2664 2792 2920 3048 3176 3304 3432 3560 3688 3816 3944 4072 4200 106 234 362 490 618 746 874 1002 1130 1258 1386 1514 1642 1770 1898 2026 2154 2282 2410 2538 2666 2794 2922 3050 3178 3306 3434 3562 3690 3818 3946 4074 4202 108 236 364 492 620 748 876 1004 1132 1260 1388 1516 1644 1772 1900 2028 2156 2284 2412 2540 2668 2796 2924 3052 3180 3308 3436 3564 3692 3820 3948 4076 4204 110 238 366 494 622 750 878 1006 1134 1262 1390 1518 1646 1774 1902 2030 2158 2286 2414 2542 2670 2798 2926 3054 3182 3310 3438 3566 3694 3822 3950 4078 4206 112 240 368 496 624 752 880 1008 1136 1264 1392 1520 1648 1776 1904 2032 2160 2288 2416 2544 2672 2800 2928 3056 3184 3312 3440 3568 3696 3824 3952 4080 4208 114 242 370 498 626 754 882 1010 1138 1266 1394 1522 1650 1778 1906 2034 2162 2290 2418 2546 2674 2802 2930 3058 3186 3314 3442 3570 3698 3826 3954 4082 4210 116 244 372 500 628 756 884 1012 1140 1268 1396 1524 1652 1780 1908 2036 2164 2292 2420 2548 2676 2804 2932 3060 3188 3316 3444 3572 3700 3828 3956 4084 4212 118 246 374 502 630 758 886 1014 1142 1270 1398 1526 1654 1782 1910 2038 2166 2294 2422 2550 2678 2806 2934 3062 3190 3318 3446 3574 3702 3830 3958 4086 4214 120 248 376 504 632 760 888 1016 1144 1272 1400 1528 1656 1784 1912 2040 2168 2296 2424 2552 2680 2808 2936 3064 3192 3320 3448 3576 3704 3832 3960 4088 4216 122 250 378 506 634 762 890 1018 1146 1274 1402 1530 1658 1786 1914 2042 2170 2298 2426 2554 2682 2810 2938 3066 3194 3322 3450 3578 3706 3834 3962 4090 4218 124 252 380 508 636 764 892 1020 1148 1276 1404 1532 1660 1788 1916 2044 2172 2300 2428 2556 2684 2812 2940 3068 3196 3324 3452 3580 3708 3836 3964 4092 4220 126 254 382 510 638 766 894 1022 1150 1278 1406 1534 1662 1790 1918 2046 2174 2302 2430 2558 2686 2814 2942 3070 3198 3326 3454 3582 3710 3838 3966 4094 4222 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_1x65x1x32.txt������������������������������������������0000664�0000000�0000000�00000023165�14364043643�0023255�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 3968 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 3970 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 3972 6 134 262 390 518 646 774 902 1030 1158 1286 1414 1542 1670 1798 1926 2054 2182 2310 2438 2566 2694 2822 2950 3078 3206 3334 3462 3590 3718 3846 3974 8 136 264 392 520 648 776 904 1032 1160 1288 1416 1544 1672 1800 1928 2056 2184 2312 2440 2568 2696 2824 2952 3080 3208 3336 3464 3592 3720 3848 3976 10 138 266 394 522 650 778 906 1034 1162 1290 1418 1546 1674 1802 1930 2058 2186 2314 2442 2570 2698 2826 2954 3082 3210 3338 3466 3594 3722 3850 3978 12 140 268 396 524 652 780 908 1036 1164 1292 1420 1548 1676 1804 1932 2060 2188 2316 2444 2572 2700 2828 2956 3084 3212 3340 3468 3596 3724 3852 3980 14 142 270 398 526 654 782 910 1038 1166 1294 1422 1550 1678 1806 1934 2062 2190 2318 2446 2574 2702 2830 2958 3086 3214 3342 3470 3598 3726 3854 3982 16 144 272 400 528 656 784 912 1040 1168 1296 1424 1552 1680 1808 1936 2064 2192 2320 2448 2576 2704 2832 2960 3088 3216 3344 3472 3600 3728 3856 3984 18 146 274 402 530 658 786 914 1042 1170 1298 1426 1554 1682 1810 1938 2066 2194 2322 2450 2578 2706 2834 2962 3090 3218 3346 3474 3602 3730 3858 3986 20 148 276 404 532 660 788 916 1044 1172 1300 1428 1556 1684 1812 1940 2068 2196 2324 2452 2580 2708 2836 2964 3092 3220 3348 3476 3604 3732 3860 3988 22 150 278 406 534 662 790 918 1046 1174 1302 1430 1558 1686 1814 1942 2070 2198 2326 2454 2582 2710 2838 2966 3094 3222 3350 3478 3606 3734 3862 3990 24 152 280 408 536 664 792 920 1048 1176 1304 1432 1560 1688 1816 1944 2072 2200 2328 2456 2584 2712 2840 2968 3096 3224 3352 3480 3608 3736 3864 3992 26 154 282 410 538 666 794 922 1050 1178 1306 1434 1562 1690 1818 1946 2074 2202 2330 2458 2586 2714 2842 2970 3098 3226 3354 3482 3610 3738 3866 3994 28 156 284 412 540 668 796 924 1052 1180 1308 1436 1564 1692 1820 1948 2076 2204 2332 2460 2588 2716 2844 2972 3100 3228 3356 3484 3612 3740 3868 3996 30 158 286 414 542 670 798 926 1054 1182 1310 1438 1566 1694 1822 1950 2078 2206 2334 2462 2590 2718 2846 2974 3102 3230 3358 3486 3614 3742 3870 3998 32 160 288 416 544 672 800 928 1056 1184 1312 1440 1568 1696 1824 1952 2080 2208 2336 2464 2592 2720 2848 2976 3104 3232 3360 3488 3616 3744 3872 4000 34 162 290 418 546 674 802 930 1058 1186 1314 1442 1570 1698 1826 1954 2082 2210 2338 2466 2594 2722 2850 2978 3106 3234 3362 3490 3618 3746 3874 4002 36 164 292 420 548 676 804 932 1060 1188 1316 1444 1572 1700 1828 1956 2084 2212 2340 2468 2596 2724 2852 2980 3108 3236 3364 3492 3620 3748 3876 4004 38 166 294 422 550 678 806 934 1062 1190 1318 1446 1574 1702 1830 1958 2086 2214 2342 2470 2598 2726 2854 2982 3110 3238 3366 3494 3622 3750 3878 4006 40 168 296 424 552 680 808 936 1064 1192 1320 1448 1576 1704 1832 1960 2088 2216 2344 2472 2600 2728 2856 2984 3112 3240 3368 3496 3624 3752 3880 4008 42 170 298 426 554 682 810 938 1066 1194 1322 1450 1578 1706 1834 1962 2090 2218 2346 2474 2602 2730 2858 2986 3114 3242 3370 3498 3626 3754 3882 4010 44 172 300 428 556 684 812 940 1068 1196 1324 1452 1580 1708 1836 1964 2092 2220 2348 2476 2604 2732 2860 2988 3116 3244 3372 3500 3628 3756 3884 4012 46 174 302 430 558 686 814 942 1070 1198 1326 1454 1582 1710 1838 1966 2094 2222 2350 2478 2606 2734 2862 2990 3118 3246 3374 3502 3630 3758 3886 4014 48 176 304 432 560 688 816 944 1072 1200 1328 1456 1584 1712 1840 1968 2096 2224 2352 2480 2608 2736 2864 2992 3120 3248 3376 3504 3632 3760 3888 4016 50 178 306 434 562 690 818 946 1074 1202 1330 1458 1586 1714 1842 1970 2098 2226 2354 2482 2610 2738 2866 2994 3122 3250 3378 3506 3634 3762 3890 4018 52 180 308 436 564 692 820 948 1076 1204 1332 1460 1588 1716 1844 1972 2100 2228 2356 2484 2612 2740 2868 2996 3124 3252 3380 3508 3636 3764 3892 4020 54 182 310 438 566 694 822 950 1078 1206 1334 1462 1590 1718 1846 1974 2102 2230 2358 2486 2614 2742 2870 2998 3126 3254 3382 3510 3638 3766 3894 4022 56 184 312 440 568 696 824 952 1080 1208 1336 1464 1592 1720 1848 1976 2104 2232 2360 2488 2616 2744 2872 3000 3128 3256 3384 3512 3640 3768 3896 4024 58 186 314 442 570 698 826 954 1082 1210 1338 1466 1594 1722 1850 1978 2106 2234 2362 2490 2618 2746 2874 3002 3130 3258 3386 3514 3642 3770 3898 4026 60 188 316 444 572 700 828 956 1084 1212 1340 1468 1596 1724 1852 1980 2108 2236 2364 2492 2620 2748 2876 3004 3132 3260 3388 3516 3644 3772 3900 4028 62 190 318 446 574 702 830 958 1086 1214 1342 1470 1598 1726 1854 1982 2110 2238 2366 2494 2622 2750 2878 3006 3134 3262 3390 3518 3646 3774 3902 4030 64 192 320 448 576 704 832 960 1088 1216 1344 1472 1600 1728 1856 1984 2112 2240 2368 2496 2624 2752 2880 3008 3136 3264 3392 3520 3648 3776 3904 4032 66 194 322 450 578 706 834 962 1090 1218 1346 1474 1602 1730 1858 1986 2114 2242 2370 2498 2626 2754 2882 3010 3138 3266 3394 3522 3650 3778 3906 4034 68 196 324 452 580 708 836 964 1092 1220 1348 1476 1604 1732 1860 1988 2116 2244 2372 2500 2628 2756 2884 3012 3140 3268 3396 3524 3652 3780 3908 4036 70 198 326 454 582 710 838 966 1094 1222 1350 1478 1606 1734 1862 1990 2118 2246 2374 2502 2630 2758 2886 3014 3142 3270 3398 3526 3654 3782 3910 4038 72 200 328 456 584 712 840 968 1096 1224 1352 1480 1608 1736 1864 1992 2120 2248 2376 2504 2632 2760 2888 3016 3144 3272 3400 3528 3656 3784 3912 4040 74 202 330 458 586 714 842 970 1098 1226 1354 1482 1610 1738 1866 1994 2122 2250 2378 2506 2634 2762 2890 3018 3146 3274 3402 3530 3658 3786 3914 4042 76 204 332 460 588 716 844 972 1100 1228 1356 1484 1612 1740 1868 1996 2124 2252 2380 2508 2636 2764 2892 3020 3148 3276 3404 3532 3660 3788 3916 4044 78 206 334 462 590 718 846 974 1102 1230 1358 1486 1614 1742 1870 1998 2126 2254 2382 2510 2638 2766 2894 3022 3150 3278 3406 3534 3662 3790 3918 4046 80 208 336 464 592 720 848 976 1104 1232 1360 1488 1616 1744 1872 2000 2128 2256 2384 2512 2640 2768 2896 3024 3152 3280 3408 3536 3664 3792 3920 4048 82 210 338 466 594 722 850 978 1106 1234 1362 1490 1618 1746 1874 2002 2130 2258 2386 2514 2642 2770 2898 3026 3154 3282 3410 3538 3666 3794 3922 4050 84 212 340 468 596 724 852 980 1108 1236 1364 1492 1620 1748 1876 2004 2132 2260 2388 2516 2644 2772 2900 3028 3156 3284 3412 3540 3668 3796 3924 4052 86 214 342 470 598 726 854 982 1110 1238 1366 1494 1622 1750 1878 2006 2134 2262 2390 2518 2646 2774 2902 3030 3158 3286 3414 3542 3670 3798 3926 4054 88 216 344 472 600 728 856 984 1112 1240 1368 1496 1624 1752 1880 2008 2136 2264 2392 2520 2648 2776 2904 3032 3160 3288 3416 3544 3672 3800 3928 4056 90 218 346 474 602 730 858 986 1114 1242 1370 1498 1626 1754 1882 2010 2138 2266 2394 2522 2650 2778 2906 3034 3162 3290 3418 3546 3674 3802 3930 4058 92 220 348 476 604 732 860 988 1116 1244 1372 1500 1628 1756 1884 2012 2140 2268 2396 2524 2652 2780 2908 3036 3164 3292 3420 3548 3676 3804 3932 4060 94 222 350 478 606 734 862 990 1118 1246 1374 1502 1630 1758 1886 2014 2142 2270 2398 2526 2654 2782 2910 3038 3166 3294 3422 3550 3678 3806 3934 4062 96 224 352 480 608 736 864 992 1120 1248 1376 1504 1632 1760 1888 2016 2144 2272 2400 2528 2656 2784 2912 3040 3168 3296 3424 3552 3680 3808 3936 4064 98 226 354 482 610 738 866 994 1122 1250 1378 1506 1634 1762 1890 2018 2146 2274 2402 2530 2658 2786 2914 3042 3170 3298 3426 3554 3682 3810 3938 4066 100 228 356 484 612 740 868 996 1124 1252 1380 1508 1636 1764 1892 2020 2148 2276 2404 2532 2660 2788 2916 3044 3172 3300 3428 3556 3684 3812 3940 4068 102 230 358 486 614 742 870 998 1126 1254 1382 1510 1638 1766 1894 2022 2150 2278 2406 2534 2662 2790 2918 3046 3174 3302 3430 3558 3686 3814 3942 4070 104 232 360 488 616 744 872 1000 1128 1256 1384 1512 1640 1768 1896 2024 2152 2280 2408 2536 2664 2792 2920 3048 3176 3304 3432 3560 3688 3816 3944 4072 106 234 362 490 618 746 874 1002 1130 1258 1386 1514 1642 1770 1898 2026 2154 2282 2410 2538 2666 2794 2922 3050 3178 3306 3434 3562 3690 3818 3946 4074 108 236 364 492 620 748 876 1004 1132 1260 1388 1516 1644 1772 1900 2028 2156 2284 2412 2540 2668 2796 2924 3052 3180 3308 3436 3564 3692 3820 3948 4076 110 238 366 494 622 750 878 1006 1134 1262 1390 1518 1646 1774 1902 2030 2158 2286 2414 2542 2670 2798 2926 3054 3182 3310 3438 3566 3694 3822 3950 4078 112 240 368 496 624 752 880 1008 1136 1264 1392 1520 1648 1776 1904 2032 2160 2288 2416 2544 2672 2800 2928 3056 3184 3312 3440 3568 3696 3824 3952 4080 114 242 370 498 626 754 882 1010 1138 1266 1394 1522 1650 1778 1906 2034 2162 2290 2418 2546 2674 2802 2930 3058 3186 3314 3442 3570 3698 3826 3954 4082 116 244 372 500 628 756 884 1012 1140 1268 1396 1524 1652 1780 1908 2036 2164 2292 2420 2548 2676 2804 2932 3060 3188 3316 3444 3572 3700 3828 3956 4084 118 246 374 502 630 758 886 1014 1142 1270 1398 1526 1654 1782 1910 2038 2166 2294 2422 2550 2678 2806 2934 3062 3190 3318 3446 3574 3702 3830 3958 4086 120 248 376 504 632 760 888 1016 1144 1272 1400 1528 1656 1784 1912 2040 2168 2296 2424 2552 2680 2808 2936 3064 3192 3320 3448 3576 3704 3832 3960 4088 122 250 378 506 634 762 890 1018 1146 1274 1402 1530 1658 1786 1914 2042 2170 2298 2426 2554 2682 2810 2938 3066 3194 3322 3450 3578 3706 3834 3962 4090 124 252 380 508 636 764 892 1020 1148 1276 1404 1532 1660 1788 1916 2044 2172 2300 2428 2556 2684 2812 2940 3068 3196 3324 3452 3580 3708 3836 3964 4092 126 254 382 510 638 766 894 1022 1150 1278 1406 1534 1662 1790 1918 2046 2174 2302 2430 2558 2686 2814 2942 3070 3198 3326 3454 3582 3710 3838 3966 4094 4096 4224 4352 4480 4608 4736 4864 4992 5120 5248 5376 5504 5632 5760 5888 6016 6144 6272 6400 6528 6656 6784 6912 7040 7168 7296 7424 7552 7680 7808 7936 8064 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nchw_2x129x3x33.txt�����������������������������������������0000664�0000000�0000000�00000457204�14364043643�0023347�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048 2176 2304 2432 2560 2688 2816 2944 3072 3200 3328 3456 3584 3712 3840 3968 4096 8192 8320 8448 8576 8704 8832 8960 9088 9216 9344 9472 9600 9728 9856 9984 10112 10240 10368 10496 10624 10752 10880 11008 11136 11264 11392 11520 11648 11776 11904 12032 12160 12288 16384 16512 16640 16768 16896 17024 17152 17280 17408 17536 17664 17792 17920 18048 18176 18304 18432 18560 18688 18816 18944 19072 19200 19328 19456 19584 19712 19840 19968 20096 20224 20352 20480 2 130 258 386 514 642 770 898 1026 1154 1282 1410 1538 1666 1794 1922 2050 2178 2306 2434 2562 2690 2818 2946 3074 3202 3330 3458 3586 3714 3842 3970 4098 8194 8322 8450 8578 8706 8834 8962 9090 9218 9346 9474 9602 9730 9858 9986 10114 10242 10370 10498 10626 10754 10882 11010 11138 11266 11394 11522 11650 11778 11906 12034 12162 12290 16386 16514 16642 16770 16898 17026 17154 17282 17410 17538 17666 17794 17922 18050 18178 18306 18434 18562 18690 18818 18946 19074 19202 19330 19458 19586 19714 19842 19970 20098 20226 20354 20482 4 132 260 388 516 644 772 900 1028 1156 1284 1412 1540 1668 1796 1924 2052 2180 2308 2436 2564 2692 2820 2948 3076 3204 3332 3460 3588 3716 3844 3972 4100 8196 8324 8452 8580 8708 8836 8964 9092 9220 9348 9476 9604 9732 9860 9988 10116 10244 10372 10500 10628 10756 10884 11012 11140 11268 11396 11524 11652 11780 11908 12036 12164 12292 16388 16516 16644 16772 16900 17028 17156 17284 17412 17540 17668 17796 17924 18052 18180 18308 18436 18564 18692 18820 18948 19076 19204 19332 19460 19588 19716 19844 19972 20100 20228 20356 20484 6 134 262 390 518 646 774 902 1030 1158 1286 1414 1542 1670 1798 1926 2054 2182 2310 2438 2566 2694 2822 2950 3078 3206 3334 3462 3590 3718 3846 3974 4102 8198 8326 8454 8582 8710 8838 8966 9094 9222 9350 9478 9606 9734 9862 9990 10118 10246 10374 10502 10630 10758 10886 11014 11142 11270 11398 11526 11654 11782 11910 12038 12166 12294 16390 16518 16646 16774 16902 17030 17158 17286 17414 17542 17670 17798 17926 18054 18182 18310 18438 18566 18694 18822 18950 19078 19206 19334 19462 19590 19718 19846 19974 20102 20230 20358 20486 8 136 264 392 520 648 776 904 1032 1160 1288 1416 1544 1672 1800 1928 2056 2184 2312 2440 2568 2696 2824 2952 3080 3208 3336 3464 3592 3720 3848 3976 4104 8200 8328 8456 8584 8712 8840 8968 9096 9224 9352 9480 9608 9736 9864 9992 10120 10248 10376 10504 10632 10760 10888 11016 11144 11272 11400 11528 11656 11784 11912 12040 12168 12296 16392 16520 16648 16776 16904 17032 17160 17288 17416 17544 17672 17800 17928 18056 18184 18312 18440 18568 18696 18824 18952 19080 19208 19336 19464 19592 19720 19848 19976 20104 20232 20360 20488 10 138 266 394 522 650 778 906 1034 1162 1290 1418 1546 1674 1802 1930 2058 2186 2314 2442 2570 2698 2826 2954 3082 3210 3338 3466 3594 3722 3850 3978 4106 8202 8330 8458 8586 8714 8842 8970 9098 9226 9354 9482 9610 9738 9866 9994 10122 10250 10378 10506 10634 10762 10890 11018 11146 11274 11402 11530 11658 11786 11914 12042 12170 12298 16394 16522 16650 16778 16906 17034 17162 17290 17418 17546 17674 17802 17930 18058 18186 18314 18442 18570 18698 18826 18954 19082 19210 19338 19466 19594 19722 19850 19978 20106 20234 20362 20490 12 140 268 396 524 652 780 908 1036 1164 1292 1420 1548 1676 1804 1932 2060 2188 2316 2444 2572 2700 2828 2956 3084 3212 3340 3468 3596 3724 3852 3980 4108 8204 8332 8460 8588 8716 8844 8972 9100 9228 9356 9484 9612 9740 9868 9996 10124 10252 10380 10508 10636 10764 10892 11020 11148 11276 11404 11532 11660 11788 11916 12044 12172 12300 16396 16524 16652 16780 16908 17036 17164 17292 17420 17548 17676 17804 17932 18060 18188 18316 18444 18572 18700 18828 18956 19084 19212 19340 19468 19596 19724 19852 19980 20108 20236 20364 20492 14 142 270 398 526 654 782 910 1038 1166 1294 1422 1550 1678 1806 1934 2062 2190 2318 2446 2574 2702 2830 2958 3086 3214 3342 3470 3598 3726 3854 3982 4110 8206 8334 8462 8590 8718 8846 8974 9102 9230 9358 9486 9614 9742 9870 9998 10126 10254 10382 10510 10638 10766 10894 11022 11150 11278 11406 11534 11662 11790 11918 12046 12174 12302 16398 16526 16654 16782 16910 17038 17166 17294 17422 17550 17678 17806 17934 18062 18190 18318 18446 18574 18702 18830 18958 19086 19214 19342 19470 19598 19726 19854 19982 20110 20238 20366 20494 16 144 272 400 528 656 784 912 1040 1168 1296 1424 1552 1680 1808 1936 2064 2192 2320 2448 2576 2704 2832 2960 3088 3216 3344 3472 3600 3728 3856 3984 4112 8208 8336 8464 8592 8720 8848 8976 9104 9232 9360 9488 9616 9744 9872 10000 10128 10256 10384 10512 10640 10768 10896 11024 11152 11280 11408 11536 11664 11792 11920 12048 12176 12304 16400 16528 16656 16784 16912 17040 17168 17296 17424 17552 17680 17808 17936 18064 18192 18320 18448 18576 18704 18832 18960 19088 19216 19344 19472 19600 19728 19856 19984 20112 20240 20368 20496 18 146 274 402 530 658 786 914 1042 1170 1298 1426 1554 1682 1810 1938 2066 2194 2322 2450 2578 2706 2834 2962 3090 3218 3346 3474 3602 3730 3858 3986 4114 8210 8338 8466 8594 8722 8850 8978 9106 9234 9362 9490 9618 9746 9874 10002 10130 10258 10386 10514 10642 10770 10898 11026 11154 11282 11410 11538 11666 11794 11922 12050 12178 12306 16402 16530 16658 16786 16914 17042 17170 17298 17426 17554 17682 17810 17938 18066 18194 18322 18450 18578 18706 18834 18962 19090 19218 19346 19474 19602 19730 19858 19986 20114 20242 20370 20498 20 148 276 404 532 660 788 916 1044 1172 1300 1428 1556 1684 1812 1940 2068 2196 2324 2452 2580 2708 2836 2964 3092 3220 3348 3476 3604 3732 3860 3988 4116 8212 8340 8468 8596 8724 8852 8980 9108 9236 9364 9492 9620 9748 9876 10004 10132 10260 10388 10516 10644 10772 10900 11028 11156 11284 11412 11540 11668 11796 11924 12052 12180 12308 16404 16532 16660 16788 16916 17044 17172 17300 17428 17556 17684 17812 17940 18068 18196 18324 18452 18580 18708 18836 18964 19092 19220 19348 19476 19604 19732 19860 19988 20116 20244 20372 20500 22 150 278 406 534 662 790 918 1046 1174 1302 1430 1558 1686 1814 1942 2070 2198 2326 2454 2582 2710 2838 2966 3094 3222 3350 3478 3606 3734 3862 3990 4118 8214 8342 8470 8598 8726 8854 8982 9110 9238 9366 9494 9622 9750 9878 10006 10134 10262 10390 10518 10646 10774 10902 11030 11158 11286 11414 11542 11670 11798 11926 12054 12182 12310 16406 16534 16662 16790 16918 17046 17174 17302 17430 17558 17686 17814 17942 18070 18198 18326 18454 18582 18710 18838 18966 19094 19222 19350 19478 19606 19734 19862 19990 20118 20246 20374 20502 24 152 280 408 536 664 792 920 1048 1176 1304 1432 1560 1688 1816 1944 2072 2200 2328 2456 2584 2712 2840 2968 3096 3224 3352 3480 3608 3736 3864 3992 4120 8216 8344 8472 8600 8728 8856 8984 9112 9240 9368 9496 9624 9752 9880 10008 10136 10264 10392 10520 10648 10776 10904 11032 11160 11288 11416 11544 11672 11800 11928 12056 12184 12312 16408 16536 16664 16792 16920 17048 17176 17304 17432 17560 17688 17816 17944 18072 18200 18328 18456 18584 18712 18840 18968 19096 19224 19352 19480 19608 19736 19864 19992 20120 20248 20376 20504 26 154 282 410 538 666 794 922 1050 1178 1306 1434 1562 1690 1818 1946 2074 2202 2330 2458 2586 2714 2842 2970 3098 3226 3354 3482 3610 3738 3866 3994 4122 8218 8346 8474 8602 8730 8858 8986 9114 9242 9370 9498 9626 9754 9882 10010 10138 10266 10394 10522 10650 10778 10906 11034 11162 11290 11418 11546 11674 11802 11930 12058 12186 12314 16410 16538 16666 16794 16922 17050 17178 17306 17434 17562 17690 17818 17946 18074 18202 18330 18458 18586 18714 18842 18970 19098 19226 19354 19482 19610 19738 19866 19994 20122 20250 20378 20506 28 156 284 412 540 668 796 924 1052 1180 1308 1436 1564 1692 1820 1948 2076 2204 2332 2460 2588 2716 2844 2972 3100 3228 3356 3484 3612 3740 3868 3996 4124 8220 8348 8476 8604 8732 8860 8988 9116 9244 9372 9500 9628 9756 9884 10012 10140 10268 10396 10524 10652 10780 10908 11036 11164 11292 11420 11548 11676 11804 11932 12060 12188 12316 16412 16540 16668 16796 16924 17052 17180 17308 17436 17564 17692 17820 17948 18076 18204 18332 18460 18588 18716 18844 18972 19100 19228 19356 19484 19612 19740 19868 19996 20124 20252 20380 20508 30 158 286 414 542 670 798 926 1054 1182 1310 1438 1566 1694 1822 1950 2078 2206 2334 2462 2590 2718 2846 2974 3102 3230 3358 3486 3614 3742 3870 3998 4126 8222 8350 8478 8606 8734 8862 8990 9118 9246 9374 9502 9630 9758 9886 10014 10142 10270 10398 10526 10654 10782 10910 11038 11166 11294 11422 11550 11678 11806 11934 12062 12190 12318 16414 16542 16670 16798 16926 17054 17182 17310 17438 17566 17694 17822 17950 18078 18206 18334 18462 18590 18718 18846 18974 19102 19230 19358 19486 19614 19742 19870 19998 20126 20254 20382 20510 32 160 288 416 544 672 800 928 1056 1184 1312 1440 1568 1696 1824 1952 2080 2208 2336 2464 2592 2720 2848 2976 3104 3232 3360 3488 3616 3744 3872 4000 4128 8224 8352 8480 8608 8736 8864 8992 9120 9248 9376 9504 9632 9760 9888 10016 10144 10272 10400 10528 10656 10784 10912 11040 11168 11296 11424 11552 11680 11808 11936 12064 12192 12320 16416 16544 16672 16800 16928 17056 17184 17312 17440 17568 17696 17824 17952 18080 18208 18336 18464 18592 18720 18848 18976 19104 19232 19360 19488 19616 19744 19872 20000 20128 20256 20384 20512 34 162 290 418 546 674 802 930 1058 1186 1314 1442 1570 1698 1826 1954 2082 2210 2338 2466 2594 2722 2850 2978 3106 3234 3362 3490 3618 3746 3874 4002 4130 8226 8354 8482 8610 8738 8866 8994 9122 9250 9378 9506 9634 9762 9890 10018 10146 10274 10402 10530 10658 10786 10914 11042 11170 11298 11426 11554 11682 11810 11938 12066 12194 12322 16418 16546 16674 16802 16930 17058 17186 17314 17442 17570 17698 17826 17954 18082 18210 18338 18466 18594 18722 18850 18978 19106 19234 19362 19490 19618 19746 19874 20002 20130 20258 20386 20514 36 164 292 420 548 676 804 932 1060 1188 1316 1444 1572 1700 1828 1956 2084 2212 2340 2468 2596 2724 2852 2980 3108 3236 3364 3492 3620 3748 3876 4004 4132 8228 8356 8484 8612 8740 8868 8996 9124 9252 9380 9508 9636 9764 9892 10020 10148 10276 10404 10532 10660 10788 10916 11044 11172 11300 11428 11556 11684 11812 11940 12068 12196 12324 16420 16548 16676 16804 16932 17060 17188 17316 17444 17572 17700 17828 17956 18084 18212 18340 18468 18596 18724 18852 18980 19108 19236 19364 19492 19620 19748 19876 20004 20132 20260 20388 20516 38 166 294 422 550 678 806 934 1062 1190 1318 1446 1574 1702 1830 1958 2086 2214 2342 2470 2598 2726 2854 2982 3110 3238 3366 3494 3622 3750 3878 4006 4134 8230 8358 8486 8614 8742 8870 8998 9126 9254 9382 9510 9638 9766 9894 10022 10150 10278 10406 10534 10662 10790 10918 11046 11174 11302 11430 11558 11686 11814 11942 12070 12198 12326 16422 16550 16678 16806 16934 17062 17190 17318 17446 17574 17702 17830 17958 18086 18214 18342 18470 18598 18726 18854 18982 19110 19238 19366 19494 19622 19750 19878 20006 20134 20262 20390 20518 40 168 296 424 552 680 808 936 1064 1192 1320 1448 1576 1704 1832 1960 2088 2216 2344 2472 2600 2728 2856 2984 3112 3240 3368 3496 3624 3752 3880 4008 4136 8232 8360 8488 8616 8744 8872 9000 9128 9256 9384 9512 9640 9768 9896 10024 10152 10280 10408 10536 10664 10792 10920 11048 11176 11304 11432 11560 11688 11816 11944 12072 12200 12328 16424 16552 16680 16808 16936 17064 17192 17320 17448 17576 17704 17832 17960 18088 18216 18344 18472 18600 18728 18856 18984 19112 19240 19368 19496 19624 19752 19880 20008 20136 20264 20392 20520 42 170 298 426 554 682 810 938 1066 1194 1322 1450 1578 1706 1834 1962 2090 2218 2346 2474 2602 2730 2858 2986 3114 3242 3370 3498 3626 3754 3882 4010 4138 8234 8362 8490 8618 8746 8874 9002 9130 9258 9386 9514 9642 9770 9898 10026 10154 10282 10410 10538 10666 10794 10922 11050 11178 11306 11434 11562 11690 11818 11946 12074 12202 12330 16426 16554 16682 16810 16938 17066 17194 17322 17450 17578 17706 17834 17962 18090 18218 18346 18474 18602 18730 18858 18986 19114 19242 19370 19498 19626 19754 19882 20010 20138 20266 20394 20522 44 172 300 428 556 684 812 940 1068 1196 1324 1452 1580 1708 1836 1964 2092 2220 2348 2476 2604 2732 2860 2988 3116 3244 3372 3500 3628 3756 3884 4012 4140 8236 8364 8492 8620 8748 8876 9004 9132 9260 9388 9516 9644 9772 9900 10028 10156 10284 10412 10540 10668 10796 10924 11052 11180 11308 11436 11564 11692 11820 11948 12076 12204 12332 16428 16556 16684 16812 16940 17068 17196 17324 17452 17580 17708 17836 17964 18092 18220 18348 18476 18604 18732 18860 18988 19116 19244 19372 19500 19628 19756 19884 20012 20140 20268 20396 20524 46 174 302 430 558 686 814 942 1070 1198 1326 1454 1582 1710 1838 1966 2094 2222 2350 2478 2606 2734 2862 2990 3118 3246 3374 3502 3630 3758 3886 4014 4142 8238 8366 8494 8622 8750 8878 9006 9134 9262 9390 9518 9646 9774 9902 10030 10158 10286 10414 10542 10670 10798 10926 11054 11182 11310 11438 11566 11694 11822 11950 12078 12206 12334 16430 16558 16686 16814 16942 17070 17198 17326 17454 17582 17710 17838 17966 18094 18222 18350 18478 18606 18734 18862 18990 19118 19246 19374 19502 19630 19758 19886 20014 20142 20270 20398 20526 48 176 304 432 560 688 816 944 1072 1200 1328 1456 1584 1712 1840 1968 2096 2224 2352 2480 2608 2736 2864 2992 3120 3248 3376 3504 3632 3760 3888 4016 4144 8240 8368 8496 8624 8752 8880 9008 9136 9264 9392 9520 9648 9776 9904 10032 10160 10288 10416 10544 10672 10800 10928 11056 11184 11312 11440 11568 11696 11824 11952 12080 12208 12336 16432 16560 16688 16816 16944 17072 17200 17328 17456 17584 17712 17840 17968 18096 18224 18352 18480 18608 18736 18864 18992 19120 19248 19376 19504 19632 19760 19888 20016 20144 20272 20400 20528 50 178 306 434 562 690 818 946 1074 1202 1330 1458 1586 1714 1842 1970 2098 2226 2354 2482 2610 2738 2866 2994 3122 3250 3378 3506 3634 3762 3890 4018 4146 8242 8370 8498 8626 8754 8882 9010 9138 9266 9394 9522 9650 9778 9906 10034 10162 10290 10418 10546 10674 10802 10930 11058 11186 11314 11442 11570 11698 11826 11954 12082 12210 12338 16434 16562 16690 16818 16946 17074 17202 17330 17458 17586 17714 17842 17970 18098 18226 18354 18482 18610 18738 18866 18994 19122 19250 19378 19506 19634 19762 19890 20018 20146 20274 20402 20530 52 180 308 436 564 692 820 948 1076 1204 1332 1460 1588 1716 1844 1972 2100 2228 2356 2484 2612 2740 2868 2996 3124 3252 3380 3508 3636 3764 3892 4020 4148 8244 8372 8500 8628 8756 8884 9012 9140 9268 9396 9524 9652 9780 9908 10036 10164 10292 10420 10548 10676 10804 10932 11060 11188 11316 11444 11572 11700 11828 11956 12084 12212 12340 16436 16564 16692 16820 16948 17076 17204 17332 17460 17588 17716 17844 17972 18100 18228 18356 18484 18612 18740 18868 18996 19124 19252 19380 19508 19636 19764 19892 20020 20148 20276 20404 20532 54 182 310 438 566 694 822 950 1078 1206 1334 1462 1590 1718 1846 1974 2102 2230 2358 2486 2614 2742 2870 2998 3126 3254 3382 3510 3638 3766 3894 4022 4150 8246 8374 8502 8630 8758 8886 9014 9142 9270 9398 9526 9654 9782 9910 10038 10166 10294 10422 10550 10678 10806 10934 11062 11190 11318 11446 11574 11702 11830 11958 12086 12214 12342 16438 16566 16694 16822 16950 17078 17206 17334 17462 17590 17718 17846 17974 18102 18230 18358 18486 18614 18742 18870 18998 19126 19254 19382 19510 19638 19766 19894 20022 20150 20278 20406 20534 56 184 312 440 568 696 824 952 1080 1208 1336 1464 1592 1720 1848 1976 2104 2232 2360 2488 2616 2744 2872 3000 3128 3256 3384 3512 3640 3768 3896 4024 4152 8248 8376 8504 8632 8760 8888 9016 9144 9272 9400 9528 9656 9784 9912 10040 10168 10296 10424 10552 10680 10808 10936 11064 11192 11320 11448 11576 11704 11832 11960 12088 12216 12344 16440 16568 16696 16824 16952 17080 17208 17336 17464 17592 17720 17848 17976 18104 18232 18360 18488 18616 18744 18872 19000 19128 19256 19384 19512 19640 19768 19896 20024 20152 20280 20408 20536 58 186 314 442 570 698 826 954 1082 1210 1338 1466 1594 1722 1850 1978 2106 2234 2362 2490 2618 2746 2874 3002 3130 3258 3386 3514 3642 3770 3898 4026 4154 8250 8378 8506 8634 8762 8890 9018 9146 9274 9402 9530 9658 9786 9914 10042 10170 10298 10426 10554 10682 10810 10938 11066 11194 11322 11450 11578 11706 11834 11962 12090 12218 12346 16442 16570 16698 16826 16954 17082 17210 17338 17466 17594 17722 17850 17978 18106 18234 18362 18490 18618 18746 18874 19002 19130 19258 19386 19514 19642 19770 19898 20026 20154 20282 20410 20538 60 188 316 444 572 700 828 956 1084 1212 1340 1468 1596 1724 1852 1980 2108 2236 2364 2492 2620 2748 2876 3004 3132 3260 3388 3516 3644 3772 3900 4028 4156 8252 8380 8508 8636 8764 8892 9020 9148 9276 9404 9532 9660 9788 9916 10044 10172 10300 10428 10556 10684 10812 10940 11068 11196 11324 11452 11580 11708 11836 11964 12092 12220 12348 16444 16572 16700 16828 16956 17084 17212 17340 17468 17596 17724 17852 17980 18108 18236 18364 18492 18620 18748 18876 19004 19132 19260 19388 19516 19644 19772 19900 20028 20156 20284 20412 20540 62 190 318 446 574 702 830 958 1086 1214 1342 1470 1598 1726 1854 1982 2110 2238 2366 2494 2622 2750 2878 3006 3134 3262 3390 3518 3646 3774 3902 4030 4158 8254 8382 8510 8638 8766 8894 9022 9150 9278 9406 9534 9662 9790 9918 10046 10174 10302 10430 10558 10686 10814 10942 11070 11198 11326 11454 11582 11710 11838 11966 12094 12222 12350 16446 16574 16702 16830 16958 17086 17214 17342 17470 17598 17726 17854 17982 18110 18238 18366 18494 18622 18750 18878 19006 19134 19262 19390 19518 19646 19774 19902 20030 20158 20286 20414 20542 64 192 320 448 576 704 832 960 1088 1216 1344 1472 1600 1728 1856 1984 2112 2240 2368 2496 2624 2752 2880 3008 3136 3264 3392 3520 3648 3776 3904 4032 4160 8256 8384 8512 8640 8768 8896 9024 9152 9280 9408 9536 9664 9792 9920 10048 10176 10304 10432 10560 10688 10816 10944 11072 11200 11328 11456 11584 11712 11840 11968 12096 12224 12352 16448 16576 16704 16832 16960 17088 17216 17344 17472 17600 17728 17856 17984 18112 18240 18368 18496 18624 18752 18880 19008 19136 19264 19392 19520 19648 19776 19904 20032 20160 20288 20416 20544 66 194 322 450 578 706 834 962 1090 1218 1346 1474 1602 1730 1858 1986 2114 2242 2370 2498 2626 2754 2882 3010 3138 3266 3394 3522 3650 3778 3906 4034 4162 8258 8386 8514 8642 8770 8898 9026 9154 9282 9410 9538 9666 9794 9922 10050 10178 10306 10434 10562 10690 10818 10946 11074 11202 11330 11458 11586 11714 11842 11970 12098 12226 12354 16450 16578 16706 16834 16962 17090 17218 17346 17474 17602 17730 17858 17986 18114 18242 18370 18498 18626 18754 18882 19010 19138 19266 19394 19522 19650 19778 19906 20034 20162 20290 20418 20546 68 196 324 452 580 708 836 964 1092 1220 1348 1476 1604 1732 1860 1988 2116 2244 2372 2500 2628 2756 2884 3012 3140 3268 3396 3524 3652 3780 3908 4036 4164 8260 8388 8516 8644 8772 8900 9028 9156 9284 9412 9540 9668 9796 9924 10052 10180 10308 10436 10564 10692 10820 10948 11076 11204 11332 11460 11588 11716 11844 11972 12100 12228 12356 16452 16580 16708 16836 16964 17092 17220 17348 17476 17604 17732 17860 17988 18116 18244 18372 18500 18628 18756 18884 19012 19140 19268 19396 19524 19652 19780 19908 20036 20164 20292 20420 20548 70 198 326 454 582 710 838 966 1094 1222 1350 1478 1606 1734 1862 1990 2118 2246 2374 2502 2630 2758 2886 3014 3142 3270 3398 3526 3654 3782 3910 4038 4166 8262 8390 8518 8646 8774 8902 9030 9158 9286 9414 9542 9670 9798 9926 10054 10182 10310 10438 10566 10694 10822 10950 11078 11206 11334 11462 11590 11718 11846 11974 12102 12230 12358 16454 16582 16710 16838 16966 17094 17222 17350 17478 17606 17734 17862 17990 18118 18246 18374 18502 18630 18758 18886 19014 19142 19270 19398 19526 19654 19782 19910 20038 20166 20294 20422 20550 72 200 328 456 584 712 840 968 1096 1224 1352 1480 1608 1736 1864 1992 2120 2248 2376 2504 2632 2760 2888 3016 3144 3272 3400 3528 3656 3784 3912 4040 4168 8264 8392 8520 8648 8776 8904 9032 9160 9288 9416 9544 9672 9800 9928 10056 10184 10312 10440 10568 10696 10824 10952 11080 11208 11336 11464 11592 11720 11848 11976 12104 12232 12360 16456 16584 16712 16840 16968 17096 17224 17352 17480 17608 17736 17864 17992 18120 18248 18376 18504 18632 18760 18888 19016 19144 19272 19400 19528 19656 19784 19912 20040 20168 20296 20424 20552 74 202 330 458 586 714 842 970 1098 1226 1354 1482 1610 1738 1866 1994 2122 2250 2378 2506 2634 2762 2890 3018 3146 3274 3402 3530 3658 3786 3914 4042 4170 8266 8394 8522 8650 8778 8906 9034 9162 9290 9418 9546 9674 9802 9930 10058 10186 10314 10442 10570 10698 10826 10954 11082 11210 11338 11466 11594 11722 11850 11978 12106 12234 12362 16458 16586 16714 16842 16970 17098 17226 17354 17482 17610 17738 17866 17994 18122 18250 18378 18506 18634 18762 18890 19018 19146 19274 19402 19530 19658 19786 19914 20042 20170 20298 20426 20554 76 204 332 460 588 716 844 972 1100 1228 1356 1484 1612 1740 1868 1996 2124 2252 2380 2508 2636 2764 2892 3020 3148 3276 3404 3532 3660 3788 3916 4044 4172 8268 8396 8524 8652 8780 8908 9036 9164 9292 9420 9548 9676 9804 9932 10060 10188 10316 10444 10572 10700 10828 10956 11084 11212 11340 11468 11596 11724 11852 11980 12108 12236 12364 16460 16588 16716 16844 16972 17100 17228 17356 17484 17612 17740 17868 17996 18124 18252 18380 18508 18636 18764 18892 19020 19148 19276 19404 19532 19660 19788 19916 20044 20172 20300 20428 20556 78 206 334 462 590 718 846 974 1102 1230 1358 1486 1614 1742 1870 1998 2126 2254 2382 2510 2638 2766 2894 3022 3150 3278 3406 3534 3662 3790 3918 4046 4174 8270 8398 8526 8654 8782 8910 9038 9166 9294 9422 9550 9678 9806 9934 10062 10190 10318 10446 10574 10702 10830 10958 11086 11214 11342 11470 11598 11726 11854 11982 12110 12238 12366 16462 16590 16718 16846 16974 17102 17230 17358 17486 17614 17742 17870 17998 18126 18254 18382 18510 18638 18766 18894 19022 19150 19278 19406 19534 19662 19790 19918 20046 20174 20302 20430 20558 80 208 336 464 592 720 848 976 1104 1232 1360 1488 1616 1744 1872 2000 2128 2256 2384 2512 2640 2768 2896 3024 3152 3280 3408 3536 3664 3792 3920 4048 4176 8272 8400 8528 8656 8784 8912 9040 9168 9296 9424 9552 9680 9808 9936 10064 10192 10320 10448 10576 10704 10832 10960 11088 11216 11344 11472 11600 11728 11856 11984 12112 12240 12368 16464 16592 16720 16848 16976 17104 17232 17360 17488 17616 17744 17872 18000 18128 18256 18384 18512 18640 18768 18896 19024 19152 19280 19408 19536 19664 19792 19920 20048 20176 20304 20432 20560 82 210 338 466 594 722 850 978 1106 1234 1362 1490 1618 1746 1874 2002 2130 2258 2386 2514 2642 2770 2898 3026 3154 3282 3410 3538 3666 3794 3922 4050 4178 8274 8402 8530 8658 8786 8914 9042 9170 9298 9426 9554 9682 9810 9938 10066 10194 10322 10450 10578 10706 10834 10962 11090 11218 11346 11474 11602 11730 11858 11986 12114 12242 12370 16466 16594 16722 16850 16978 17106 17234 17362 17490 17618 17746 17874 18002 18130 18258 18386 18514 18642 18770 18898 19026 19154 19282 19410 19538 19666 19794 19922 20050 20178 20306 20434 20562 84 212 340 468 596 724 852 980 1108 1236 1364 1492 1620 1748 1876 2004 2132 2260 2388 2516 2644 2772 2900 3028 3156 3284 3412 3540 3668 3796 3924 4052 4180 8276 8404 8532 8660 8788 8916 9044 9172 9300 9428 9556 9684 9812 9940 10068 10196 10324 10452 10580 10708 10836 10964 11092 11220 11348 11476 11604 11732 11860 11988 12116 12244 12372 16468 16596 16724 16852 16980 17108 17236 17364 17492 17620 17748 17876 18004 18132 18260 18388 18516 18644 18772 18900 19028 19156 19284 19412 19540 19668 19796 19924 20052 20180 20308 20436 20564 86 214 342 470 598 726 854 982 1110 1238 1366 1494 1622 1750 1878 2006 2134 2262 2390 2518 2646 2774 2902 3030 3158 3286 3414 3542 3670 3798 3926 4054 4182 8278 8406 8534 8662 8790 8918 9046 9174 9302 9430 9558 9686 9814 9942 10070 10198 10326 10454 10582 10710 10838 10966 11094 11222 11350 11478 11606 11734 11862 11990 12118 12246 12374 16470 16598 16726 16854 16982 17110 17238 17366 17494 17622 17750 17878 18006 18134 18262 18390 18518 18646 18774 18902 19030 19158 19286 19414 19542 19670 19798 19926 20054 20182 20310 20438 20566 88 216 344 472 600 728 856 984 1112 1240 1368 1496 1624 1752 1880 2008 2136 2264 2392 2520 2648 2776 2904 3032 3160 3288 3416 3544 3672 3800 3928 4056 4184 8280 8408 8536 8664 8792 8920 9048 9176 9304 9432 9560 9688 9816 9944 10072 10200 10328 10456 10584 10712 10840 10968 11096 11224 11352 11480 11608 11736 11864 11992 12120 12248 12376 16472 16600 16728 16856 16984 17112 17240 17368 17496 17624 17752 17880 18008 18136 18264 18392 18520 18648 18776 18904 19032 19160 19288 19416 19544 19672 19800 19928 20056 20184 20312 20440 20568 90 218 346 474 602 730 858 986 1114 1242 1370 1498 1626 1754 1882 2010 2138 2266 2394 2522 2650 2778 2906 3034 3162 3290 3418 3546 3674 3802 3930 4058 4186 8282 8410 8538 8666 8794 8922 9050 9178 9306 9434 9562 9690 9818 9946 10074 10202 10330 10458 10586 10714 10842 10970 11098 11226 11354 11482 11610 11738 11866 11994 12122 12250 12378 16474 16602 16730 16858 16986 17114 17242 17370 17498 17626 17754 17882 18010 18138 18266 18394 18522 18650 18778 18906 19034 19162 19290 19418 19546 19674 19802 19930 20058 20186 20314 20442 20570 92 220 348 476 604 732 860 988 1116 1244 1372 1500 1628 1756 1884 2012 2140 2268 2396 2524 2652 2780 2908 3036 3164 3292 3420 3548 3676 3804 3932 4060 4188 8284 8412 8540 8668 8796 8924 9052 9180 9308 9436 9564 9692 9820 9948 10076 10204 10332 10460 10588 10716 10844 10972 11100 11228 11356 11484 11612 11740 11868 11996 12124 12252 12380 16476 16604 16732 16860 16988 17116 17244 17372 17500 17628 17756 17884 18012 18140 18268 18396 18524 18652 18780 18908 19036 19164 19292 19420 19548 19676 19804 19932 20060 20188 20316 20444 20572 94 222 350 478 606 734 862 990 1118 1246 1374 1502 1630 1758 1886 2014 2142 2270 2398 2526 2654 2782 2910 3038 3166 3294 3422 3550 3678 3806 3934 4062 4190 8286 8414 8542 8670 8798 8926 9054 9182 9310 9438 9566 9694 9822 9950 10078 10206 10334 10462 10590 10718 10846 10974 11102 11230 11358 11486 11614 11742 11870 11998 12126 12254 12382 16478 16606 16734 16862 16990 17118 17246 17374 17502 17630 17758 17886 18014 18142 18270 18398 18526 18654 18782 18910 19038 19166 19294 19422 19550 19678 19806 19934 20062 20190 20318 20446 20574 96 224 352 480 608 736 864 992 1120 1248 1376 1504 1632 1760 1888 2016 2144 2272 2400 2528 2656 2784 2912 3040 3168 3296 3424 3552 3680 3808 3936 4064 4192 8288 8416 8544 8672 8800 8928 9056 9184 9312 9440 9568 9696 9824 9952 10080 10208 10336 10464 10592 10720 10848 10976 11104 11232 11360 11488 11616 11744 11872 12000 12128 12256 12384 16480 16608 16736 16864 16992 17120 17248 17376 17504 17632 17760 17888 18016 18144 18272 18400 18528 18656 18784 18912 19040 19168 19296 19424 19552 19680 19808 19936 20064 20192 20320 20448 20576 98 226 354 482 610 738 866 994 1122 1250 1378 1506 1634 1762 1890 2018 2146 2274 2402 2530 2658 2786 2914 3042 3170 3298 3426 3554 3682 3810 3938 4066 4194 8290 8418 8546 8674 8802 8930 9058 9186 9314 9442 9570 9698 9826 9954 10082 10210 10338 10466 10594 10722 10850 10978 11106 11234 11362 11490 11618 11746 11874 12002 12130 12258 12386 16482 16610 16738 16866 16994 17122 17250 17378 17506 17634 17762 17890 18018 18146 18274 18402 18530 18658 18786 18914 19042 19170 19298 19426 19554 19682 19810 19938 20066 20194 20322 20450 20578 100 228 356 484 612 740 868 996 1124 1252 1380 1508 1636 1764 1892 2020 2148 2276 2404 2532 2660 2788 2916 3044 3172 3300 3428 3556 3684 3812 3940 4068 4196 8292 8420 8548 8676 8804 8932 9060 9188 9316 9444 9572 9700 9828 9956 10084 10212 10340 10468 10596 10724 10852 10980 11108 11236 11364 11492 11620 11748 11876 12004 12132 12260 12388 16484 16612 16740 16868 16996 17124 17252 17380 17508 17636 17764 17892 18020 18148 18276 18404 18532 18660 18788 18916 19044 19172 19300 19428 19556 19684 19812 19940 20068 20196 20324 20452 20580 102 230 358 486 614 742 870 998 1126 1254 1382 1510 1638 1766 1894 2022 2150 2278 2406 2534 2662 2790 2918 3046 3174 3302 3430 3558 3686 3814 3942 4070 4198 8294 8422 8550 8678 8806 8934 9062 9190 9318 9446 9574 9702 9830 9958 10086 10214 10342 10470 10598 10726 10854 10982 11110 11238 11366 11494 11622 11750 11878 12006 12134 12262 12390 16486 16614 16742 16870 16998 17126 17254 17382 17510 17638 17766 17894 18022 18150 18278 18406 18534 18662 18790 18918 19046 19174 19302 19430 19558 19686 19814 19942 20070 20198 20326 20454 20582 104 232 360 488 616 744 872 1000 1128 1256 1384 1512 1640 1768 1896 2024 2152 2280 2408 2536 2664 2792 2920 3048 3176 3304 3432 3560 3688 3816 3944 4072 4200 8296 8424 8552 8680 8808 8936 9064 9192 9320 9448 9576 9704 9832 9960 10088 10216 10344 10472 10600 10728 10856 10984 11112 11240 11368 11496 11624 11752 11880 12008 12136 12264 12392 16488 16616 16744 16872 17000 17128 17256 17384 17512 17640 17768 17896 18024 18152 18280 18408 18536 18664 18792 18920 19048 19176 19304 19432 19560 19688 19816 19944 20072 20200 20328 20456 20584 106 234 362 490 618 746 874 1002 1130 1258 1386 1514 1642 1770 1898 2026 2154 2282 2410 2538 2666 2794 2922 3050 3178 3306 3434 3562 3690 3818 3946 4074 4202 8298 8426 8554 8682 8810 8938 9066 9194 9322 9450 9578 9706 9834 9962 10090 10218 10346 10474 10602 10730 10858 10986 11114 11242 11370 11498 11626 11754 11882 12010 12138 12266 12394 16490 16618 16746 16874 17002 17130 17258 17386 17514 17642 17770 17898 18026 18154 18282 18410 18538 18666 18794 18922 19050 19178 19306 19434 19562 19690 19818 19946 20074 20202 20330 20458 20586 108 236 364 492 620 748 876 1004 1132 1260 1388 1516 1644 1772 1900 2028 2156 2284 2412 2540 2668 2796 2924 3052 3180 3308 3436 3564 3692 3820 3948 4076 4204 8300 8428 8556 8684 8812 8940 9068 9196 9324 9452 9580 9708 9836 9964 10092 10220 10348 10476 10604 10732 10860 10988 11116 11244 11372 11500 11628 11756 11884 12012 12140 12268 12396 16492 16620 16748 16876 17004 17132 17260 17388 17516 17644 17772 17900 18028 18156 18284 18412 18540 18668 18796 18924 19052 19180 19308 19436 19564 19692 19820 19948 20076 20204 20332 20460 20588 110 238 366 494 622 750 878 1006 1134 1262 1390 1518 1646 1774 1902 2030 2158 2286 2414 2542 2670 2798 2926 3054 3182 3310 3438 3566 3694 3822 3950 4078 4206 8302 8430 8558 8686 8814 8942 9070 9198 9326 9454 9582 9710 9838 9966 10094 10222 10350 10478 10606 10734 10862 10990 11118 11246 11374 11502 11630 11758 11886 12014 12142 12270 12398 16494 16622 16750 16878 17006 17134 17262 17390 17518 17646 17774 17902 18030 18158 18286 18414 18542 18670 18798 18926 19054 19182 19310 19438 19566 19694 19822 19950 20078 20206 20334 20462 20590 112 240 368 496 624 752 880 1008 1136 1264 1392 1520 1648 1776 1904 2032 2160 2288 2416 2544 2672 2800 2928 3056 3184 3312 3440 3568 3696 3824 3952 4080 4208 8304 8432 8560 8688 8816 8944 9072 9200 9328 9456 9584 9712 9840 9968 10096 10224 10352 10480 10608 10736 10864 10992 11120 11248 11376 11504 11632 11760 11888 12016 12144 12272 12400 16496 16624 16752 16880 17008 17136 17264 17392 17520 17648 17776 17904 18032 18160 18288 18416 18544 18672 18800 18928 19056 19184 19312 19440 19568 19696 19824 19952 20080 20208 20336 20464 20592 114 242 370 498 626 754 882 1010 1138 1266 1394 1522 1650 1778 1906 2034 2162 2290 2418 2546 2674 2802 2930 3058 3186 3314 3442 3570 3698 3826 3954 4082 4210 8306 8434 8562 8690 8818 8946 9074 9202 9330 9458 9586 9714 9842 9970 10098 10226 10354 10482 10610 10738 10866 10994 11122 11250 11378 11506 11634 11762 11890 12018 12146 12274 12402 16498 16626 16754 16882 17010 17138 17266 17394 17522 17650 17778 17906 18034 18162 18290 18418 18546 18674 18802 18930 19058 19186 19314 19442 19570 19698 19826 19954 20082 20210 20338 20466 20594 116 244 372 500 628 756 884 1012 1140 1268 1396 1524 1652 1780 1908 2036 2164 2292 2420 2548 2676 2804 2932 3060 3188 3316 3444 3572 3700 3828 3956 4084 4212 8308 8436 8564 8692 8820 8948 9076 9204 9332 9460 9588 9716 9844 9972 10100 10228 10356 10484 10612 10740 10868 10996 11124 11252 11380 11508 11636 11764 11892 12020 12148 12276 12404 16500 16628 16756 16884 17012 17140 17268 17396 17524 17652 17780 17908 18036 18164 18292 18420 18548 18676 18804 18932 19060 19188 19316 19444 19572 19700 19828 19956 20084 20212 20340 20468 20596 118 246 374 502 630 758 886 1014 1142 1270 1398 1526 1654 1782 1910 2038 2166 2294 2422 2550 2678 2806 2934 3062 3190 3318 3446 3574 3702 3830 3958 4086 4214 8310 8438 8566 8694 8822 8950 9078 9206 9334 9462 9590 9718 9846 9974 10102 10230 10358 10486 10614 10742 10870 10998 11126 11254 11382 11510 11638 11766 11894 12022 12150 12278 12406 16502 16630 16758 16886 17014 17142 17270 17398 17526 17654 17782 17910 18038 18166 18294 18422 18550 18678 18806 18934 19062 19190 19318 19446 19574 19702 19830 19958 20086 20214 20342 20470 20598 120 248 376 504 632 760 888 1016 1144 1272 1400 1528 1656 1784 1912 2040 2168 2296 2424 2552 2680 2808 2936 3064 3192 3320 3448 3576 3704 3832 3960 4088 4216 8312 8440 8568 8696 8824 8952 9080 9208 9336 9464 9592 9720 9848 9976 10104 10232 10360 10488 10616 10744 10872 11000 11128 11256 11384 11512 11640 11768 11896 12024 12152 12280 12408 16504 16632 16760 16888 17016 17144 17272 17400 17528 17656 17784 17912 18040 18168 18296 18424 18552 18680 18808 18936 19064 19192 19320 19448 19576 19704 19832 19960 20088 20216 20344 20472 20600 122 250 378 506 634 762 890 1018 1146 1274 1402 1530 1658 1786 1914 2042 2170 2298 2426 2554 2682 2810 2938 3066 3194 3322 3450 3578 3706 3834 3962 4090 4218 8314 8442 8570 8698 8826 8954 9082 9210 9338 9466 9594 9722 9850 9978 10106 10234 10362 10490 10618 10746 10874 11002 11130 11258 11386 11514 11642 11770 11898 12026 12154 12282 12410 16506 16634 16762 16890 17018 17146 17274 17402 17530 17658 17786 17914 18042 18170 18298 18426 18554 18682 18810 18938 19066 19194 19322 19450 19578 19706 19834 19962 20090 20218 20346 20474 20602 124 252 380 508 636 764 892 1020 1148 1276 1404 1532 1660 1788 1916 2044 2172 2300 2428 2556 2684 2812 2940 3068 3196 3324 3452 3580 3708 3836 3964 4092 4220 8316 8444 8572 8700 8828 8956 9084 9212 9340 9468 9596 9724 9852 9980 10108 10236 10364 10492 10620 10748 10876 11004 11132 11260 11388 11516 11644 11772 11900 12028 12156 12284 12412 16508 16636 16764 16892 17020 17148 17276 17404 17532 17660 17788 17916 18044 18172 18300 18428 18556 18684 18812 18940 19068 19196 19324 19452 19580 19708 19836 19964 20092 20220 20348 20476 20604 126 254 382 510 638 766 894 1022 1150 1278 1406 1534 1662 1790 1918 2046 2174 2302 2430 2558 2686 2814 2942 3070 3198 3326 3454 3582 3710 3838 3966 4094 4222 8318 8446 8574 8702 8830 8958 9086 9214 9342 9470 9598 9726 9854 9982 10110 10238 10366 10494 10622 10750 10878 11006 11134 11262 11390 11518 11646 11774 11902 12030 12158 12286 12414 16510 16638 16766 16894 17022 17150 17278 17406 17534 17662 17790 17918 18046 18174 18302 18430 18558 18686 18814 18942 19070 19198 19326 19454 19582 19710 19838 19966 20094 20222 20350 20478 20606 24576 24704 24832 24960 25088 25216 25344 25472 25600 25728 25856 25984 26112 26240 26368 26496 26624 26752 26880 27008 27136 27264 27392 27520 27648 27776 27904 28032 28160 28288 28416 28544 28672 32768 32896 33024 33152 33280 33408 33536 33664 33792 33920 34048 34176 34304 34432 34560 34688 34816 34944 35072 35200 35328 35456 35584 35712 35840 35968 36096 36224 36352 36480 36608 36736 36864 40960 41088 41216 41344 41472 41600 41728 41856 41984 42112 42240 42368 42496 42624 42752 42880 43008 43136 43264 43392 43520 43648 43776 43904 44032 44160 44288 44416 44544 44672 44800 44928 45056 24578 24706 24834 24962 25090 25218 25346 25474 25602 25730 25858 25986 26114 26242 26370 26498 26626 26754 26882 27010 27138 27266 27394 27522 27650 27778 27906 28034 28162 28290 28418 28546 28674 32770 32898 33026 33154 33282 33410 33538 33666 33794 33922 34050 34178 34306 34434 34562 34690 34818 34946 35074 35202 35330 35458 35586 35714 35842 35970 36098 36226 36354 36482 36610 36738 36866 40962 41090 41218 41346 41474 41602 41730 41858 41986 42114 42242 42370 42498 42626 42754 42882 43010 43138 43266 43394 43522 43650 43778 43906 44034 44162 44290 44418 44546 44674 44802 44930 45058 24580 24708 24836 24964 25092 25220 25348 25476 25604 25732 25860 25988 26116 26244 26372 26500 26628 26756 26884 27012 27140 27268 27396 27524 27652 27780 27908 28036 28164 28292 28420 28548 28676 32772 32900 33028 33156 33284 33412 33540 33668 33796 33924 34052 34180 34308 34436 34564 34692 34820 34948 35076 35204 35332 35460 35588 35716 35844 35972 36100 36228 36356 36484 36612 36740 36868 40964 41092 41220 41348 41476 41604 41732 41860 41988 42116 42244 42372 42500 42628 42756 42884 43012 43140 43268 43396 43524 43652 43780 43908 44036 44164 44292 44420 44548 44676 44804 44932 45060 24582 24710 24838 24966 25094 25222 25350 25478 25606 25734 25862 25990 26118 26246 26374 26502 26630 26758 26886 27014 27142 27270 27398 27526 27654 27782 27910 28038 28166 28294 28422 28550 28678 32774 32902 33030 33158 33286 33414 33542 33670 33798 33926 34054 34182 34310 34438 34566 34694 34822 34950 35078 35206 35334 35462 35590 35718 35846 35974 36102 36230 36358 36486 36614 36742 36870 40966 41094 41222 41350 41478 41606 41734 41862 41990 42118 42246 42374 42502 42630 42758 42886 43014 43142 43270 43398 43526 43654 43782 43910 44038 44166 44294 44422 44550 44678 44806 44934 45062 24584 24712 24840 24968 25096 25224 25352 25480 25608 25736 25864 25992 26120 26248 26376 26504 26632 26760 26888 27016 27144 27272 27400 27528 27656 27784 27912 28040 28168 28296 28424 28552 28680 32776 32904 33032 33160 33288 33416 33544 33672 33800 33928 34056 34184 34312 34440 34568 34696 34824 34952 35080 35208 35336 35464 35592 35720 35848 35976 36104 36232 36360 36488 36616 36744 36872 40968 41096 41224 41352 41480 41608 41736 41864 41992 42120 42248 42376 42504 42632 42760 42888 43016 43144 43272 43400 43528 43656 43784 43912 44040 44168 44296 44424 44552 44680 44808 44936 45064 24586 24714 24842 24970 25098 25226 25354 25482 25610 25738 25866 25994 26122 26250 26378 26506 26634 26762 26890 27018 27146 27274 27402 27530 27658 27786 27914 28042 28170 28298 28426 28554 28682 32778 32906 33034 33162 33290 33418 33546 33674 33802 33930 34058 34186 34314 34442 34570 34698 34826 34954 35082 35210 35338 35466 35594 35722 35850 35978 36106 36234 36362 36490 36618 36746 36874 40970 41098 41226 41354 41482 41610 41738 41866 41994 42122 42250 42378 42506 42634 42762 42890 43018 43146 43274 43402 43530 43658 43786 43914 44042 44170 44298 44426 44554 44682 44810 44938 45066 24588 24716 24844 24972 25100 25228 25356 25484 25612 25740 25868 25996 26124 26252 26380 26508 26636 26764 26892 27020 27148 27276 27404 27532 27660 27788 27916 28044 28172 28300 28428 28556 28684 32780 32908 33036 33164 33292 33420 33548 33676 33804 33932 34060 34188 34316 34444 34572 34700 34828 34956 35084 35212 35340 35468 35596 35724 35852 35980 36108 36236 36364 36492 36620 36748 36876 40972 41100 41228 41356 41484 41612 41740 41868 41996 42124 42252 42380 42508 42636 42764 42892 43020 43148 43276 43404 43532 43660 43788 43916 44044 44172 44300 44428 44556 44684 44812 44940 45068 24590 24718 24846 24974 25102 25230 25358 25486 25614 25742 25870 25998 26126 26254 26382 26510 26638 26766 26894 27022 27150 27278 27406 27534 27662 27790 27918 28046 28174 28302 28430 28558 28686 32782 32910 33038 33166 33294 33422 33550 33678 33806 33934 34062 34190 34318 34446 34574 34702 34830 34958 35086 35214 35342 35470 35598 35726 35854 35982 36110 36238 36366 36494 36622 36750 36878 40974 41102 41230 41358 41486 41614 41742 41870 41998 42126 42254 42382 42510 42638 42766 42894 43022 43150 43278 43406 43534 43662 43790 43918 44046 44174 44302 44430 44558 44686 44814 44942 45070 24592 24720 24848 24976 25104 25232 25360 25488 25616 25744 25872 26000 26128 26256 26384 26512 26640 26768 26896 27024 27152 27280 27408 27536 27664 27792 27920 28048 28176 28304 28432 28560 28688 32784 32912 33040 33168 33296 33424 33552 33680 33808 33936 34064 34192 34320 34448 34576 34704 34832 34960 35088 35216 35344 35472 35600 35728 35856 35984 36112 36240 36368 36496 36624 36752 36880 40976 41104 41232 41360 41488 41616 41744 41872 42000 42128 42256 42384 42512 42640 42768 42896 43024 43152 43280 43408 43536 43664 43792 43920 44048 44176 44304 44432 44560 44688 44816 44944 45072 24594 24722 24850 24978 25106 25234 25362 25490 25618 25746 25874 26002 26130 26258 26386 26514 26642 26770 26898 27026 27154 27282 27410 27538 27666 27794 27922 28050 28178 28306 28434 28562 28690 32786 32914 33042 33170 33298 33426 33554 33682 33810 33938 34066 34194 34322 34450 34578 34706 34834 34962 35090 35218 35346 35474 35602 35730 35858 35986 36114 36242 36370 36498 36626 36754 36882 40978 41106 41234 41362 41490 41618 41746 41874 42002 42130 42258 42386 42514 42642 42770 42898 43026 43154 43282 43410 43538 43666 43794 43922 44050 44178 44306 44434 44562 44690 44818 44946 45074 24596 24724 24852 24980 25108 25236 25364 25492 25620 25748 25876 26004 26132 26260 26388 26516 26644 26772 26900 27028 27156 27284 27412 27540 27668 27796 27924 28052 28180 28308 28436 28564 28692 32788 32916 33044 33172 33300 33428 33556 33684 33812 33940 34068 34196 34324 34452 34580 34708 34836 34964 35092 35220 35348 35476 35604 35732 35860 35988 36116 36244 36372 36500 36628 36756 36884 40980 41108 41236 41364 41492 41620 41748 41876 42004 42132 42260 42388 42516 42644 42772 42900 43028 43156 43284 43412 43540 43668 43796 43924 44052 44180 44308 44436 44564 44692 44820 44948 45076 24598 24726 24854 24982 25110 25238 25366 25494 25622 25750 25878 26006 26134 26262 26390 26518 26646 26774 26902 27030 27158 27286 27414 27542 27670 27798 27926 28054 28182 28310 28438 28566 28694 32790 32918 33046 33174 33302 33430 33558 33686 33814 33942 34070 34198 34326 34454 34582 34710 34838 34966 35094 35222 35350 35478 35606 35734 35862 35990 36118 36246 36374 36502 36630 36758 36886 40982 41110 41238 41366 41494 41622 41750 41878 42006 42134 42262 42390 42518 42646 42774 42902 43030 43158 43286 43414 43542 43670 43798 43926 44054 44182 44310 44438 44566 44694 44822 44950 45078 24600 24728 24856 24984 25112 25240 25368 25496 25624 25752 25880 26008 26136 26264 26392 26520 26648 26776 26904 27032 27160 27288 27416 27544 27672 27800 27928 28056 28184 28312 28440 28568 28696 32792 32920 33048 33176 33304 33432 33560 33688 33816 33944 34072 34200 34328 34456 34584 34712 34840 34968 35096 35224 35352 35480 35608 35736 35864 35992 36120 36248 36376 36504 36632 36760 36888 40984 41112 41240 41368 41496 41624 41752 41880 42008 42136 42264 42392 42520 42648 42776 42904 43032 43160 43288 43416 43544 43672 43800 43928 44056 44184 44312 44440 44568 44696 44824 44952 45080 24602 24730 24858 24986 25114 25242 25370 25498 25626 25754 25882 26010 26138 26266 26394 26522 26650 26778 26906 27034 27162 27290 27418 27546 27674 27802 27930 28058 28186 28314 28442 28570 28698 32794 32922 33050 33178 33306 33434 33562 33690 33818 33946 34074 34202 34330 34458 34586 34714 34842 34970 35098 35226 35354 35482 35610 35738 35866 35994 36122 36250 36378 36506 36634 36762 36890 40986 41114 41242 41370 41498 41626 41754 41882 42010 42138 42266 42394 42522 42650 42778 42906 43034 43162 43290 43418 43546 43674 43802 43930 44058 44186 44314 44442 44570 44698 44826 44954 45082 24604 24732 24860 24988 25116 25244 25372 25500 25628 25756 25884 26012 26140 26268 26396 26524 26652 26780 26908 27036 27164 27292 27420 27548 27676 27804 27932 28060 28188 28316 28444 28572 28700 32796 32924 33052 33180 33308 33436 33564 33692 33820 33948 34076 34204 34332 34460 34588 34716 34844 34972 35100 35228 35356 35484 35612 35740 35868 35996 36124 36252 36380 36508 36636 36764 36892 40988 41116 41244 41372 41500 41628 41756 41884 42012 42140 42268 42396 42524 42652 42780 42908 43036 43164 43292 43420 43548 43676 43804 43932 44060 44188 44316 44444 44572 44700 44828 44956 45084 24606 24734 24862 24990 25118 25246 25374 25502 25630 25758 25886 26014 26142 26270 26398 26526 26654 26782 26910 27038 27166 27294 27422 27550 27678 27806 27934 28062 28190 28318 28446 28574 28702 32798 32926 33054 33182 33310 33438 33566 33694 33822 33950 34078 34206 34334 34462 34590 34718 34846 34974 35102 35230 35358 35486 35614 35742 35870 35998 36126 36254 36382 36510 36638 36766 36894 40990 41118 41246 41374 41502 41630 41758 41886 42014 42142 42270 42398 42526 42654 42782 42910 43038 43166 43294 43422 43550 43678 43806 43934 44062 44190 44318 44446 44574 44702 44830 44958 45086 24608 24736 24864 24992 25120 25248 25376 25504 25632 25760 25888 26016 26144 26272 26400 26528 26656 26784 26912 27040 27168 27296 27424 27552 27680 27808 27936 28064 28192 28320 28448 28576 28704 32800 32928 33056 33184 33312 33440 33568 33696 33824 33952 34080 34208 34336 34464 34592 34720 34848 34976 35104 35232 35360 35488 35616 35744 35872 36000 36128 36256 36384 36512 36640 36768 36896 40992 41120 41248 41376 41504 41632 41760 41888 42016 42144 42272 42400 42528 42656 42784 42912 43040 43168 43296 43424 43552 43680 43808 43936 44064 44192 44320 44448 44576 44704 44832 44960 45088 24610 24738 24866 24994 25122 25250 25378 25506 25634 25762 25890 26018 26146 26274 26402 26530 26658 26786 26914 27042 27170 27298 27426 27554 27682 27810 27938 28066 28194 28322 28450 28578 28706 32802 32930 33058 33186 33314 33442 33570 33698 33826 33954 34082 34210 34338 34466 34594 34722 34850 34978 35106 35234 35362 35490 35618 35746 35874 36002 36130 36258 36386 36514 36642 36770 36898 40994 41122 41250 41378 41506 41634 41762 41890 42018 42146 42274 42402 42530 42658 42786 42914 43042 43170 43298 43426 43554 43682 43810 43938 44066 44194 44322 44450 44578 44706 44834 44962 45090 24612 24740 24868 24996 25124 25252 25380 25508 25636 25764 25892 26020 26148 26276 26404 26532 26660 26788 26916 27044 27172 27300 27428 27556 27684 27812 27940 28068 28196 28324 28452 28580 28708 32804 32932 33060 33188 33316 33444 33572 33700 33828 33956 34084 34212 34340 34468 34596 34724 34852 34980 35108 35236 35364 35492 35620 35748 35876 36004 36132 36260 36388 36516 36644 36772 36900 40996 41124 41252 41380 41508 41636 41764 41892 42020 42148 42276 42404 42532 42660 42788 42916 43044 43172 43300 43428 43556 43684 43812 43940 44068 44196 44324 44452 44580 44708 44836 44964 45092 24614 24742 24870 24998 25126 25254 25382 25510 25638 25766 25894 26022 26150 26278 26406 26534 26662 26790 26918 27046 27174 27302 27430 27558 27686 27814 27942 28070 28198 28326 28454 28582 28710 32806 32934 33062 33190 33318 33446 33574 33702 33830 33958 34086 34214 34342 34470 34598 34726 34854 34982 35110 35238 35366 35494 35622 35750 35878 36006 36134 36262 36390 36518 36646 36774 36902 40998 41126 41254 41382 41510 41638 41766 41894 42022 42150 42278 42406 42534 42662 42790 42918 43046 43174 43302 43430 43558 43686 43814 43942 44070 44198 44326 44454 44582 44710 44838 44966 45094 24616 24744 24872 25000 25128 25256 25384 25512 25640 25768 25896 26024 26152 26280 26408 26536 26664 26792 26920 27048 27176 27304 27432 27560 27688 27816 27944 28072 28200 28328 28456 28584 28712 32808 32936 33064 33192 33320 33448 33576 33704 33832 33960 34088 34216 34344 34472 34600 34728 34856 34984 35112 35240 35368 35496 35624 35752 35880 36008 36136 36264 36392 36520 36648 36776 36904 41000 41128 41256 41384 41512 41640 41768 41896 42024 42152 42280 42408 42536 42664 42792 42920 43048 43176 43304 43432 43560 43688 43816 43944 44072 44200 44328 44456 44584 44712 44840 44968 45096 24618 24746 24874 25002 25130 25258 25386 25514 25642 25770 25898 26026 26154 26282 26410 26538 26666 26794 26922 27050 27178 27306 27434 27562 27690 27818 27946 28074 28202 28330 28458 28586 28714 32810 32938 33066 33194 33322 33450 33578 33706 33834 33962 34090 34218 34346 34474 34602 34730 34858 34986 35114 35242 35370 35498 35626 35754 35882 36010 36138 36266 36394 36522 36650 36778 36906 41002 41130 41258 41386 41514 41642 41770 41898 42026 42154 42282 42410 42538 42666 42794 42922 43050 43178 43306 43434 43562 43690 43818 43946 44074 44202 44330 44458 44586 44714 44842 44970 45098 24620 24748 24876 25004 25132 25260 25388 25516 25644 25772 25900 26028 26156 26284 26412 26540 26668 26796 26924 27052 27180 27308 27436 27564 27692 27820 27948 28076 28204 28332 28460 28588 28716 32812 32940 33068 33196 33324 33452 33580 33708 33836 33964 34092 34220 34348 34476 34604 34732 34860 34988 35116 35244 35372 35500 35628 35756 35884 36012 36140 36268 36396 36524 36652 36780 36908 41004 41132 41260 41388 41516 41644 41772 41900 42028 42156 42284 42412 42540 42668 42796 42924 43052 43180 43308 43436 43564 43692 43820 43948 44076 44204 44332 44460 44588 44716 44844 44972 45100 24622 24750 24878 25006 25134 25262 25390 25518 25646 25774 25902 26030 26158 26286 26414 26542 26670 26798 26926 27054 27182 27310 27438 27566 27694 27822 27950 28078 28206 28334 28462 28590 28718 32814 32942 33070 33198 33326 33454 33582 33710 33838 33966 34094 34222 34350 34478 34606 34734 34862 34990 35118 35246 35374 35502 35630 35758 35886 36014 36142 36270 36398 36526 36654 36782 36910 41006 41134 41262 41390 41518 41646 41774 41902 42030 42158 42286 42414 42542 42670 42798 42926 43054 43182 43310 43438 43566 43694 43822 43950 44078 44206 44334 44462 44590 44718 44846 44974 45102 24624 24752 24880 25008 25136 25264 25392 25520 25648 25776 25904 26032 26160 26288 26416 26544 26672 26800 26928 27056 27184 27312 27440 27568 27696 27824 27952 28080 28208 28336 28464 28592 28720 32816 32944 33072 33200 33328 33456 33584 33712 33840 33968 34096 34224 34352 34480 34608 34736 34864 34992 35120 35248 35376 35504 35632 35760 35888 36016 36144 36272 36400 36528 36656 36784 36912 41008 41136 41264 41392 41520 41648 41776 41904 42032 42160 42288 42416 42544 42672 42800 42928 43056 43184 43312 43440 43568 43696 43824 43952 44080 44208 44336 44464 44592 44720 44848 44976 45104 24626 24754 24882 25010 25138 25266 25394 25522 25650 25778 25906 26034 26162 26290 26418 26546 26674 26802 26930 27058 27186 27314 27442 27570 27698 27826 27954 28082 28210 28338 28466 28594 28722 32818 32946 33074 33202 33330 33458 33586 33714 33842 33970 34098 34226 34354 34482 34610 34738 34866 34994 35122 35250 35378 35506 35634 35762 35890 36018 36146 36274 36402 36530 36658 36786 36914 41010 41138 41266 41394 41522 41650 41778 41906 42034 42162 42290 42418 42546 42674 42802 42930 43058 43186 43314 43442 43570 43698 43826 43954 44082 44210 44338 44466 44594 44722 44850 44978 45106 24628 24756 24884 25012 25140 25268 25396 25524 25652 25780 25908 26036 26164 26292 26420 26548 26676 26804 26932 27060 27188 27316 27444 27572 27700 27828 27956 28084 28212 28340 28468 28596 28724 32820 32948 33076 33204 33332 33460 33588 33716 33844 33972 34100 34228 34356 34484 34612 34740 34868 34996 35124 35252 35380 35508 35636 35764 35892 36020 36148 36276 36404 36532 36660 36788 36916 41012 41140 41268 41396 41524 41652 41780 41908 42036 42164 42292 42420 42548 42676 42804 42932 43060 43188 43316 43444 43572 43700 43828 43956 44084 44212 44340 44468 44596 44724 44852 44980 45108 24630 24758 24886 25014 25142 25270 25398 25526 25654 25782 25910 26038 26166 26294 26422 26550 26678 26806 26934 27062 27190 27318 27446 27574 27702 27830 27958 28086 28214 28342 28470 28598 28726 32822 32950 33078 33206 33334 33462 33590 33718 33846 33974 34102 34230 34358 34486 34614 34742 34870 34998 35126 35254 35382 35510 35638 35766 35894 36022 36150 36278 36406 36534 36662 36790 36918 41014 41142 41270 41398 41526 41654 41782 41910 42038 42166 42294 42422 42550 42678 42806 42934 43062 43190 43318 43446 43574 43702 43830 43958 44086 44214 44342 44470 44598 44726 44854 44982 45110 24632 24760 24888 25016 25144 25272 25400 25528 25656 25784 25912 26040 26168 26296 26424 26552 26680 26808 26936 27064 27192 27320 27448 27576 27704 27832 27960 28088 28216 28344 28472 28600 28728 32824 32952 33080 33208 33336 33464 33592 33720 33848 33976 34104 34232 34360 34488 34616 34744 34872 35000 35128 35256 35384 35512 35640 35768 35896 36024 36152 36280 36408 36536 36664 36792 36920 41016 41144 41272 41400 41528 41656 41784 41912 42040 42168 42296 42424 42552 42680 42808 42936 43064 43192 43320 43448 43576 43704 43832 43960 44088 44216 44344 44472 44600 44728 44856 44984 45112 24634 24762 24890 25018 25146 25274 25402 25530 25658 25786 25914 26042 26170 26298 26426 26554 26682 26810 26938 27066 27194 27322 27450 27578 27706 27834 27962 28090 28218 28346 28474 28602 28730 32826 32954 33082 33210 33338 33466 33594 33722 33850 33978 34106 34234 34362 34490 34618 34746 34874 35002 35130 35258 35386 35514 35642 35770 35898 36026 36154 36282 36410 36538 36666 36794 36922 41018 41146 41274 41402 41530 41658 41786 41914 42042 42170 42298 42426 42554 42682 42810 42938 43066 43194 43322 43450 43578 43706 43834 43962 44090 44218 44346 44474 44602 44730 44858 44986 45114 24636 24764 24892 25020 25148 25276 25404 25532 25660 25788 25916 26044 26172 26300 26428 26556 26684 26812 26940 27068 27196 27324 27452 27580 27708 27836 27964 28092 28220 28348 28476 28604 28732 32828 32956 33084 33212 33340 33468 33596 33724 33852 33980 34108 34236 34364 34492 34620 34748 34876 35004 35132 35260 35388 35516 35644 35772 35900 36028 36156 36284 36412 36540 36668 36796 36924 41020 41148 41276 41404 41532 41660 41788 41916 42044 42172 42300 42428 42556 42684 42812 42940 43068 43196 43324 43452 43580 43708 43836 43964 44092 44220 44348 44476 44604 44732 44860 44988 45116 24638 24766 24894 25022 25150 25278 25406 25534 25662 25790 25918 26046 26174 26302 26430 26558 26686 26814 26942 27070 27198 27326 27454 27582 27710 27838 27966 28094 28222 28350 28478 28606 28734 32830 32958 33086 33214 33342 33470 33598 33726 33854 33982 34110 34238 34366 34494 34622 34750 34878 35006 35134 35262 35390 35518 35646 35774 35902 36030 36158 36286 36414 36542 36670 36798 36926 41022 41150 41278 41406 41534 41662 41790 41918 42046 42174 42302 42430 42558 42686 42814 42942 43070 43198 43326 43454 43582 43710 43838 43966 44094 44222 44350 44478 44606 44734 44862 44990 45118 24640 24768 24896 25024 25152 25280 25408 25536 25664 25792 25920 26048 26176 26304 26432 26560 26688 26816 26944 27072 27200 27328 27456 27584 27712 27840 27968 28096 28224 28352 28480 28608 28736 32832 32960 33088 33216 33344 33472 33600 33728 33856 33984 34112 34240 34368 34496 34624 34752 34880 35008 35136 35264 35392 35520 35648 35776 35904 36032 36160 36288 36416 36544 36672 36800 36928 41024 41152 41280 41408 41536 41664 41792 41920 42048 42176 42304 42432 42560 42688 42816 42944 43072 43200 43328 43456 43584 43712 43840 43968 44096 44224 44352 44480 44608 44736 44864 44992 45120 24642 24770 24898 25026 25154 25282 25410 25538 25666 25794 25922 26050 26178 26306 26434 26562 26690 26818 26946 27074 27202 27330 27458 27586 27714 27842 27970 28098 28226 28354 28482 28610 28738 32834 32962 33090 33218 33346 33474 33602 33730 33858 33986 34114 34242 34370 34498 34626 34754 34882 35010 35138 35266 35394 35522 35650 35778 35906 36034 36162 36290 36418 36546 36674 36802 36930 41026 41154 41282 41410 41538 41666 41794 41922 42050 42178 42306 42434 42562 42690 42818 42946 43074 43202 43330 43458 43586 43714 43842 43970 44098 44226 44354 44482 44610 44738 44866 44994 45122 24644 24772 24900 25028 25156 25284 25412 25540 25668 25796 25924 26052 26180 26308 26436 26564 26692 26820 26948 27076 27204 27332 27460 27588 27716 27844 27972 28100 28228 28356 28484 28612 28740 32836 32964 33092 33220 33348 33476 33604 33732 33860 33988 34116 34244 34372 34500 34628 34756 34884 35012 35140 35268 35396 35524 35652 35780 35908 36036 36164 36292 36420 36548 36676 36804 36932 41028 41156 41284 41412 41540 41668 41796 41924 42052 42180 42308 42436 42564 42692 42820 42948 43076 43204 43332 43460 43588 43716 43844 43972 44100 44228 44356 44484 44612 44740 44868 44996 45124 24646 24774 24902 25030 25158 25286 25414 25542 25670 25798 25926 26054 26182 26310 26438 26566 26694 26822 26950 27078 27206 27334 27462 27590 27718 27846 27974 28102 28230 28358 28486 28614 28742 32838 32966 33094 33222 33350 33478 33606 33734 33862 33990 34118 34246 34374 34502 34630 34758 34886 35014 35142 35270 35398 35526 35654 35782 35910 36038 36166 36294 36422 36550 36678 36806 36934 41030 41158 41286 41414 41542 41670 41798 41926 42054 42182 42310 42438 42566 42694 42822 42950 43078 43206 43334 43462 43590 43718 43846 43974 44102 44230 44358 44486 44614 44742 44870 44998 45126 24648 24776 24904 25032 25160 25288 25416 25544 25672 25800 25928 26056 26184 26312 26440 26568 26696 26824 26952 27080 27208 27336 27464 27592 27720 27848 27976 28104 28232 28360 28488 28616 28744 32840 32968 33096 33224 33352 33480 33608 33736 33864 33992 34120 34248 34376 34504 34632 34760 34888 35016 35144 35272 35400 35528 35656 35784 35912 36040 36168 36296 36424 36552 36680 36808 36936 41032 41160 41288 41416 41544 41672 41800 41928 42056 42184 42312 42440 42568 42696 42824 42952 43080 43208 43336 43464 43592 43720 43848 43976 44104 44232 44360 44488 44616 44744 44872 45000 45128 24650 24778 24906 25034 25162 25290 25418 25546 25674 25802 25930 26058 26186 26314 26442 26570 26698 26826 26954 27082 27210 27338 27466 27594 27722 27850 27978 28106 28234 28362 28490 28618 28746 32842 32970 33098 33226 33354 33482 33610 33738 33866 33994 34122 34250 34378 34506 34634 34762 34890 35018 35146 35274 35402 35530 35658 35786 35914 36042 36170 36298 36426 36554 36682 36810 36938 41034 41162 41290 41418 41546 41674 41802 41930 42058 42186 42314 42442 42570 42698 42826 42954 43082 43210 43338 43466 43594 43722 43850 43978 44106 44234 44362 44490 44618 44746 44874 45002 45130 24652 24780 24908 25036 25164 25292 25420 25548 25676 25804 25932 26060 26188 26316 26444 26572 26700 26828 26956 27084 27212 27340 27468 27596 27724 27852 27980 28108 28236 28364 28492 28620 28748 32844 32972 33100 33228 33356 33484 33612 33740 33868 33996 34124 34252 34380 34508 34636 34764 34892 35020 35148 35276 35404 35532 35660 35788 35916 36044 36172 36300 36428 36556 36684 36812 36940 41036 41164 41292 41420 41548 41676 41804 41932 42060 42188 42316 42444 42572 42700 42828 42956 43084 43212 43340 43468 43596 43724 43852 43980 44108 44236 44364 44492 44620 44748 44876 45004 45132 24654 24782 24910 25038 25166 25294 25422 25550 25678 25806 25934 26062 26190 26318 26446 26574 26702 26830 26958 27086 27214 27342 27470 27598 27726 27854 27982 28110 28238 28366 28494 28622 28750 32846 32974 33102 33230 33358 33486 33614 33742 33870 33998 34126 34254 34382 34510 34638 34766 34894 35022 35150 35278 35406 35534 35662 35790 35918 36046 36174 36302 36430 36558 36686 36814 36942 41038 41166 41294 41422 41550 41678 41806 41934 42062 42190 42318 42446 42574 42702 42830 42958 43086 43214 43342 43470 43598 43726 43854 43982 44110 44238 44366 44494 44622 44750 44878 45006 45134 24656 24784 24912 25040 25168 25296 25424 25552 25680 25808 25936 26064 26192 26320 26448 26576 26704 26832 26960 27088 27216 27344 27472 27600 27728 27856 27984 28112 28240 28368 28496 28624 28752 32848 32976 33104 33232 33360 33488 33616 33744 33872 34000 34128 34256 34384 34512 34640 34768 34896 35024 35152 35280 35408 35536 35664 35792 35920 36048 36176 36304 36432 36560 36688 36816 36944 41040 41168 41296 41424 41552 41680 41808 41936 42064 42192 42320 42448 42576 42704 42832 42960 43088 43216 43344 43472 43600 43728 43856 43984 44112 44240 44368 44496 44624 44752 44880 45008 45136 24658 24786 24914 25042 25170 25298 25426 25554 25682 25810 25938 26066 26194 26322 26450 26578 26706 26834 26962 27090 27218 27346 27474 27602 27730 27858 27986 28114 28242 28370 28498 28626 28754 32850 32978 33106 33234 33362 33490 33618 33746 33874 34002 34130 34258 34386 34514 34642 34770 34898 35026 35154 35282 35410 35538 35666 35794 35922 36050 36178 36306 36434 36562 36690 36818 36946 41042 41170 41298 41426 41554 41682 41810 41938 42066 42194 42322 42450 42578 42706 42834 42962 43090 43218 43346 43474 43602 43730 43858 43986 44114 44242 44370 44498 44626 44754 44882 45010 45138 24660 24788 24916 25044 25172 25300 25428 25556 25684 25812 25940 26068 26196 26324 26452 26580 26708 26836 26964 27092 27220 27348 27476 27604 27732 27860 27988 28116 28244 28372 28500 28628 28756 32852 32980 33108 33236 33364 33492 33620 33748 33876 34004 34132 34260 34388 34516 34644 34772 34900 35028 35156 35284 35412 35540 35668 35796 35924 36052 36180 36308 36436 36564 36692 36820 36948 41044 41172 41300 41428 41556 41684 41812 41940 42068 42196 42324 42452 42580 42708 42836 42964 43092 43220 43348 43476 43604 43732 43860 43988 44116 44244 44372 44500 44628 44756 44884 45012 45140 24662 24790 24918 25046 25174 25302 25430 25558 25686 25814 25942 26070 26198 26326 26454 26582 26710 26838 26966 27094 27222 27350 27478 27606 27734 27862 27990 28118 28246 28374 28502 28630 28758 32854 32982 33110 33238 33366 33494 33622 33750 33878 34006 34134 34262 34390 34518 34646 34774 34902 35030 35158 35286 35414 35542 35670 35798 35926 36054 36182 36310 36438 36566 36694 36822 36950 41046 41174 41302 41430 41558 41686 41814 41942 42070 42198 42326 42454 42582 42710 42838 42966 43094 43222 43350 43478 43606 43734 43862 43990 44118 44246 44374 44502 44630 44758 44886 45014 45142 24664 24792 24920 25048 25176 25304 25432 25560 25688 25816 25944 26072 26200 26328 26456 26584 26712 26840 26968 27096 27224 27352 27480 27608 27736 27864 27992 28120 28248 28376 28504 28632 28760 32856 32984 33112 33240 33368 33496 33624 33752 33880 34008 34136 34264 34392 34520 34648 34776 34904 35032 35160 35288 35416 35544 35672 35800 35928 36056 36184 36312 36440 36568 36696 36824 36952 41048 41176 41304 41432 41560 41688 41816 41944 42072 42200 42328 42456 42584 42712 42840 42968 43096 43224 43352 43480 43608 43736 43864 43992 44120 44248 44376 44504 44632 44760 44888 45016 45144 24666 24794 24922 25050 25178 25306 25434 25562 25690 25818 25946 26074 26202 26330 26458 26586 26714 26842 26970 27098 27226 27354 27482 27610 27738 27866 27994 28122 28250 28378 28506 28634 28762 32858 32986 33114 33242 33370 33498 33626 33754 33882 34010 34138 34266 34394 34522 34650 34778 34906 35034 35162 35290 35418 35546 35674 35802 35930 36058 36186 36314 36442 36570 36698 36826 36954 41050 41178 41306 41434 41562 41690 41818 41946 42074 42202 42330 42458 42586 42714 42842 42970 43098 43226 43354 43482 43610 43738 43866 43994 44122 44250 44378 44506 44634 44762 44890 45018 45146 24668 24796 24924 25052 25180 25308 25436 25564 25692 25820 25948 26076 26204 26332 26460 26588 26716 26844 26972 27100 27228 27356 27484 27612 27740 27868 27996 28124 28252 28380 28508 28636 28764 32860 32988 33116 33244 33372 33500 33628 33756 33884 34012 34140 34268 34396 34524 34652 34780 34908 35036 35164 35292 35420 35548 35676 35804 35932 36060 36188 36316 36444 36572 36700 36828 36956 41052 41180 41308 41436 41564 41692 41820 41948 42076 42204 42332 42460 42588 42716 42844 42972 43100 43228 43356 43484 43612 43740 43868 43996 44124 44252 44380 44508 44636 44764 44892 45020 45148 24670 24798 24926 25054 25182 25310 25438 25566 25694 25822 25950 26078 26206 26334 26462 26590 26718 26846 26974 27102 27230 27358 27486 27614 27742 27870 27998 28126 28254 28382 28510 28638 28766 32862 32990 33118 33246 33374 33502 33630 33758 33886 34014 34142 34270 34398 34526 34654 34782 34910 35038 35166 35294 35422 35550 35678 35806 35934 36062 36190 36318 36446 36574 36702 36830 36958 41054 41182 41310 41438 41566 41694 41822 41950 42078 42206 42334 42462 42590 42718 42846 42974 43102 43230 43358 43486 43614 43742 43870 43998 44126 44254 44382 44510 44638 44766 44894 45022 45150 24672 24800 24928 25056 25184 25312 25440 25568 25696 25824 25952 26080 26208 26336 26464 26592 26720 26848 26976 27104 27232 27360 27488 27616 27744 27872 28000 28128 28256 28384 28512 28640 28768 32864 32992 33120 33248 33376 33504 33632 33760 33888 34016 34144 34272 34400 34528 34656 34784 34912 35040 35168 35296 35424 35552 35680 35808 35936 36064 36192 36320 36448 36576 36704 36832 36960 41056 41184 41312 41440 41568 41696 41824 41952 42080 42208 42336 42464 42592 42720 42848 42976 43104 43232 43360 43488 43616 43744 43872 44000 44128 44256 44384 44512 44640 44768 44896 45024 45152 24674 24802 24930 25058 25186 25314 25442 25570 25698 25826 25954 26082 26210 26338 26466 26594 26722 26850 26978 27106 27234 27362 27490 27618 27746 27874 28002 28130 28258 28386 28514 28642 28770 32866 32994 33122 33250 33378 33506 33634 33762 33890 34018 34146 34274 34402 34530 34658 34786 34914 35042 35170 35298 35426 35554 35682 35810 35938 36066 36194 36322 36450 36578 36706 36834 36962 41058 41186 41314 41442 41570 41698 41826 41954 42082 42210 42338 42466 42594 42722 42850 42978 43106 43234 43362 43490 43618 43746 43874 44002 44130 44258 44386 44514 44642 44770 44898 45026 45154 24676 24804 24932 25060 25188 25316 25444 25572 25700 25828 25956 26084 26212 26340 26468 26596 26724 26852 26980 27108 27236 27364 27492 27620 27748 27876 28004 28132 28260 28388 28516 28644 28772 32868 32996 33124 33252 33380 33508 33636 33764 33892 34020 34148 34276 34404 34532 34660 34788 34916 35044 35172 35300 35428 35556 35684 35812 35940 36068 36196 36324 36452 36580 36708 36836 36964 41060 41188 41316 41444 41572 41700 41828 41956 42084 42212 42340 42468 42596 42724 42852 42980 43108 43236 43364 43492 43620 43748 43876 44004 44132 44260 44388 44516 44644 44772 44900 45028 45156 24678 24806 24934 25062 25190 25318 25446 25574 25702 25830 25958 26086 26214 26342 26470 26598 26726 26854 26982 27110 27238 27366 27494 27622 27750 27878 28006 28134 28262 28390 28518 28646 28774 32870 32998 33126 33254 33382 33510 33638 33766 33894 34022 34150 34278 34406 34534 34662 34790 34918 35046 35174 35302 35430 35558 35686 35814 35942 36070 36198 36326 36454 36582 36710 36838 36966 41062 41190 41318 41446 41574 41702 41830 41958 42086 42214 42342 42470 42598 42726 42854 42982 43110 43238 43366 43494 43622 43750 43878 44006 44134 44262 44390 44518 44646 44774 44902 45030 45158 24680 24808 24936 25064 25192 25320 25448 25576 25704 25832 25960 26088 26216 26344 26472 26600 26728 26856 26984 27112 27240 27368 27496 27624 27752 27880 28008 28136 28264 28392 28520 28648 28776 32872 33000 33128 33256 33384 33512 33640 33768 33896 34024 34152 34280 34408 34536 34664 34792 34920 35048 35176 35304 35432 35560 35688 35816 35944 36072 36200 36328 36456 36584 36712 36840 36968 41064 41192 41320 41448 41576 41704 41832 41960 42088 42216 42344 42472 42600 42728 42856 42984 43112 43240 43368 43496 43624 43752 43880 44008 44136 44264 44392 44520 44648 44776 44904 45032 45160 24682 24810 24938 25066 25194 25322 25450 25578 25706 25834 25962 26090 26218 26346 26474 26602 26730 26858 26986 27114 27242 27370 27498 27626 27754 27882 28010 28138 28266 28394 28522 28650 28778 32874 33002 33130 33258 33386 33514 33642 33770 33898 34026 34154 34282 34410 34538 34666 34794 34922 35050 35178 35306 35434 35562 35690 35818 35946 36074 36202 36330 36458 36586 36714 36842 36970 41066 41194 41322 41450 41578 41706 41834 41962 42090 42218 42346 42474 42602 42730 42858 42986 43114 43242 43370 43498 43626 43754 43882 44010 44138 44266 44394 44522 44650 44778 44906 45034 45162 24684 24812 24940 25068 25196 25324 25452 25580 25708 25836 25964 26092 26220 26348 26476 26604 26732 26860 26988 27116 27244 27372 27500 27628 27756 27884 28012 28140 28268 28396 28524 28652 28780 32876 33004 33132 33260 33388 33516 33644 33772 33900 34028 34156 34284 34412 34540 34668 34796 34924 35052 35180 35308 35436 35564 35692 35820 35948 36076 36204 36332 36460 36588 36716 36844 36972 41068 41196 41324 41452 41580 41708 41836 41964 42092 42220 42348 42476 42604 42732 42860 42988 43116 43244 43372 43500 43628 43756 43884 44012 44140 44268 44396 44524 44652 44780 44908 45036 45164 24686 24814 24942 25070 25198 25326 25454 25582 25710 25838 25966 26094 26222 26350 26478 26606 26734 26862 26990 27118 27246 27374 27502 27630 27758 27886 28014 28142 28270 28398 28526 28654 28782 32878 33006 33134 33262 33390 33518 33646 33774 33902 34030 34158 34286 34414 34542 34670 34798 34926 35054 35182 35310 35438 35566 35694 35822 35950 36078 36206 36334 36462 36590 36718 36846 36974 41070 41198 41326 41454 41582 41710 41838 41966 42094 42222 42350 42478 42606 42734 42862 42990 43118 43246 43374 43502 43630 43758 43886 44014 44142 44270 44398 44526 44654 44782 44910 45038 45166 24688 24816 24944 25072 25200 25328 25456 25584 25712 25840 25968 26096 26224 26352 26480 26608 26736 26864 26992 27120 27248 27376 27504 27632 27760 27888 28016 28144 28272 28400 28528 28656 28784 32880 33008 33136 33264 33392 33520 33648 33776 33904 34032 34160 34288 34416 34544 34672 34800 34928 35056 35184 35312 35440 35568 35696 35824 35952 36080 36208 36336 36464 36592 36720 36848 36976 41072 41200 41328 41456 41584 41712 41840 41968 42096 42224 42352 42480 42608 42736 42864 42992 43120 43248 43376 43504 43632 43760 43888 44016 44144 44272 44400 44528 44656 44784 44912 45040 45168 24690 24818 24946 25074 25202 25330 25458 25586 25714 25842 25970 26098 26226 26354 26482 26610 26738 26866 26994 27122 27250 27378 27506 27634 27762 27890 28018 28146 28274 28402 28530 28658 28786 32882 33010 33138 33266 33394 33522 33650 33778 33906 34034 34162 34290 34418 34546 34674 34802 34930 35058 35186 35314 35442 35570 35698 35826 35954 36082 36210 36338 36466 36594 36722 36850 36978 41074 41202 41330 41458 41586 41714 41842 41970 42098 42226 42354 42482 42610 42738 42866 42994 43122 43250 43378 43506 43634 43762 43890 44018 44146 44274 44402 44530 44658 44786 44914 45042 45170 24692 24820 24948 25076 25204 25332 25460 25588 25716 25844 25972 26100 26228 26356 26484 26612 26740 26868 26996 27124 27252 27380 27508 27636 27764 27892 28020 28148 28276 28404 28532 28660 28788 32884 33012 33140 33268 33396 33524 33652 33780 33908 34036 34164 34292 34420 34548 34676 34804 34932 35060 35188 35316 35444 35572 35700 35828 35956 36084 36212 36340 36468 36596 36724 36852 36980 41076 41204 41332 41460 41588 41716 41844 41972 42100 42228 42356 42484 42612 42740 42868 42996 43124 43252 43380 43508 43636 43764 43892 44020 44148 44276 44404 44532 44660 44788 44916 45044 45172 24694 24822 24950 25078 25206 25334 25462 25590 25718 25846 25974 26102 26230 26358 26486 26614 26742 26870 26998 27126 27254 27382 27510 27638 27766 27894 28022 28150 28278 28406 28534 28662 28790 32886 33014 33142 33270 33398 33526 33654 33782 33910 34038 34166 34294 34422 34550 34678 34806 34934 35062 35190 35318 35446 35574 35702 35830 35958 36086 36214 36342 36470 36598 36726 36854 36982 41078 41206 41334 41462 41590 41718 41846 41974 42102 42230 42358 42486 42614 42742 42870 42998 43126 43254 43382 43510 43638 43766 43894 44022 44150 44278 44406 44534 44662 44790 44918 45046 45174 24696 24824 24952 25080 25208 25336 25464 25592 25720 25848 25976 26104 26232 26360 26488 26616 26744 26872 27000 27128 27256 27384 27512 27640 27768 27896 28024 28152 28280 28408 28536 28664 28792 32888 33016 33144 33272 33400 33528 33656 33784 33912 34040 34168 34296 34424 34552 34680 34808 34936 35064 35192 35320 35448 35576 35704 35832 35960 36088 36216 36344 36472 36600 36728 36856 36984 41080 41208 41336 41464 41592 41720 41848 41976 42104 42232 42360 42488 42616 42744 42872 43000 43128 43256 43384 43512 43640 43768 43896 44024 44152 44280 44408 44536 44664 44792 44920 45048 45176 24698 24826 24954 25082 25210 25338 25466 25594 25722 25850 25978 26106 26234 26362 26490 26618 26746 26874 27002 27130 27258 27386 27514 27642 27770 27898 28026 28154 28282 28410 28538 28666 28794 32890 33018 33146 33274 33402 33530 33658 33786 33914 34042 34170 34298 34426 34554 34682 34810 34938 35066 35194 35322 35450 35578 35706 35834 35962 36090 36218 36346 36474 36602 36730 36858 36986 41082 41210 41338 41466 41594 41722 41850 41978 42106 42234 42362 42490 42618 42746 42874 43002 43130 43258 43386 43514 43642 43770 43898 44026 44154 44282 44410 44538 44666 44794 44922 45050 45178 24700 24828 24956 25084 25212 25340 25468 25596 25724 25852 25980 26108 26236 26364 26492 26620 26748 26876 27004 27132 27260 27388 27516 27644 27772 27900 28028 28156 28284 28412 28540 28668 28796 32892 33020 33148 33276 33404 33532 33660 33788 33916 34044 34172 34300 34428 34556 34684 34812 34940 35068 35196 35324 35452 35580 35708 35836 35964 36092 36220 36348 36476 36604 36732 36860 36988 41084 41212 41340 41468 41596 41724 41852 41980 42108 42236 42364 42492 42620 42748 42876 43004 43132 43260 43388 43516 43644 43772 43900 44028 44156 44284 44412 44540 44668 44796 44924 45052 45180 24702 24830 24958 25086 25214 25342 25470 25598 25726 25854 25982 26110 26238 26366 26494 26622 26750 26878 27006 27134 27262 27390 27518 27646 27774 27902 28030 28158 28286 28414 28542 28670 28798 32894 33022 33150 33278 33406 33534 33662 33790 33918 34046 34174 34302 34430 34558 34686 34814 34942 35070 35198 35326 35454 35582 35710 35838 35966 36094 36222 36350 36478 36606 36734 36862 36990 41086 41214 41342 41470 41598 41726 41854 41982 42110 42238 42366 42494 42622 42750 42878 43006 43134 43262 43390 43518 43646 43774 43902 44030 44158 44286 44414 44542 44670 44798 44926 45054 45182 49152 49280 49408 49536 49664 49792 49920 50048 50176 50304 50432 50560 50688 50816 50944 51072 51200 51328 51456 51584 51712 51840 51968 52096 52224 52352 52480 52608 52736 52864 52992 53120 53248 57344 57472 57600 57728 57856 57984 58112 58240 58368 58496 58624 58752 58880 59008 59136 59264 59392 59520 59648 59776 59904 60032 60160 60288 60416 60544 60672 60800 60928 61056 61184 61312 61440 65536 65664 65792 65920 66048 66176 66304 66432 66560 66688 66816 66944 67072 67200 67328 67456 67584 67712 67840 67968 68096 68224 68352 68480 68608 68736 68864 68992 69120 69248 69376 69504 69632 73728 73856 73984 74112 74240 74368 74496 74624 74752 74880 75008 75136 75264 75392 75520 75648 75776 75904 76032 76160 76288 76416 76544 76672 76800 76928 77056 77184 77312 77440 77568 77696 77824 81920 82048 82176 82304 82432 82560 82688 82816 82944 83072 83200 83328 83456 83584 83712 83840 83968 84096 84224 84352 84480 84608 84736 84864 84992 85120 85248 85376 85504 85632 85760 85888 86016 90112 90240 90368 90496 90624 90752 90880 91008 91136 91264 91392 91520 91648 91776 91904 92032 92160 92288 92416 92544 92672 92800 92928 93056 93184 93312 93440 93568 93696 93824 93952 94080 94208 73730 73858 73986 74114 74242 74370 74498 74626 74754 74882 75010 75138 75266 75394 75522 75650 75778 75906 76034 76162 76290 76418 76546 76674 76802 76930 77058 77186 77314 77442 77570 77698 77826 81922 82050 82178 82306 82434 82562 82690 82818 82946 83074 83202 83330 83458 83586 83714 83842 83970 84098 84226 84354 84482 84610 84738 84866 84994 85122 85250 85378 85506 85634 85762 85890 86018 90114 90242 90370 90498 90626 90754 90882 91010 91138 91266 91394 91522 91650 91778 91906 92034 92162 92290 92418 92546 92674 92802 92930 93058 93186 93314 93442 93570 93698 93826 93954 94082 94210 73732 73860 73988 74116 74244 74372 74500 74628 74756 74884 75012 75140 75268 75396 75524 75652 75780 75908 76036 76164 76292 76420 76548 76676 76804 76932 77060 77188 77316 77444 77572 77700 77828 81924 82052 82180 82308 82436 82564 82692 82820 82948 83076 83204 83332 83460 83588 83716 83844 83972 84100 84228 84356 84484 84612 84740 84868 84996 85124 85252 85380 85508 85636 85764 85892 86020 90116 90244 90372 90500 90628 90756 90884 91012 91140 91268 91396 91524 91652 91780 91908 92036 92164 92292 92420 92548 92676 92804 92932 93060 93188 93316 93444 93572 93700 93828 93956 94084 94212 73734 73862 73990 74118 74246 74374 74502 74630 74758 74886 75014 75142 75270 75398 75526 75654 75782 75910 76038 76166 76294 76422 76550 76678 76806 76934 77062 77190 77318 77446 77574 77702 77830 81926 82054 82182 82310 82438 82566 82694 82822 82950 83078 83206 83334 83462 83590 83718 83846 83974 84102 84230 84358 84486 84614 84742 84870 84998 85126 85254 85382 85510 85638 85766 85894 86022 90118 90246 90374 90502 90630 90758 90886 91014 91142 91270 91398 91526 91654 91782 91910 92038 92166 92294 92422 92550 92678 92806 92934 93062 93190 93318 93446 93574 93702 93830 93958 94086 94214 73736 73864 73992 74120 74248 74376 74504 74632 74760 74888 75016 75144 75272 75400 75528 75656 75784 75912 76040 76168 76296 76424 76552 76680 76808 76936 77064 77192 77320 77448 77576 77704 77832 81928 82056 82184 82312 82440 82568 82696 82824 82952 83080 83208 83336 83464 83592 83720 83848 83976 84104 84232 84360 84488 84616 84744 84872 85000 85128 85256 85384 85512 85640 85768 85896 86024 90120 90248 90376 90504 90632 90760 90888 91016 91144 91272 91400 91528 91656 91784 91912 92040 92168 92296 92424 92552 92680 92808 92936 93064 93192 93320 93448 93576 93704 93832 93960 94088 94216 73738 73866 73994 74122 74250 74378 74506 74634 74762 74890 75018 75146 75274 75402 75530 75658 75786 75914 76042 76170 76298 76426 76554 76682 76810 76938 77066 77194 77322 77450 77578 77706 77834 81930 82058 82186 82314 82442 82570 82698 82826 82954 83082 83210 83338 83466 83594 83722 83850 83978 84106 84234 84362 84490 84618 84746 84874 85002 85130 85258 85386 85514 85642 85770 85898 86026 90122 90250 90378 90506 90634 90762 90890 91018 91146 91274 91402 91530 91658 91786 91914 92042 92170 92298 92426 92554 92682 92810 92938 93066 93194 93322 93450 93578 93706 93834 93962 94090 94218 73740 73868 73996 74124 74252 74380 74508 74636 74764 74892 75020 75148 75276 75404 75532 75660 75788 75916 76044 76172 76300 76428 76556 76684 76812 76940 77068 77196 77324 77452 77580 77708 77836 81932 82060 82188 82316 82444 82572 82700 82828 82956 83084 83212 83340 83468 83596 83724 83852 83980 84108 84236 84364 84492 84620 84748 84876 85004 85132 85260 85388 85516 85644 85772 85900 86028 90124 90252 90380 90508 90636 90764 90892 91020 91148 91276 91404 91532 91660 91788 91916 92044 92172 92300 92428 92556 92684 92812 92940 93068 93196 93324 93452 93580 93708 93836 93964 94092 94220 73742 73870 73998 74126 74254 74382 74510 74638 74766 74894 75022 75150 75278 75406 75534 75662 75790 75918 76046 76174 76302 76430 76558 76686 76814 76942 77070 77198 77326 77454 77582 77710 77838 81934 82062 82190 82318 82446 82574 82702 82830 82958 83086 83214 83342 83470 83598 83726 83854 83982 84110 84238 84366 84494 84622 84750 84878 85006 85134 85262 85390 85518 85646 85774 85902 86030 90126 90254 90382 90510 90638 90766 90894 91022 91150 91278 91406 91534 91662 91790 91918 92046 92174 92302 92430 92558 92686 92814 92942 93070 93198 93326 93454 93582 93710 93838 93966 94094 94222 73744 73872 74000 74128 74256 74384 74512 74640 74768 74896 75024 75152 75280 75408 75536 75664 75792 75920 76048 76176 76304 76432 76560 76688 76816 76944 77072 77200 77328 77456 77584 77712 77840 81936 82064 82192 82320 82448 82576 82704 82832 82960 83088 83216 83344 83472 83600 83728 83856 83984 84112 84240 84368 84496 84624 84752 84880 85008 85136 85264 85392 85520 85648 85776 85904 86032 90128 90256 90384 90512 90640 90768 90896 91024 91152 91280 91408 91536 91664 91792 91920 92048 92176 92304 92432 92560 92688 92816 92944 93072 93200 93328 93456 93584 93712 93840 93968 94096 94224 73746 73874 74002 74130 74258 74386 74514 74642 74770 74898 75026 75154 75282 75410 75538 75666 75794 75922 76050 76178 76306 76434 76562 76690 76818 76946 77074 77202 77330 77458 77586 77714 77842 81938 82066 82194 82322 82450 82578 82706 82834 82962 83090 83218 83346 83474 83602 83730 83858 83986 84114 84242 84370 84498 84626 84754 84882 85010 85138 85266 85394 85522 85650 85778 85906 86034 90130 90258 90386 90514 90642 90770 90898 91026 91154 91282 91410 91538 91666 91794 91922 92050 92178 92306 92434 92562 92690 92818 92946 93074 93202 93330 93458 93586 93714 93842 93970 94098 94226 73748 73876 74004 74132 74260 74388 74516 74644 74772 74900 75028 75156 75284 75412 75540 75668 75796 75924 76052 76180 76308 76436 76564 76692 76820 76948 77076 77204 77332 77460 77588 77716 77844 81940 82068 82196 82324 82452 82580 82708 82836 82964 83092 83220 83348 83476 83604 83732 83860 83988 84116 84244 84372 84500 84628 84756 84884 85012 85140 85268 85396 85524 85652 85780 85908 86036 90132 90260 90388 90516 90644 90772 90900 91028 91156 91284 91412 91540 91668 91796 91924 92052 92180 92308 92436 92564 92692 92820 92948 93076 93204 93332 93460 93588 93716 93844 93972 94100 94228 73750 73878 74006 74134 74262 74390 74518 74646 74774 74902 75030 75158 75286 75414 75542 75670 75798 75926 76054 76182 76310 76438 76566 76694 76822 76950 77078 77206 77334 77462 77590 77718 77846 81942 82070 82198 82326 82454 82582 82710 82838 82966 83094 83222 83350 83478 83606 83734 83862 83990 84118 84246 84374 84502 84630 84758 84886 85014 85142 85270 85398 85526 85654 85782 85910 86038 90134 90262 90390 90518 90646 90774 90902 91030 91158 91286 91414 91542 91670 91798 91926 92054 92182 92310 92438 92566 92694 92822 92950 93078 93206 93334 93462 93590 93718 93846 93974 94102 94230 73752 73880 74008 74136 74264 74392 74520 74648 74776 74904 75032 75160 75288 75416 75544 75672 75800 75928 76056 76184 76312 76440 76568 76696 76824 76952 77080 77208 77336 77464 77592 77720 77848 81944 82072 82200 82328 82456 82584 82712 82840 82968 83096 83224 83352 83480 83608 83736 83864 83992 84120 84248 84376 84504 84632 84760 84888 85016 85144 85272 85400 85528 85656 85784 85912 86040 90136 90264 90392 90520 90648 90776 90904 91032 91160 91288 91416 91544 91672 91800 91928 92056 92184 92312 92440 92568 92696 92824 92952 93080 93208 93336 93464 93592 93720 93848 93976 94104 94232 73754 73882 74010 74138 74266 74394 74522 74650 74778 74906 75034 75162 75290 75418 75546 75674 75802 75930 76058 76186 76314 76442 76570 76698 76826 76954 77082 77210 77338 77466 77594 77722 77850 81946 82074 82202 82330 82458 82586 82714 82842 82970 83098 83226 83354 83482 83610 83738 83866 83994 84122 84250 84378 84506 84634 84762 84890 85018 85146 85274 85402 85530 85658 85786 85914 86042 90138 90266 90394 90522 90650 90778 90906 91034 91162 91290 91418 91546 91674 91802 91930 92058 92186 92314 92442 92570 92698 92826 92954 93082 93210 93338 93466 93594 93722 93850 93978 94106 94234 73756 73884 74012 74140 74268 74396 74524 74652 74780 74908 75036 75164 75292 75420 75548 75676 75804 75932 76060 76188 76316 76444 76572 76700 76828 76956 77084 77212 77340 77468 77596 77724 77852 81948 82076 82204 82332 82460 82588 82716 82844 82972 83100 83228 83356 83484 83612 83740 83868 83996 84124 84252 84380 84508 84636 84764 84892 85020 85148 85276 85404 85532 85660 85788 85916 86044 90140 90268 90396 90524 90652 90780 90908 91036 91164 91292 91420 91548 91676 91804 91932 92060 92188 92316 92444 92572 92700 92828 92956 93084 93212 93340 93468 93596 93724 93852 93980 94108 94236 73758 73886 74014 74142 74270 74398 74526 74654 74782 74910 75038 75166 75294 75422 75550 75678 75806 75934 76062 76190 76318 76446 76574 76702 76830 76958 77086 77214 77342 77470 77598 77726 77854 81950 82078 82206 82334 82462 82590 82718 82846 82974 83102 83230 83358 83486 83614 83742 83870 83998 84126 84254 84382 84510 84638 84766 84894 85022 85150 85278 85406 85534 85662 85790 85918 86046 90142 90270 90398 90526 90654 90782 90910 91038 91166 91294 91422 91550 91678 91806 91934 92062 92190 92318 92446 92574 92702 92830 92958 93086 93214 93342 93470 93598 93726 93854 93982 94110 94238 73760 73888 74016 74144 74272 74400 74528 74656 74784 74912 75040 75168 75296 75424 75552 75680 75808 75936 76064 76192 76320 76448 76576 76704 76832 76960 77088 77216 77344 77472 77600 77728 77856 81952 82080 82208 82336 82464 82592 82720 82848 82976 83104 83232 83360 83488 83616 83744 83872 84000 84128 84256 84384 84512 84640 84768 84896 85024 85152 85280 85408 85536 85664 85792 85920 86048 90144 90272 90400 90528 90656 90784 90912 91040 91168 91296 91424 91552 91680 91808 91936 92064 92192 92320 92448 92576 92704 92832 92960 93088 93216 93344 93472 93600 93728 93856 93984 94112 94240 73762 73890 74018 74146 74274 74402 74530 74658 74786 74914 75042 75170 75298 75426 75554 75682 75810 75938 76066 76194 76322 76450 76578 76706 76834 76962 77090 77218 77346 77474 77602 77730 77858 81954 82082 82210 82338 82466 82594 82722 82850 82978 83106 83234 83362 83490 83618 83746 83874 84002 84130 84258 84386 84514 84642 84770 84898 85026 85154 85282 85410 85538 85666 85794 85922 86050 90146 90274 90402 90530 90658 90786 90914 91042 91170 91298 91426 91554 91682 91810 91938 92066 92194 92322 92450 92578 92706 92834 92962 93090 93218 93346 93474 93602 93730 93858 93986 94114 94242 73764 73892 74020 74148 74276 74404 74532 74660 74788 74916 75044 75172 75300 75428 75556 75684 75812 75940 76068 76196 76324 76452 76580 76708 76836 76964 77092 77220 77348 77476 77604 77732 77860 81956 82084 82212 82340 82468 82596 82724 82852 82980 83108 83236 83364 83492 83620 83748 83876 84004 84132 84260 84388 84516 84644 84772 84900 85028 85156 85284 85412 85540 85668 85796 85924 86052 90148 90276 90404 90532 90660 90788 90916 91044 91172 91300 91428 91556 91684 91812 91940 92068 92196 92324 92452 92580 92708 92836 92964 93092 93220 93348 93476 93604 93732 93860 93988 94116 94244 73766 73894 74022 74150 74278 74406 74534 74662 74790 74918 75046 75174 75302 75430 75558 75686 75814 75942 76070 76198 76326 76454 76582 76710 76838 76966 77094 77222 77350 77478 77606 77734 77862 81958 82086 82214 82342 82470 82598 82726 82854 82982 83110 83238 83366 83494 83622 83750 83878 84006 84134 84262 84390 84518 84646 84774 84902 85030 85158 85286 85414 85542 85670 85798 85926 86054 90150 90278 90406 90534 90662 90790 90918 91046 91174 91302 91430 91558 91686 91814 91942 92070 92198 92326 92454 92582 92710 92838 92966 93094 93222 93350 93478 93606 93734 93862 93990 94118 94246 73768 73896 74024 74152 74280 74408 74536 74664 74792 74920 75048 75176 75304 75432 75560 75688 75816 75944 76072 76200 76328 76456 76584 76712 76840 76968 77096 77224 77352 77480 77608 77736 77864 81960 82088 82216 82344 82472 82600 82728 82856 82984 83112 83240 83368 83496 83624 83752 83880 84008 84136 84264 84392 84520 84648 84776 84904 85032 85160 85288 85416 85544 85672 85800 85928 86056 90152 90280 90408 90536 90664 90792 90920 91048 91176 91304 91432 91560 91688 91816 91944 92072 92200 92328 92456 92584 92712 92840 92968 93096 93224 93352 93480 93608 93736 93864 93992 94120 94248 73770 73898 74026 74154 74282 74410 74538 74666 74794 74922 75050 75178 75306 75434 75562 75690 75818 75946 76074 76202 76330 76458 76586 76714 76842 76970 77098 77226 77354 77482 77610 77738 77866 81962 82090 82218 82346 82474 82602 82730 82858 82986 83114 83242 83370 83498 83626 83754 83882 84010 84138 84266 84394 84522 84650 84778 84906 85034 85162 85290 85418 85546 85674 85802 85930 86058 90154 90282 90410 90538 90666 90794 90922 91050 91178 91306 91434 91562 91690 91818 91946 92074 92202 92330 92458 92586 92714 92842 92970 93098 93226 93354 93482 93610 93738 93866 93994 94122 94250 73772 73900 74028 74156 74284 74412 74540 74668 74796 74924 75052 75180 75308 75436 75564 75692 75820 75948 76076 76204 76332 76460 76588 76716 76844 76972 77100 77228 77356 77484 77612 77740 77868 81964 82092 82220 82348 82476 82604 82732 82860 82988 83116 83244 83372 83500 83628 83756 83884 84012 84140 84268 84396 84524 84652 84780 84908 85036 85164 85292 85420 85548 85676 85804 85932 86060 90156 90284 90412 90540 90668 90796 90924 91052 91180 91308 91436 91564 91692 91820 91948 92076 92204 92332 92460 92588 92716 92844 92972 93100 93228 93356 93484 93612 93740 93868 93996 94124 94252 73774 73902 74030 74158 74286 74414 74542 74670 74798 74926 75054 75182 75310 75438 75566 75694 75822 75950 76078 76206 76334 76462 76590 76718 76846 76974 77102 77230 77358 77486 77614 77742 77870 81966 82094 82222 82350 82478 82606 82734 82862 82990 83118 83246 83374 83502 83630 83758 83886 84014 84142 84270 84398 84526 84654 84782 84910 85038 85166 85294 85422 85550 85678 85806 85934 86062 90158 90286 90414 90542 90670 90798 90926 91054 91182 91310 91438 91566 91694 91822 91950 92078 92206 92334 92462 92590 92718 92846 92974 93102 93230 93358 93486 93614 93742 93870 93998 94126 94254 73776 73904 74032 74160 74288 74416 74544 74672 74800 74928 75056 75184 75312 75440 75568 75696 75824 75952 76080 76208 76336 76464 76592 76720 76848 76976 77104 77232 77360 77488 77616 77744 77872 81968 82096 82224 82352 82480 82608 82736 82864 82992 83120 83248 83376 83504 83632 83760 83888 84016 84144 84272 84400 84528 84656 84784 84912 85040 85168 85296 85424 85552 85680 85808 85936 86064 90160 90288 90416 90544 90672 90800 90928 91056 91184 91312 91440 91568 91696 91824 91952 92080 92208 92336 92464 92592 92720 92848 92976 93104 93232 93360 93488 93616 93744 93872 94000 94128 94256 73778 73906 74034 74162 74290 74418 74546 74674 74802 74930 75058 75186 75314 75442 75570 75698 75826 75954 76082 76210 76338 76466 76594 76722 76850 76978 77106 77234 77362 77490 77618 77746 77874 81970 82098 82226 82354 82482 82610 82738 82866 82994 83122 83250 83378 83506 83634 83762 83890 84018 84146 84274 84402 84530 84658 84786 84914 85042 85170 85298 85426 85554 85682 85810 85938 86066 90162 90290 90418 90546 90674 90802 90930 91058 91186 91314 91442 91570 91698 91826 91954 92082 92210 92338 92466 92594 92722 92850 92978 93106 93234 93362 93490 93618 93746 93874 94002 94130 94258 73780 73908 74036 74164 74292 74420 74548 74676 74804 74932 75060 75188 75316 75444 75572 75700 75828 75956 76084 76212 76340 76468 76596 76724 76852 76980 77108 77236 77364 77492 77620 77748 77876 81972 82100 82228 82356 82484 82612 82740 82868 82996 83124 83252 83380 83508 83636 83764 83892 84020 84148 84276 84404 84532 84660 84788 84916 85044 85172 85300 85428 85556 85684 85812 85940 86068 90164 90292 90420 90548 90676 90804 90932 91060 91188 91316 91444 91572 91700 91828 91956 92084 92212 92340 92468 92596 92724 92852 92980 93108 93236 93364 93492 93620 93748 93876 94004 94132 94260 73782 73910 74038 74166 74294 74422 74550 74678 74806 74934 75062 75190 75318 75446 75574 75702 75830 75958 76086 76214 76342 76470 76598 76726 76854 76982 77110 77238 77366 77494 77622 77750 77878 81974 82102 82230 82358 82486 82614 82742 82870 82998 83126 83254 83382 83510 83638 83766 83894 84022 84150 84278 84406 84534 84662 84790 84918 85046 85174 85302 85430 85558 85686 85814 85942 86070 90166 90294 90422 90550 90678 90806 90934 91062 91190 91318 91446 91574 91702 91830 91958 92086 92214 92342 92470 92598 92726 92854 92982 93110 93238 93366 93494 93622 93750 93878 94006 94134 94262 73784 73912 74040 74168 74296 74424 74552 74680 74808 74936 75064 75192 75320 75448 75576 75704 75832 75960 76088 76216 76344 76472 76600 76728 76856 76984 77112 77240 77368 77496 77624 77752 77880 81976 82104 82232 82360 82488 82616 82744 82872 83000 83128 83256 83384 83512 83640 83768 83896 84024 84152 84280 84408 84536 84664 84792 84920 85048 85176 85304 85432 85560 85688 85816 85944 86072 90168 90296 90424 90552 90680 90808 90936 91064 91192 91320 91448 91576 91704 91832 91960 92088 92216 92344 92472 92600 92728 92856 92984 93112 93240 93368 93496 93624 93752 93880 94008 94136 94264 73786 73914 74042 74170 74298 74426 74554 74682 74810 74938 75066 75194 75322 75450 75578 75706 75834 75962 76090 76218 76346 76474 76602 76730 76858 76986 77114 77242 77370 77498 77626 77754 77882 81978 82106 82234 82362 82490 82618 82746 82874 83002 83130 83258 83386 83514 83642 83770 83898 84026 84154 84282 84410 84538 84666 84794 84922 85050 85178 85306 85434 85562 85690 85818 85946 86074 90170 90298 90426 90554 90682 90810 90938 91066 91194 91322 91450 91578 91706 91834 91962 92090 92218 92346 92474 92602 92730 92858 92986 93114 93242 93370 93498 93626 93754 93882 94010 94138 94266 73788 73916 74044 74172 74300 74428 74556 74684 74812 74940 75068 75196 75324 75452 75580 75708 75836 75964 76092 76220 76348 76476 76604 76732 76860 76988 77116 77244 77372 77500 77628 77756 77884 81980 82108 82236 82364 82492 82620 82748 82876 83004 83132 83260 83388 83516 83644 83772 83900 84028 84156 84284 84412 84540 84668 84796 84924 85052 85180 85308 85436 85564 85692 85820 85948 86076 90172 90300 90428 90556 90684 90812 90940 91068 91196 91324 91452 91580 91708 91836 91964 92092 92220 92348 92476 92604 92732 92860 92988 93116 93244 93372 93500 93628 93756 93884 94012 94140 94268 73790 73918 74046 74174 74302 74430 74558 74686 74814 74942 75070 75198 75326 75454 75582 75710 75838 75966 76094 76222 76350 76478 76606 76734 76862 76990 77118 77246 77374 77502 77630 77758 77886 81982 82110 82238 82366 82494 82622 82750 82878 83006 83134 83262 83390 83518 83646 83774 83902 84030 84158 84286 84414 84542 84670 84798 84926 85054 85182 85310 85438 85566 85694 85822 85950 86078 90174 90302 90430 90558 90686 90814 90942 91070 91198 91326 91454 91582 91710 91838 91966 92094 92222 92350 92478 92606 92734 92862 92990 93118 93246 93374 93502 93630 93758 93886 94014 94142 94270 73792 73920 74048 74176 74304 74432 74560 74688 74816 74944 75072 75200 75328 75456 75584 75712 75840 75968 76096 76224 76352 76480 76608 76736 76864 76992 77120 77248 77376 77504 77632 77760 77888 81984 82112 82240 82368 82496 82624 82752 82880 83008 83136 83264 83392 83520 83648 83776 83904 84032 84160 84288 84416 84544 84672 84800 84928 85056 85184 85312 85440 85568 85696 85824 85952 86080 90176 90304 90432 90560 90688 90816 90944 91072 91200 91328 91456 91584 91712 91840 91968 92096 92224 92352 92480 92608 92736 92864 92992 93120 93248 93376 93504 93632 93760 93888 94016 94144 94272 73794 73922 74050 74178 74306 74434 74562 74690 74818 74946 75074 75202 75330 75458 75586 75714 75842 75970 76098 76226 76354 76482 76610 76738 76866 76994 77122 77250 77378 77506 77634 77762 77890 81986 82114 82242 82370 82498 82626 82754 82882 83010 83138 83266 83394 83522 83650 83778 83906 84034 84162 84290 84418 84546 84674 84802 84930 85058 85186 85314 85442 85570 85698 85826 85954 86082 90178 90306 90434 90562 90690 90818 90946 91074 91202 91330 91458 91586 91714 91842 91970 92098 92226 92354 92482 92610 92738 92866 92994 93122 93250 93378 93506 93634 93762 93890 94018 94146 94274 73796 73924 74052 74180 74308 74436 74564 74692 74820 74948 75076 75204 75332 75460 75588 75716 75844 75972 76100 76228 76356 76484 76612 76740 76868 76996 77124 77252 77380 77508 77636 77764 77892 81988 82116 82244 82372 82500 82628 82756 82884 83012 83140 83268 83396 83524 83652 83780 83908 84036 84164 84292 84420 84548 84676 84804 84932 85060 85188 85316 85444 85572 85700 85828 85956 86084 90180 90308 90436 90564 90692 90820 90948 91076 91204 91332 91460 91588 91716 91844 91972 92100 92228 92356 92484 92612 92740 92868 92996 93124 93252 93380 93508 93636 93764 93892 94020 94148 94276 73798 73926 74054 74182 74310 74438 74566 74694 74822 74950 75078 75206 75334 75462 75590 75718 75846 75974 76102 76230 76358 76486 76614 76742 76870 76998 77126 77254 77382 77510 77638 77766 77894 81990 82118 82246 82374 82502 82630 82758 82886 83014 83142 83270 83398 83526 83654 83782 83910 84038 84166 84294 84422 84550 84678 84806 84934 85062 85190 85318 85446 85574 85702 85830 85958 86086 90182 90310 90438 90566 90694 90822 90950 91078 91206 91334 91462 91590 91718 91846 91974 92102 92230 92358 92486 92614 92742 92870 92998 93126 93254 93382 93510 93638 93766 93894 94022 94150 94278 73800 73928 74056 74184 74312 74440 74568 74696 74824 74952 75080 75208 75336 75464 75592 75720 75848 75976 76104 76232 76360 76488 76616 76744 76872 77000 77128 77256 77384 77512 77640 77768 77896 81992 82120 82248 82376 82504 82632 82760 82888 83016 83144 83272 83400 83528 83656 83784 83912 84040 84168 84296 84424 84552 84680 84808 84936 85064 85192 85320 85448 85576 85704 85832 85960 86088 90184 90312 90440 90568 90696 90824 90952 91080 91208 91336 91464 91592 91720 91848 91976 92104 92232 92360 92488 92616 92744 92872 93000 93128 93256 93384 93512 93640 93768 93896 94024 94152 94280 73802 73930 74058 74186 74314 74442 74570 74698 74826 74954 75082 75210 75338 75466 75594 75722 75850 75978 76106 76234 76362 76490 76618 76746 76874 77002 77130 77258 77386 77514 77642 77770 77898 81994 82122 82250 82378 82506 82634 82762 82890 83018 83146 83274 83402 83530 83658 83786 83914 84042 84170 84298 84426 84554 84682 84810 84938 85066 85194 85322 85450 85578 85706 85834 85962 86090 90186 90314 90442 90570 90698 90826 90954 91082 91210 91338 91466 91594 91722 91850 91978 92106 92234 92362 92490 92618 92746 92874 93002 93130 93258 93386 93514 93642 93770 93898 94026 94154 94282 73804 73932 74060 74188 74316 74444 74572 74700 74828 74956 75084 75212 75340 75468 75596 75724 75852 75980 76108 76236 76364 76492 76620 76748 76876 77004 77132 77260 77388 77516 77644 77772 77900 81996 82124 82252 82380 82508 82636 82764 82892 83020 83148 83276 83404 83532 83660 83788 83916 84044 84172 84300 84428 84556 84684 84812 84940 85068 85196 85324 85452 85580 85708 85836 85964 86092 90188 90316 90444 90572 90700 90828 90956 91084 91212 91340 91468 91596 91724 91852 91980 92108 92236 92364 92492 92620 92748 92876 93004 93132 93260 93388 93516 93644 93772 93900 94028 94156 94284 73806 73934 74062 74190 74318 74446 74574 74702 74830 74958 75086 75214 75342 75470 75598 75726 75854 75982 76110 76238 76366 76494 76622 76750 76878 77006 77134 77262 77390 77518 77646 77774 77902 81998 82126 82254 82382 82510 82638 82766 82894 83022 83150 83278 83406 83534 83662 83790 83918 84046 84174 84302 84430 84558 84686 84814 84942 85070 85198 85326 85454 85582 85710 85838 85966 86094 90190 90318 90446 90574 90702 90830 90958 91086 91214 91342 91470 91598 91726 91854 91982 92110 92238 92366 92494 92622 92750 92878 93006 93134 93262 93390 93518 93646 93774 93902 94030 94158 94286 73808 73936 74064 74192 74320 74448 74576 74704 74832 74960 75088 75216 75344 75472 75600 75728 75856 75984 76112 76240 76368 76496 76624 76752 76880 77008 77136 77264 77392 77520 77648 77776 77904 82000 82128 82256 82384 82512 82640 82768 82896 83024 83152 83280 83408 83536 83664 83792 83920 84048 84176 84304 84432 84560 84688 84816 84944 85072 85200 85328 85456 85584 85712 85840 85968 86096 90192 90320 90448 90576 90704 90832 90960 91088 91216 91344 91472 91600 91728 91856 91984 92112 92240 92368 92496 92624 92752 92880 93008 93136 93264 93392 93520 93648 93776 93904 94032 94160 94288 73810 73938 74066 74194 74322 74450 74578 74706 74834 74962 75090 75218 75346 75474 75602 75730 75858 75986 76114 76242 76370 76498 76626 76754 76882 77010 77138 77266 77394 77522 77650 77778 77906 82002 82130 82258 82386 82514 82642 82770 82898 83026 83154 83282 83410 83538 83666 83794 83922 84050 84178 84306 84434 84562 84690 84818 84946 85074 85202 85330 85458 85586 85714 85842 85970 86098 90194 90322 90450 90578 90706 90834 90962 91090 91218 91346 91474 91602 91730 91858 91986 92114 92242 92370 92498 92626 92754 92882 93010 93138 93266 93394 93522 93650 93778 93906 94034 94162 94290 73812 73940 74068 74196 74324 74452 74580 74708 74836 74964 75092 75220 75348 75476 75604 75732 75860 75988 76116 76244 76372 76500 76628 76756 76884 77012 77140 77268 77396 77524 77652 77780 77908 82004 82132 82260 82388 82516 82644 82772 82900 83028 83156 83284 83412 83540 83668 83796 83924 84052 84180 84308 84436 84564 84692 84820 84948 85076 85204 85332 85460 85588 85716 85844 85972 86100 90196 90324 90452 90580 90708 90836 90964 91092 91220 91348 91476 91604 91732 91860 91988 92116 92244 92372 92500 92628 92756 92884 93012 93140 93268 93396 93524 93652 93780 93908 94036 94164 94292 73814 73942 74070 74198 74326 74454 74582 74710 74838 74966 75094 75222 75350 75478 75606 75734 75862 75990 76118 76246 76374 76502 76630 76758 76886 77014 77142 77270 77398 77526 77654 77782 77910 82006 82134 82262 82390 82518 82646 82774 82902 83030 83158 83286 83414 83542 83670 83798 83926 84054 84182 84310 84438 84566 84694 84822 84950 85078 85206 85334 85462 85590 85718 85846 85974 86102 90198 90326 90454 90582 90710 90838 90966 91094 91222 91350 91478 91606 91734 91862 91990 92118 92246 92374 92502 92630 92758 92886 93014 93142 93270 93398 93526 93654 93782 93910 94038 94166 94294 73816 73944 74072 74200 74328 74456 74584 74712 74840 74968 75096 75224 75352 75480 75608 75736 75864 75992 76120 76248 76376 76504 76632 76760 76888 77016 77144 77272 77400 77528 77656 77784 77912 82008 82136 82264 82392 82520 82648 82776 82904 83032 83160 83288 83416 83544 83672 83800 83928 84056 84184 84312 84440 84568 84696 84824 84952 85080 85208 85336 85464 85592 85720 85848 85976 86104 90200 90328 90456 90584 90712 90840 90968 91096 91224 91352 91480 91608 91736 91864 91992 92120 92248 92376 92504 92632 92760 92888 93016 93144 93272 93400 93528 93656 93784 93912 94040 94168 94296 73818 73946 74074 74202 74330 74458 74586 74714 74842 74970 75098 75226 75354 75482 75610 75738 75866 75994 76122 76250 76378 76506 76634 76762 76890 77018 77146 77274 77402 77530 77658 77786 77914 82010 82138 82266 82394 82522 82650 82778 82906 83034 83162 83290 83418 83546 83674 83802 83930 84058 84186 84314 84442 84570 84698 84826 84954 85082 85210 85338 85466 85594 85722 85850 85978 86106 90202 90330 90458 90586 90714 90842 90970 91098 91226 91354 91482 91610 91738 91866 91994 92122 92250 92378 92506 92634 92762 92890 93018 93146 93274 93402 93530 93658 93786 93914 94042 94170 94298 73820 73948 74076 74204 74332 74460 74588 74716 74844 74972 75100 75228 75356 75484 75612 75740 75868 75996 76124 76252 76380 76508 76636 76764 76892 77020 77148 77276 77404 77532 77660 77788 77916 82012 82140 82268 82396 82524 82652 82780 82908 83036 83164 83292 83420 83548 83676 83804 83932 84060 84188 84316 84444 84572 84700 84828 84956 85084 85212 85340 85468 85596 85724 85852 85980 86108 90204 90332 90460 90588 90716 90844 90972 91100 91228 91356 91484 91612 91740 91868 91996 92124 92252 92380 92508 92636 92764 92892 93020 93148 93276 93404 93532 93660 93788 93916 94044 94172 94300 73822 73950 74078 74206 74334 74462 74590 74718 74846 74974 75102 75230 75358 75486 75614 75742 75870 75998 76126 76254 76382 76510 76638 76766 76894 77022 77150 77278 77406 77534 77662 77790 77918 82014 82142 82270 82398 82526 82654 82782 82910 83038 83166 83294 83422 83550 83678 83806 83934 84062 84190 84318 84446 84574 84702 84830 84958 85086 85214 85342 85470 85598 85726 85854 85982 86110 90206 90334 90462 90590 90718 90846 90974 91102 91230 91358 91486 91614 91742 91870 91998 92126 92254 92382 92510 92638 92766 92894 93022 93150 93278 93406 93534 93662 93790 93918 94046 94174 94302 73824 73952 74080 74208 74336 74464 74592 74720 74848 74976 75104 75232 75360 75488 75616 75744 75872 76000 76128 76256 76384 76512 76640 76768 76896 77024 77152 77280 77408 77536 77664 77792 77920 82016 82144 82272 82400 82528 82656 82784 82912 83040 83168 83296 83424 83552 83680 83808 83936 84064 84192 84320 84448 84576 84704 84832 84960 85088 85216 85344 85472 85600 85728 85856 85984 86112 90208 90336 90464 90592 90720 90848 90976 91104 91232 91360 91488 91616 91744 91872 92000 92128 92256 92384 92512 92640 92768 92896 93024 93152 93280 93408 93536 93664 93792 93920 94048 94176 94304 73826 73954 74082 74210 74338 74466 74594 74722 74850 74978 75106 75234 75362 75490 75618 75746 75874 76002 76130 76258 76386 76514 76642 76770 76898 77026 77154 77282 77410 77538 77666 77794 77922 82018 82146 82274 82402 82530 82658 82786 82914 83042 83170 83298 83426 83554 83682 83810 83938 84066 84194 84322 84450 84578 84706 84834 84962 85090 85218 85346 85474 85602 85730 85858 85986 86114 90210 90338 90466 90594 90722 90850 90978 91106 91234 91362 91490 91618 91746 91874 92002 92130 92258 92386 92514 92642 92770 92898 93026 93154 93282 93410 93538 93666 93794 93922 94050 94178 94306 73828 73956 74084 74212 74340 74468 74596 74724 74852 74980 75108 75236 75364 75492 75620 75748 75876 76004 76132 76260 76388 76516 76644 76772 76900 77028 77156 77284 77412 77540 77668 77796 77924 82020 82148 82276 82404 82532 82660 82788 82916 83044 83172 83300 83428 83556 83684 83812 83940 84068 84196 84324 84452 84580 84708 84836 84964 85092 85220 85348 85476 85604 85732 85860 85988 86116 90212 90340 90468 90596 90724 90852 90980 91108 91236 91364 91492 91620 91748 91876 92004 92132 92260 92388 92516 92644 92772 92900 93028 93156 93284 93412 93540 93668 93796 93924 94052 94180 94308 73830 73958 74086 74214 74342 74470 74598 74726 74854 74982 75110 75238 75366 75494 75622 75750 75878 76006 76134 76262 76390 76518 76646 76774 76902 77030 77158 77286 77414 77542 77670 77798 77926 82022 82150 82278 82406 82534 82662 82790 82918 83046 83174 83302 83430 83558 83686 83814 83942 84070 84198 84326 84454 84582 84710 84838 84966 85094 85222 85350 85478 85606 85734 85862 85990 86118 90214 90342 90470 90598 90726 90854 90982 91110 91238 91366 91494 91622 91750 91878 92006 92134 92262 92390 92518 92646 92774 92902 93030 93158 93286 93414 93542 93670 93798 93926 94054 94182 94310 73832 73960 74088 74216 74344 74472 74600 74728 74856 74984 75112 75240 75368 75496 75624 75752 75880 76008 76136 76264 76392 76520 76648 76776 76904 77032 77160 77288 77416 77544 77672 77800 77928 82024 82152 82280 82408 82536 82664 82792 82920 83048 83176 83304 83432 83560 83688 83816 83944 84072 84200 84328 84456 84584 84712 84840 84968 85096 85224 85352 85480 85608 85736 85864 85992 86120 90216 90344 90472 90600 90728 90856 90984 91112 91240 91368 91496 91624 91752 91880 92008 92136 92264 92392 92520 92648 92776 92904 93032 93160 93288 93416 93544 93672 93800 93928 94056 94184 94312 73834 73962 74090 74218 74346 74474 74602 74730 74858 74986 75114 75242 75370 75498 75626 75754 75882 76010 76138 76266 76394 76522 76650 76778 76906 77034 77162 77290 77418 77546 77674 77802 77930 82026 82154 82282 82410 82538 82666 82794 82922 83050 83178 83306 83434 83562 83690 83818 83946 84074 84202 84330 84458 84586 84714 84842 84970 85098 85226 85354 85482 85610 85738 85866 85994 86122 90218 90346 90474 90602 90730 90858 90986 91114 91242 91370 91498 91626 91754 91882 92010 92138 92266 92394 92522 92650 92778 92906 93034 93162 93290 93418 93546 93674 93802 93930 94058 94186 94314 73836 73964 74092 74220 74348 74476 74604 74732 74860 74988 75116 75244 75372 75500 75628 75756 75884 76012 76140 76268 76396 76524 76652 76780 76908 77036 77164 77292 77420 77548 77676 77804 77932 82028 82156 82284 82412 82540 82668 82796 82924 83052 83180 83308 83436 83564 83692 83820 83948 84076 84204 84332 84460 84588 84716 84844 84972 85100 85228 85356 85484 85612 85740 85868 85996 86124 90220 90348 90476 90604 90732 90860 90988 91116 91244 91372 91500 91628 91756 91884 92012 92140 92268 92396 92524 92652 92780 92908 93036 93164 93292 93420 93548 93676 93804 93932 94060 94188 94316 73838 73966 74094 74222 74350 74478 74606 74734 74862 74990 75118 75246 75374 75502 75630 75758 75886 76014 76142 76270 76398 76526 76654 76782 76910 77038 77166 77294 77422 77550 77678 77806 77934 82030 82158 82286 82414 82542 82670 82798 82926 83054 83182 83310 83438 83566 83694 83822 83950 84078 84206 84334 84462 84590 84718 84846 84974 85102 85230 85358 85486 85614 85742 85870 85998 86126 90222 90350 90478 90606 90734 90862 90990 91118 91246 91374 91502 91630 91758 91886 92014 92142 92270 92398 92526 92654 92782 92910 93038 93166 93294 93422 93550 93678 93806 93934 94062 94190 94318 73840 73968 74096 74224 74352 74480 74608 74736 74864 74992 75120 75248 75376 75504 75632 75760 75888 76016 76144 76272 76400 76528 76656 76784 76912 77040 77168 77296 77424 77552 77680 77808 77936 82032 82160 82288 82416 82544 82672 82800 82928 83056 83184 83312 83440 83568 83696 83824 83952 84080 84208 84336 84464 84592 84720 84848 84976 85104 85232 85360 85488 85616 85744 85872 86000 86128 90224 90352 90480 90608 90736 90864 90992 91120 91248 91376 91504 91632 91760 91888 92016 92144 92272 92400 92528 92656 92784 92912 93040 93168 93296 93424 93552 93680 93808 93936 94064 94192 94320 73842 73970 74098 74226 74354 74482 74610 74738 74866 74994 75122 75250 75378 75506 75634 75762 75890 76018 76146 76274 76402 76530 76658 76786 76914 77042 77170 77298 77426 77554 77682 77810 77938 82034 82162 82290 82418 82546 82674 82802 82930 83058 83186 83314 83442 83570 83698 83826 83954 84082 84210 84338 84466 84594 84722 84850 84978 85106 85234 85362 85490 85618 85746 85874 86002 86130 90226 90354 90482 90610 90738 90866 90994 91122 91250 91378 91506 91634 91762 91890 92018 92146 92274 92402 92530 92658 92786 92914 93042 93170 93298 93426 93554 93682 93810 93938 94066 94194 94322 73844 73972 74100 74228 74356 74484 74612 74740 74868 74996 75124 75252 75380 75508 75636 75764 75892 76020 76148 76276 76404 76532 76660 76788 76916 77044 77172 77300 77428 77556 77684 77812 77940 82036 82164 82292 82420 82548 82676 82804 82932 83060 83188 83316 83444 83572 83700 83828 83956 84084 84212 84340 84468 84596 84724 84852 84980 85108 85236 85364 85492 85620 85748 85876 86004 86132 90228 90356 90484 90612 90740 90868 90996 91124 91252 91380 91508 91636 91764 91892 92020 92148 92276 92404 92532 92660 92788 92916 93044 93172 93300 93428 93556 93684 93812 93940 94068 94196 94324 73846 73974 74102 74230 74358 74486 74614 74742 74870 74998 75126 75254 75382 75510 75638 75766 75894 76022 76150 76278 76406 76534 76662 76790 76918 77046 77174 77302 77430 77558 77686 77814 77942 82038 82166 82294 82422 82550 82678 82806 82934 83062 83190 83318 83446 83574 83702 83830 83958 84086 84214 84342 84470 84598 84726 84854 84982 85110 85238 85366 85494 85622 85750 85878 86006 86134 90230 90358 90486 90614 90742 90870 90998 91126 91254 91382 91510 91638 91766 91894 92022 92150 92278 92406 92534 92662 92790 92918 93046 93174 93302 93430 93558 93686 93814 93942 94070 94198 94326 73848 73976 74104 74232 74360 74488 74616 74744 74872 75000 75128 75256 75384 75512 75640 75768 75896 76024 76152 76280 76408 76536 76664 76792 76920 77048 77176 77304 77432 77560 77688 77816 77944 82040 82168 82296 82424 82552 82680 82808 82936 83064 83192 83320 83448 83576 83704 83832 83960 84088 84216 84344 84472 84600 84728 84856 84984 85112 85240 85368 85496 85624 85752 85880 86008 86136 90232 90360 90488 90616 90744 90872 91000 91128 91256 91384 91512 91640 91768 91896 92024 92152 92280 92408 92536 92664 92792 92920 93048 93176 93304 93432 93560 93688 93816 93944 94072 94200 94328 73850 73978 74106 74234 74362 74490 74618 74746 74874 75002 75130 75258 75386 75514 75642 75770 75898 76026 76154 76282 76410 76538 76666 76794 76922 77050 77178 77306 77434 77562 77690 77818 77946 82042 82170 82298 82426 82554 82682 82810 82938 83066 83194 83322 83450 83578 83706 83834 83962 84090 84218 84346 84474 84602 84730 84858 84986 85114 85242 85370 85498 85626 85754 85882 86010 86138 90234 90362 90490 90618 90746 90874 91002 91130 91258 91386 91514 91642 91770 91898 92026 92154 92282 92410 92538 92666 92794 92922 93050 93178 93306 93434 93562 93690 93818 93946 94074 94202 94330 73852 73980 74108 74236 74364 74492 74620 74748 74876 75004 75132 75260 75388 75516 75644 75772 75900 76028 76156 76284 76412 76540 76668 76796 76924 77052 77180 77308 77436 77564 77692 77820 77948 82044 82172 82300 82428 82556 82684 82812 82940 83068 83196 83324 83452 83580 83708 83836 83964 84092 84220 84348 84476 84604 84732 84860 84988 85116 85244 85372 85500 85628 85756 85884 86012 86140 90236 90364 90492 90620 90748 90876 91004 91132 91260 91388 91516 91644 91772 91900 92028 92156 92284 92412 92540 92668 92796 92924 93052 93180 93308 93436 93564 93692 93820 93948 94076 94204 94332 73854 73982 74110 74238 74366 74494 74622 74750 74878 75006 75134 75262 75390 75518 75646 75774 75902 76030 76158 76286 76414 76542 76670 76798 76926 77054 77182 77310 77438 77566 77694 77822 77950 82046 82174 82302 82430 82558 82686 82814 82942 83070 83198 83326 83454 83582 83710 83838 83966 84094 84222 84350 84478 84606 84734 84862 84990 85118 85246 85374 85502 85630 85758 85886 86014 86142 90238 90366 90494 90622 90750 90878 91006 91134 91262 91390 91518 91646 91774 91902 92030 92158 92286 92414 92542 92670 92798 92926 93054 93182 93310 93438 93566 93694 93822 93950 94078 94206 94334 98304 98432 98560 98688 98816 98944 99072 99200 99328 99456 99584 99712 99840 99968 100096 100224 100352 100480 100608 100736 100864 100992 101120 101248 101376 101504 101632 101760 101888 102016 102144 102272 102400 106496 106624 106752 106880 107008 107136 107264 107392 107520 107648 107776 107904 108032 108160 108288 108416 108544 108672 108800 108928 109056 109184 109312 109440 109568 109696 109824 109952 110080 110208 110336 110464 110592 114688 114816 114944 115072 115200 115328 115456 115584 115712 115840 115968 116096 116224 116352 116480 116608 116736 116864 116992 117120 117248 117376 117504 117632 117760 117888 118016 118144 118272 118400 118528 118656 118784 98306 98434 98562 98690 98818 98946 99074 99202 99330 99458 99586 99714 99842 99970 100098 100226 100354 100482 100610 100738 100866 100994 101122 101250 101378 101506 101634 101762 101890 102018 102146 102274 102402 106498 106626 106754 106882 107010 107138 107266 107394 107522 107650 107778 107906 108034 108162 108290 108418 108546 108674 108802 108930 109058 109186 109314 109442 109570 109698 109826 109954 110082 110210 110338 110466 110594 114690 114818 114946 115074 115202 115330 115458 115586 115714 115842 115970 116098 116226 116354 116482 116610 116738 116866 116994 117122 117250 117378 117506 117634 117762 117890 118018 118146 118274 118402 118530 118658 118786 98308 98436 98564 98692 98820 98948 99076 99204 99332 99460 99588 99716 99844 99972 100100 100228 100356 100484 100612 100740 100868 100996 101124 101252 101380 101508 101636 101764 101892 102020 102148 102276 102404 106500 106628 106756 106884 107012 107140 107268 107396 107524 107652 107780 107908 108036 108164 108292 108420 108548 108676 108804 108932 109060 109188 109316 109444 109572 109700 109828 109956 110084 110212 110340 110468 110596 114692 114820 114948 115076 115204 115332 115460 115588 115716 115844 115972 116100 116228 116356 116484 116612 116740 116868 116996 117124 117252 117380 117508 117636 117764 117892 118020 118148 118276 118404 118532 118660 118788 98310 98438 98566 98694 98822 98950 99078 99206 99334 99462 99590 99718 99846 99974 100102 100230 100358 100486 100614 100742 100870 100998 101126 101254 101382 101510 101638 101766 101894 102022 102150 102278 102406 106502 106630 106758 106886 107014 107142 107270 107398 107526 107654 107782 107910 108038 108166 108294 108422 108550 108678 108806 108934 109062 109190 109318 109446 109574 109702 109830 109958 110086 110214 110342 110470 110598 114694 114822 114950 115078 115206 115334 115462 115590 115718 115846 115974 116102 116230 116358 116486 116614 116742 116870 116998 117126 117254 117382 117510 117638 117766 117894 118022 118150 118278 118406 118534 118662 118790 98312 98440 98568 98696 98824 98952 99080 99208 99336 99464 99592 99720 99848 99976 100104 100232 100360 100488 100616 100744 100872 101000 101128 101256 101384 101512 101640 101768 101896 102024 102152 102280 102408 106504 106632 106760 106888 107016 107144 107272 107400 107528 107656 107784 107912 108040 108168 108296 108424 108552 108680 108808 108936 109064 109192 109320 109448 109576 109704 109832 109960 110088 110216 110344 110472 110600 114696 114824 114952 115080 115208 115336 115464 115592 115720 115848 115976 116104 116232 116360 116488 116616 116744 116872 117000 117128 117256 117384 117512 117640 117768 117896 118024 118152 118280 118408 118536 118664 118792 98314 98442 98570 98698 98826 98954 99082 99210 99338 99466 99594 99722 99850 99978 100106 100234 100362 100490 100618 100746 100874 101002 101130 101258 101386 101514 101642 101770 101898 102026 102154 102282 102410 106506 106634 106762 106890 107018 107146 107274 107402 107530 107658 107786 107914 108042 108170 108298 108426 108554 108682 108810 108938 109066 109194 109322 109450 109578 109706 109834 109962 110090 110218 110346 110474 110602 114698 114826 114954 115082 115210 115338 115466 115594 115722 115850 115978 116106 116234 116362 116490 116618 116746 116874 117002 117130 117258 117386 117514 117642 117770 117898 118026 118154 118282 118410 118538 118666 118794 98316 98444 98572 98700 98828 98956 99084 99212 99340 99468 99596 99724 99852 99980 100108 100236 100364 100492 100620 100748 100876 101004 101132 101260 101388 101516 101644 101772 101900 102028 102156 102284 102412 106508 106636 106764 106892 107020 107148 107276 107404 107532 107660 107788 107916 108044 108172 108300 108428 108556 108684 108812 108940 109068 109196 109324 109452 109580 109708 109836 109964 110092 110220 110348 110476 110604 114700 114828 114956 115084 115212 115340 115468 115596 115724 115852 115980 116108 116236 116364 116492 116620 116748 116876 117004 117132 117260 117388 117516 117644 117772 117900 118028 118156 118284 118412 118540 118668 118796 98318 98446 98574 98702 98830 98958 99086 99214 99342 99470 99598 99726 99854 99982 100110 100238 100366 100494 100622 100750 100878 101006 101134 101262 101390 101518 101646 101774 101902 102030 102158 102286 102414 106510 106638 106766 106894 107022 107150 107278 107406 107534 107662 107790 107918 108046 108174 108302 108430 108558 108686 108814 108942 109070 109198 109326 109454 109582 109710 109838 109966 110094 110222 110350 110478 110606 114702 114830 114958 115086 115214 115342 115470 115598 115726 115854 115982 116110 116238 116366 116494 116622 116750 116878 117006 117134 117262 117390 117518 117646 117774 117902 118030 118158 118286 118414 118542 118670 118798 98320 98448 98576 98704 98832 98960 99088 99216 99344 99472 99600 99728 99856 99984 100112 100240 100368 100496 100624 100752 100880 101008 101136 101264 101392 101520 101648 101776 101904 102032 102160 102288 102416 106512 106640 106768 106896 107024 107152 107280 107408 107536 107664 107792 107920 108048 108176 108304 108432 108560 108688 108816 108944 109072 109200 109328 109456 109584 109712 109840 109968 110096 110224 110352 110480 110608 114704 114832 114960 115088 115216 115344 115472 115600 115728 115856 115984 116112 116240 116368 116496 116624 116752 116880 117008 117136 117264 117392 117520 117648 117776 117904 118032 118160 118288 118416 118544 118672 118800 98322 98450 98578 98706 98834 98962 99090 99218 99346 99474 99602 99730 99858 99986 100114 100242 100370 100498 100626 100754 100882 101010 101138 101266 101394 101522 101650 101778 101906 102034 102162 102290 102418 106514 106642 106770 106898 107026 107154 107282 107410 107538 107666 107794 107922 108050 108178 108306 108434 108562 108690 108818 108946 109074 109202 109330 109458 109586 109714 109842 109970 110098 110226 110354 110482 110610 114706 114834 114962 115090 115218 115346 115474 115602 115730 115858 115986 116114 116242 116370 116498 116626 116754 116882 117010 117138 117266 117394 117522 117650 117778 117906 118034 118162 118290 118418 118546 118674 118802 98324 98452 98580 98708 98836 98964 99092 99220 99348 99476 99604 99732 99860 99988 100116 100244 100372 100500 100628 100756 100884 101012 101140 101268 101396 101524 101652 101780 101908 102036 102164 102292 102420 106516 106644 106772 106900 107028 107156 107284 107412 107540 107668 107796 107924 108052 108180 108308 108436 108564 108692 108820 108948 109076 109204 109332 109460 109588 109716 109844 109972 110100 110228 110356 110484 110612 114708 114836 114964 115092 115220 115348 115476 115604 115732 115860 115988 116116 116244 116372 116500 116628 116756 116884 117012 117140 117268 117396 117524 117652 117780 117908 118036 118164 118292 118420 118548 118676 118804 98326 98454 98582 98710 98838 98966 99094 99222 99350 99478 99606 99734 99862 99990 100118 100246 100374 100502 100630 100758 100886 101014 101142 101270 101398 101526 101654 101782 101910 102038 102166 102294 102422 106518 106646 106774 106902 107030 107158 107286 107414 107542 107670 107798 107926 108054 108182 108310 108438 108566 108694 108822 108950 109078 109206 109334 109462 109590 109718 109846 109974 110102 110230 110358 110486 110614 114710 114838 114966 115094 115222 115350 115478 115606 115734 115862 115990 116118 116246 116374 116502 116630 116758 116886 117014 117142 117270 117398 117526 117654 117782 117910 118038 118166 118294 118422 118550 118678 118806 98328 98456 98584 98712 98840 98968 99096 99224 99352 99480 99608 99736 99864 99992 100120 100248 100376 100504 100632 100760 100888 101016 101144 101272 101400 101528 101656 101784 101912 102040 102168 102296 102424 106520 106648 106776 106904 107032 107160 107288 107416 107544 107672 107800 107928 108056 108184 108312 108440 108568 108696 108824 108952 109080 109208 109336 109464 109592 109720 109848 109976 110104 110232 110360 110488 110616 114712 114840 114968 115096 115224 115352 115480 115608 115736 115864 115992 116120 116248 116376 116504 116632 116760 116888 117016 117144 117272 117400 117528 117656 117784 117912 118040 118168 118296 118424 118552 118680 118808 98330 98458 98586 98714 98842 98970 99098 99226 99354 99482 99610 99738 99866 99994 100122 100250 100378 100506 100634 100762 100890 101018 101146 101274 101402 101530 101658 101786 101914 102042 102170 102298 102426 106522 106650 106778 106906 107034 107162 107290 107418 107546 107674 107802 107930 108058 108186 108314 108442 108570 108698 108826 108954 109082 109210 109338 109466 109594 109722 109850 109978 110106 110234 110362 110490 110618 114714 114842 114970 115098 115226 115354 115482 115610 115738 115866 115994 116122 116250 116378 116506 116634 116762 116890 117018 117146 117274 117402 117530 117658 117786 117914 118042 118170 118298 118426 118554 118682 118810 98332 98460 98588 98716 98844 98972 99100 99228 99356 99484 99612 99740 99868 99996 100124 100252 100380 100508 100636 100764 100892 101020 101148 101276 101404 101532 101660 101788 101916 102044 102172 102300 102428 106524 106652 106780 106908 107036 107164 107292 107420 107548 107676 107804 107932 108060 108188 108316 108444 108572 108700 108828 108956 109084 109212 109340 109468 109596 109724 109852 109980 110108 110236 110364 110492 110620 114716 114844 114972 115100 115228 115356 115484 115612 115740 115868 115996 116124 116252 116380 116508 116636 116764 116892 117020 117148 117276 117404 117532 117660 117788 117916 118044 118172 118300 118428 118556 118684 118812 98334 98462 98590 98718 98846 98974 99102 99230 99358 99486 99614 99742 99870 99998 100126 100254 100382 100510 100638 100766 100894 101022 101150 101278 101406 101534 101662 101790 101918 102046 102174 102302 102430 106526 106654 106782 106910 107038 107166 107294 107422 107550 107678 107806 107934 108062 108190 108318 108446 108574 108702 108830 108958 109086 109214 109342 109470 109598 109726 109854 109982 110110 110238 110366 110494 110622 114718 114846 114974 115102 115230 115358 115486 115614 115742 115870 115998 116126 116254 116382 116510 116638 116766 116894 117022 117150 117278 117406 117534 117662 117790 117918 118046 118174 118302 118430 118558 118686 118814 98336 98464 98592 98720 98848 98976 99104 99232 99360 99488 99616 99744 99872 100000 100128 100256 100384 100512 100640 100768 100896 101024 101152 101280 101408 101536 101664 101792 101920 102048 102176 102304 102432 106528 106656 106784 106912 107040 107168 107296 107424 107552 107680 107808 107936 108064 108192 108320 108448 108576 108704 108832 108960 109088 109216 109344 109472 109600 109728 109856 109984 110112 110240 110368 110496 110624 114720 114848 114976 115104 115232 115360 115488 115616 115744 115872 116000 116128 116256 116384 116512 116640 116768 116896 117024 117152 117280 117408 117536 117664 117792 117920 118048 118176 118304 118432 118560 118688 118816 98338 98466 98594 98722 98850 98978 99106 99234 99362 99490 99618 99746 99874 100002 100130 100258 100386 100514 100642 100770 100898 101026 101154 101282 101410 101538 101666 101794 101922 102050 102178 102306 102434 106530 106658 106786 106914 107042 107170 107298 107426 107554 107682 107810 107938 108066 108194 108322 108450 108578 108706 108834 108962 109090 109218 109346 109474 109602 109730 109858 109986 110114 110242 110370 110498 110626 114722 114850 114978 115106 115234 115362 115490 115618 115746 115874 116002 116130 116258 116386 116514 116642 116770 116898 117026 117154 117282 117410 117538 117666 117794 117922 118050 118178 118306 118434 118562 118690 118818 98340 98468 98596 98724 98852 98980 99108 99236 99364 99492 99620 99748 99876 100004 100132 100260 100388 100516 100644 100772 100900 101028 101156 101284 101412 101540 101668 101796 101924 102052 102180 102308 102436 106532 106660 106788 106916 107044 107172 107300 107428 107556 107684 107812 107940 108068 108196 108324 108452 108580 108708 108836 108964 109092 109220 109348 109476 109604 109732 109860 109988 110116 110244 110372 110500 110628 114724 114852 114980 115108 115236 115364 115492 115620 115748 115876 116004 116132 116260 116388 116516 116644 116772 116900 117028 117156 117284 117412 117540 117668 117796 117924 118052 118180 118308 118436 118564 118692 118820 98342 98470 98598 98726 98854 98982 99110 99238 99366 99494 99622 99750 99878 100006 100134 100262 100390 100518 100646 100774 100902 101030 101158 101286 101414 101542 101670 101798 101926 102054 102182 102310 102438 106534 106662 106790 106918 107046 107174 107302 107430 107558 107686 107814 107942 108070 108198 108326 108454 108582 108710 108838 108966 109094 109222 109350 109478 109606 109734 109862 109990 110118 110246 110374 110502 110630 114726 114854 114982 115110 115238 115366 115494 115622 115750 115878 116006 116134 116262 116390 116518 116646 116774 116902 117030 117158 117286 117414 117542 117670 117798 117926 118054 118182 118310 118438 118566 118694 118822 98344 98472 98600 98728 98856 98984 99112 99240 99368 99496 99624 99752 99880 100008 100136 100264 100392 100520 100648 100776 100904 101032 101160 101288 101416 101544 101672 101800 101928 102056 102184 102312 102440 106536 106664 106792 106920 107048 107176 107304 107432 107560 107688 107816 107944 108072 108200 108328 108456 108584 108712 108840 108968 109096 109224 109352 109480 109608 109736 109864 109992 110120 110248 110376 110504 110632 114728 114856 114984 115112 115240 115368 115496 115624 115752 115880 116008 116136 116264 116392 116520 116648 116776 116904 117032 117160 117288 117416 117544 117672 117800 117928 118056 118184 118312 118440 118568 118696 118824 98346 98474 98602 98730 98858 98986 99114 99242 99370 99498 99626 99754 99882 100010 100138 100266 100394 100522 100650 100778 100906 101034 101162 101290 101418 101546 101674 101802 101930 102058 102186 102314 102442 106538 106666 106794 106922 107050 107178 107306 107434 107562 107690 107818 107946 108074 108202 108330 108458 108586 108714 108842 108970 109098 109226 109354 109482 109610 109738 109866 109994 110122 110250 110378 110506 110634 114730 114858 114986 115114 115242 115370 115498 115626 115754 115882 116010 116138 116266 116394 116522 116650 116778 116906 117034 117162 117290 117418 117546 117674 117802 117930 118058 118186 118314 118442 118570 118698 118826 98348 98476 98604 98732 98860 98988 99116 99244 99372 99500 99628 99756 99884 100012 100140 100268 100396 100524 100652 100780 100908 101036 101164 101292 101420 101548 101676 101804 101932 102060 102188 102316 102444 106540 106668 106796 106924 107052 107180 107308 107436 107564 107692 107820 107948 108076 108204 108332 108460 108588 108716 108844 108972 109100 109228 109356 109484 109612 109740 109868 109996 110124 110252 110380 110508 110636 114732 114860 114988 115116 115244 115372 115500 115628 115756 115884 116012 116140 116268 116396 116524 116652 116780 116908 117036 117164 117292 117420 117548 117676 117804 117932 118060 118188 118316 118444 118572 118700 118828 98350 98478 98606 98734 98862 98990 99118 99246 99374 99502 99630 99758 99886 100014 100142 100270 100398 100526 100654 100782 100910 101038 101166 101294 101422 101550 101678 101806 101934 102062 102190 102318 102446 106542 106670 106798 106926 107054 107182 107310 107438 107566 107694 107822 107950 108078 108206 108334 108462 108590 108718 108846 108974 109102 109230 109358 109486 109614 109742 109870 109998 110126 110254 110382 110510 110638 114734 114862 114990 115118 115246 115374 115502 115630 115758 115886 116014 116142 116270 116398 116526 116654 116782 116910 117038 117166 117294 117422 117550 117678 117806 117934 118062 118190 118318 118446 118574 118702 118830 98352 98480 98608 98736 98864 98992 99120 99248 99376 99504 99632 99760 99888 100016 100144 100272 100400 100528 100656 100784 100912 101040 101168 101296 101424 101552 101680 101808 101936 102064 102192 102320 102448 106544 106672 106800 106928 107056 107184 107312 107440 107568 107696 107824 107952 108080 108208 108336 108464 108592 108720 108848 108976 109104 109232 109360 109488 109616 109744 109872 110000 110128 110256 110384 110512 110640 114736 114864 114992 115120 115248 115376 115504 115632 115760 115888 116016 116144 116272 116400 116528 116656 116784 116912 117040 117168 117296 117424 117552 117680 117808 117936 118064 118192 118320 118448 118576 118704 118832 98354 98482 98610 98738 98866 98994 99122 99250 99378 99506 99634 99762 99890 100018 100146 100274 100402 100530 100658 100786 100914 101042 101170 101298 101426 101554 101682 101810 101938 102066 102194 102322 102450 106546 106674 106802 106930 107058 107186 107314 107442 107570 107698 107826 107954 108082 108210 108338 108466 108594 108722 108850 108978 109106 109234 109362 109490 109618 109746 109874 110002 110130 110258 110386 110514 110642 114738 114866 114994 115122 115250 115378 115506 115634 115762 115890 116018 116146 116274 116402 116530 116658 116786 116914 117042 117170 117298 117426 117554 117682 117810 117938 118066 118194 118322 118450 118578 118706 118834 98356 98484 98612 98740 98868 98996 99124 99252 99380 99508 99636 99764 99892 100020 100148 100276 100404 100532 100660 100788 100916 101044 101172 101300 101428 101556 101684 101812 101940 102068 102196 102324 102452 106548 106676 106804 106932 107060 107188 107316 107444 107572 107700 107828 107956 108084 108212 108340 108468 108596 108724 108852 108980 109108 109236 109364 109492 109620 109748 109876 110004 110132 110260 110388 110516 110644 114740 114868 114996 115124 115252 115380 115508 115636 115764 115892 116020 116148 116276 116404 116532 116660 116788 116916 117044 117172 117300 117428 117556 117684 117812 117940 118068 118196 118324 118452 118580 118708 118836 98358 98486 98614 98742 98870 98998 99126 99254 99382 99510 99638 99766 99894 100022 100150 100278 100406 100534 100662 100790 100918 101046 101174 101302 101430 101558 101686 101814 101942 102070 102198 102326 102454 106550 106678 106806 106934 107062 107190 107318 107446 107574 107702 107830 107958 108086 108214 108342 108470 108598 108726 108854 108982 109110 109238 109366 109494 109622 109750 109878 110006 110134 110262 110390 110518 110646 114742 114870 114998 115126 115254 115382 115510 115638 115766 115894 116022 116150 116278 116406 116534 116662 116790 116918 117046 117174 117302 117430 117558 117686 117814 117942 118070 118198 118326 118454 118582 118710 118838 98360 98488 98616 98744 98872 99000 99128 99256 99384 99512 99640 99768 99896 100024 100152 100280 100408 100536 100664 100792 100920 101048 101176 101304 101432 101560 101688 101816 101944 102072 102200 102328 102456 106552 106680 106808 106936 107064 107192 107320 107448 107576 107704 107832 107960 108088 108216 108344 108472 108600 108728 108856 108984 109112 109240 109368 109496 109624 109752 109880 110008 110136 110264 110392 110520 110648 114744 114872 115000 115128 115256 115384 115512 115640 115768 115896 116024 116152 116280 116408 116536 116664 116792 116920 117048 117176 117304 117432 117560 117688 117816 117944 118072 118200 118328 118456 118584 118712 118840 98362 98490 98618 98746 98874 99002 99130 99258 99386 99514 99642 99770 99898 100026 100154 100282 100410 100538 100666 100794 100922 101050 101178 101306 101434 101562 101690 101818 101946 102074 102202 102330 102458 106554 106682 106810 106938 107066 107194 107322 107450 107578 107706 107834 107962 108090 108218 108346 108474 108602 108730 108858 108986 109114 109242 109370 109498 109626 109754 109882 110010 110138 110266 110394 110522 110650 114746 114874 115002 115130 115258 115386 115514 115642 115770 115898 116026 116154 116282 116410 116538 116666 116794 116922 117050 117178 117306 117434 117562 117690 117818 117946 118074 118202 118330 118458 118586 118714 118842 98364 98492 98620 98748 98876 99004 99132 99260 99388 99516 99644 99772 99900 100028 100156 100284 100412 100540 100668 100796 100924 101052 101180 101308 101436 101564 101692 101820 101948 102076 102204 102332 102460 106556 106684 106812 106940 107068 107196 107324 107452 107580 107708 107836 107964 108092 108220 108348 108476 108604 108732 108860 108988 109116 109244 109372 109500 109628 109756 109884 110012 110140 110268 110396 110524 110652 114748 114876 115004 115132 115260 115388 115516 115644 115772 115900 116028 116156 116284 116412 116540 116668 116796 116924 117052 117180 117308 117436 117564 117692 117820 117948 118076 118204 118332 118460 118588 118716 118844 98366 98494 98622 98750 98878 99006 99134 99262 99390 99518 99646 99774 99902 100030 100158 100286 100414 100542 100670 100798 100926 101054 101182 101310 101438 101566 101694 101822 101950 102078 102206 102334 102462 106558 106686 106814 106942 107070 107198 107326 107454 107582 107710 107838 107966 108094 108222 108350 108478 108606 108734 108862 108990 109118 109246 109374 109502 109630 109758 109886 110014 110142 110270 110398 110526 110654 114750 114878 115006 115134 115262 115390 115518 115646 115774 115902 116030 116158 116286 116414 116542 116670 116798 116926 117054 117182 117310 117438 117566 117694 117822 117950 118078 118206 118334 118462 118590 118718 118846 98368 98496 98624 98752 98880 99008 99136 99264 99392 99520 99648 99776 99904 100032 100160 100288 100416 100544 100672 100800 100928 101056 101184 101312 101440 101568 101696 101824 101952 102080 102208 102336 102464 106560 106688 106816 106944 107072 107200 107328 107456 107584 107712 107840 107968 108096 108224 108352 108480 108608 108736 108864 108992 109120 109248 109376 109504 109632 109760 109888 110016 110144 110272 110400 110528 110656 114752 114880 115008 115136 115264 115392 115520 115648 115776 115904 116032 116160 116288 116416 116544 116672 116800 116928 117056 117184 117312 117440 117568 117696 117824 117952 118080 118208 118336 118464 118592 118720 118848 98370 98498 98626 98754 98882 99010 99138 99266 99394 99522 99650 99778 99906 100034 100162 100290 100418 100546 100674 100802 100930 101058 101186 101314 101442 101570 101698 101826 101954 102082 102210 102338 102466 106562 106690 106818 106946 107074 107202 107330 107458 107586 107714 107842 107970 108098 108226 108354 108482 108610 108738 108866 108994 109122 109250 109378 109506 109634 109762 109890 110018 110146 110274 110402 110530 110658 114754 114882 115010 115138 115266 115394 115522 115650 115778 115906 116034 116162 116290 116418 116546 116674 116802 116930 117058 117186 117314 117442 117570 117698 117826 117954 118082 118210 118338 118466 118594 118722 118850 98372 98500 98628 98756 98884 99012 99140 99268 99396 99524 99652 99780 99908 100036 100164 100292 100420 100548 100676 100804 100932 101060 101188 101316 101444 101572 101700 101828 101956 102084 102212 102340 102468 106564 106692 106820 106948 107076 107204 107332 107460 107588 107716 107844 107972 108100 108228 108356 108484 108612 108740 108868 108996 109124 109252 109380 109508 109636 109764 109892 110020 110148 110276 110404 110532 110660 114756 114884 115012 115140 115268 115396 115524 115652 115780 115908 116036 116164 116292 116420 116548 116676 116804 116932 117060 117188 117316 117444 117572 117700 117828 117956 118084 118212 118340 118468 118596 118724 118852 98374 98502 98630 98758 98886 99014 99142 99270 99398 99526 99654 99782 99910 100038 100166 100294 100422 100550 100678 100806 100934 101062 101190 101318 101446 101574 101702 101830 101958 102086 102214 102342 102470 106566 106694 106822 106950 107078 107206 107334 107462 107590 107718 107846 107974 108102 108230 108358 108486 108614 108742 108870 108998 109126 109254 109382 109510 109638 109766 109894 110022 110150 110278 110406 110534 110662 114758 114886 115014 115142 115270 115398 115526 115654 115782 115910 116038 116166 116294 116422 116550 116678 116806 116934 117062 117190 117318 117446 117574 117702 117830 117958 118086 118214 118342 118470 118598 118726 118854 98376 98504 98632 98760 98888 99016 99144 99272 99400 99528 99656 99784 99912 100040 100168 100296 100424 100552 100680 100808 100936 101064 101192 101320 101448 101576 101704 101832 101960 102088 102216 102344 102472 106568 106696 106824 106952 107080 107208 107336 107464 107592 107720 107848 107976 108104 108232 108360 108488 108616 108744 108872 109000 109128 109256 109384 109512 109640 109768 109896 110024 110152 110280 110408 110536 110664 114760 114888 115016 115144 115272 115400 115528 115656 115784 115912 116040 116168 116296 116424 116552 116680 116808 116936 117064 117192 117320 117448 117576 117704 117832 117960 118088 118216 118344 118472 118600 118728 118856 98378 98506 98634 98762 98890 99018 99146 99274 99402 99530 99658 99786 99914 100042 100170 100298 100426 100554 100682 100810 100938 101066 101194 101322 101450 101578 101706 101834 101962 102090 102218 102346 102474 106570 106698 106826 106954 107082 107210 107338 107466 107594 107722 107850 107978 108106 108234 108362 108490 108618 108746 108874 109002 109130 109258 109386 109514 109642 109770 109898 110026 110154 110282 110410 110538 110666 114762 114890 115018 115146 115274 115402 115530 115658 115786 115914 116042 116170 116298 116426 116554 116682 116810 116938 117066 117194 117322 117450 117578 117706 117834 117962 118090 118218 118346 118474 118602 118730 118858 98380 98508 98636 98764 98892 99020 99148 99276 99404 99532 99660 99788 99916 100044 100172 100300 100428 100556 100684 100812 100940 101068 101196 101324 101452 101580 101708 101836 101964 102092 102220 102348 102476 106572 106700 106828 106956 107084 107212 107340 107468 107596 107724 107852 107980 108108 108236 108364 108492 108620 108748 108876 109004 109132 109260 109388 109516 109644 109772 109900 110028 110156 110284 110412 110540 110668 114764 114892 115020 115148 115276 115404 115532 115660 115788 115916 116044 116172 116300 116428 116556 116684 116812 116940 117068 117196 117324 117452 117580 117708 117836 117964 118092 118220 118348 118476 118604 118732 118860 98382 98510 98638 98766 98894 99022 99150 99278 99406 99534 99662 99790 99918 100046 100174 100302 100430 100558 100686 100814 100942 101070 101198 101326 101454 101582 101710 101838 101966 102094 102222 102350 102478 106574 106702 106830 106958 107086 107214 107342 107470 107598 107726 107854 107982 108110 108238 108366 108494 108622 108750 108878 109006 109134 109262 109390 109518 109646 109774 109902 110030 110158 110286 110414 110542 110670 114766 114894 115022 115150 115278 115406 115534 115662 115790 115918 116046 116174 116302 116430 116558 116686 116814 116942 117070 117198 117326 117454 117582 117710 117838 117966 118094 118222 118350 118478 118606 118734 118862 98384 98512 98640 98768 98896 99024 99152 99280 99408 99536 99664 99792 99920 100048 100176 100304 100432 100560 100688 100816 100944 101072 101200 101328 101456 101584 101712 101840 101968 102096 102224 102352 102480 106576 106704 106832 106960 107088 107216 107344 107472 107600 107728 107856 107984 108112 108240 108368 108496 108624 108752 108880 109008 109136 109264 109392 109520 109648 109776 109904 110032 110160 110288 110416 110544 110672 114768 114896 115024 115152 115280 115408 115536 115664 115792 115920 116048 116176 116304 116432 116560 116688 116816 116944 117072 117200 117328 117456 117584 117712 117840 117968 118096 118224 118352 118480 118608 118736 118864 98386 98514 98642 98770 98898 99026 99154 99282 99410 99538 99666 99794 99922 100050 100178 100306 100434 100562 100690 100818 100946 101074 101202 101330 101458 101586 101714 101842 101970 102098 102226 102354 102482 106578 106706 106834 106962 107090 107218 107346 107474 107602 107730 107858 107986 108114 108242 108370 108498 108626 108754 108882 109010 109138 109266 109394 109522 109650 109778 109906 110034 110162 110290 110418 110546 110674 114770 114898 115026 115154 115282 115410 115538 115666 115794 115922 116050 116178 116306 116434 116562 116690 116818 116946 117074 117202 117330 117458 117586 117714 117842 117970 118098 118226 118354 118482 118610 118738 118866 98388 98516 98644 98772 98900 99028 99156 99284 99412 99540 99668 99796 99924 100052 100180 100308 100436 100564 100692 100820 100948 101076 101204 101332 101460 101588 101716 101844 101972 102100 102228 102356 102484 106580 106708 106836 106964 107092 107220 107348 107476 107604 107732 107860 107988 108116 108244 108372 108500 108628 108756 108884 109012 109140 109268 109396 109524 109652 109780 109908 110036 110164 110292 110420 110548 110676 114772 114900 115028 115156 115284 115412 115540 115668 115796 115924 116052 116180 116308 116436 116564 116692 116820 116948 117076 117204 117332 117460 117588 117716 117844 117972 118100 118228 118356 118484 118612 118740 118868 98390 98518 98646 98774 98902 99030 99158 99286 99414 99542 99670 99798 99926 100054 100182 100310 100438 100566 100694 100822 100950 101078 101206 101334 101462 101590 101718 101846 101974 102102 102230 102358 102486 106582 106710 106838 106966 107094 107222 107350 107478 107606 107734 107862 107990 108118 108246 108374 108502 108630 108758 108886 109014 109142 109270 109398 109526 109654 109782 109910 110038 110166 110294 110422 110550 110678 114774 114902 115030 115158 115286 115414 115542 115670 115798 115926 116054 116182 116310 116438 116566 116694 116822 116950 117078 117206 117334 117462 117590 117718 117846 117974 118102 118230 118358 118486 118614 118742 118870 98392 98520 98648 98776 98904 99032 99160 99288 99416 99544 99672 99800 99928 100056 100184 100312 100440 100568 100696 100824 100952 101080 101208 101336 101464 101592 101720 101848 101976 102104 102232 102360 102488 106584 106712 106840 106968 107096 107224 107352 107480 107608 107736 107864 107992 108120 108248 108376 108504 108632 108760 108888 109016 109144 109272 109400 109528 109656 109784 109912 110040 110168 110296 110424 110552 110680 114776 114904 115032 115160 115288 115416 115544 115672 115800 115928 116056 116184 116312 116440 116568 116696 116824 116952 117080 117208 117336 117464 117592 117720 117848 117976 118104 118232 118360 118488 118616 118744 118872 98394 98522 98650 98778 98906 99034 99162 99290 99418 99546 99674 99802 99930 100058 100186 100314 100442 100570 100698 100826 100954 101082 101210 101338 101466 101594 101722 101850 101978 102106 102234 102362 102490 106586 106714 106842 106970 107098 107226 107354 107482 107610 107738 107866 107994 108122 108250 108378 108506 108634 108762 108890 109018 109146 109274 109402 109530 109658 109786 109914 110042 110170 110298 110426 110554 110682 114778 114906 115034 115162 115290 115418 115546 115674 115802 115930 116058 116186 116314 116442 116570 116698 116826 116954 117082 117210 117338 117466 117594 117722 117850 117978 118106 118234 118362 118490 118618 118746 118874 98396 98524 98652 98780 98908 99036 99164 99292 99420 99548 99676 99804 99932 100060 100188 100316 100444 100572 100700 100828 100956 101084 101212 101340 101468 101596 101724 101852 101980 102108 102236 102364 102492 106588 106716 106844 106972 107100 107228 107356 107484 107612 107740 107868 107996 108124 108252 108380 108508 108636 108764 108892 109020 109148 109276 109404 109532 109660 109788 109916 110044 110172 110300 110428 110556 110684 114780 114908 115036 115164 115292 115420 115548 115676 115804 115932 116060 116188 116316 116444 116572 116700 116828 116956 117084 117212 117340 117468 117596 117724 117852 117980 118108 118236 118364 118492 118620 118748 118876 98398 98526 98654 98782 98910 99038 99166 99294 99422 99550 99678 99806 99934 100062 100190 100318 100446 100574 100702 100830 100958 101086 101214 101342 101470 101598 101726 101854 101982 102110 102238 102366 102494 106590 106718 106846 106974 107102 107230 107358 107486 107614 107742 107870 107998 108126 108254 108382 108510 108638 108766 108894 109022 109150 109278 109406 109534 109662 109790 109918 110046 110174 110302 110430 110558 110686 114782 114910 115038 115166 115294 115422 115550 115678 115806 115934 116062 116190 116318 116446 116574 116702 116830 116958 117086 117214 117342 117470 117598 117726 117854 117982 118110 118238 118366 118494 118622 118750 118878 98400 98528 98656 98784 98912 99040 99168 99296 99424 99552 99680 99808 99936 100064 100192 100320 100448 100576 100704 100832 100960 101088 101216 101344 101472 101600 101728 101856 101984 102112 102240 102368 102496 106592 106720 106848 106976 107104 107232 107360 107488 107616 107744 107872 108000 108128 108256 108384 108512 108640 108768 108896 109024 109152 109280 109408 109536 109664 109792 109920 110048 110176 110304 110432 110560 110688 114784 114912 115040 115168 115296 115424 115552 115680 115808 115936 116064 116192 116320 116448 116576 116704 116832 116960 117088 117216 117344 117472 117600 117728 117856 117984 118112 118240 118368 118496 118624 118752 118880 98402 98530 98658 98786 98914 99042 99170 99298 99426 99554 99682 99810 99938 100066 100194 100322 100450 100578 100706 100834 100962 101090 101218 101346 101474 101602 101730 101858 101986 102114 102242 102370 102498 106594 106722 106850 106978 107106 107234 107362 107490 107618 107746 107874 108002 108130 108258 108386 108514 108642 108770 108898 109026 109154 109282 109410 109538 109666 109794 109922 110050 110178 110306 110434 110562 110690 114786 114914 115042 115170 115298 115426 115554 115682 115810 115938 116066 116194 116322 116450 116578 116706 116834 116962 117090 117218 117346 117474 117602 117730 117858 117986 118114 118242 118370 118498 118626 118754 118882 98404 98532 98660 98788 98916 99044 99172 99300 99428 99556 99684 99812 99940 100068 100196 100324 100452 100580 100708 100836 100964 101092 101220 101348 101476 101604 101732 101860 101988 102116 102244 102372 102500 106596 106724 106852 106980 107108 107236 107364 107492 107620 107748 107876 108004 108132 108260 108388 108516 108644 108772 108900 109028 109156 109284 109412 109540 109668 109796 109924 110052 110180 110308 110436 110564 110692 114788 114916 115044 115172 115300 115428 115556 115684 115812 115940 116068 116196 116324 116452 116580 116708 116836 116964 117092 117220 117348 117476 117604 117732 117860 117988 118116 118244 118372 118500 118628 118756 118884 98406 98534 98662 98790 98918 99046 99174 99302 99430 99558 99686 99814 99942 100070 100198 100326 100454 100582 100710 100838 100966 101094 101222 101350 101478 101606 101734 101862 101990 102118 102246 102374 102502 106598 106726 106854 106982 107110 107238 107366 107494 107622 107750 107878 108006 108134 108262 108390 108518 108646 108774 108902 109030 109158 109286 109414 109542 109670 109798 109926 110054 110182 110310 110438 110566 110694 114790 114918 115046 115174 115302 115430 115558 115686 115814 115942 116070 116198 116326 116454 116582 116710 116838 116966 117094 117222 117350 117478 117606 117734 117862 117990 118118 118246 118374 118502 118630 118758 118886 98408 98536 98664 98792 98920 99048 99176 99304 99432 99560 99688 99816 99944 100072 100200 100328 100456 100584 100712 100840 100968 101096 101224 101352 101480 101608 101736 101864 101992 102120 102248 102376 102504 106600 106728 106856 106984 107112 107240 107368 107496 107624 107752 107880 108008 108136 108264 108392 108520 108648 108776 108904 109032 109160 109288 109416 109544 109672 109800 109928 110056 110184 110312 110440 110568 110696 114792 114920 115048 115176 115304 115432 115560 115688 115816 115944 116072 116200 116328 116456 116584 116712 116840 116968 117096 117224 117352 117480 117608 117736 117864 117992 118120 118248 118376 118504 118632 118760 118888 98410 98538 98666 98794 98922 99050 99178 99306 99434 99562 99690 99818 99946 100074 100202 100330 100458 100586 100714 100842 100970 101098 101226 101354 101482 101610 101738 101866 101994 102122 102250 102378 102506 106602 106730 106858 106986 107114 107242 107370 107498 107626 107754 107882 108010 108138 108266 108394 108522 108650 108778 108906 109034 109162 109290 109418 109546 109674 109802 109930 110058 110186 110314 110442 110570 110698 114794 114922 115050 115178 115306 115434 115562 115690 115818 115946 116074 116202 116330 116458 116586 116714 116842 116970 117098 117226 117354 117482 117610 117738 117866 117994 118122 118250 118378 118506 118634 118762 118890 98412 98540 98668 98796 98924 99052 99180 99308 99436 99564 99692 99820 99948 100076 100204 100332 100460 100588 100716 100844 100972 101100 101228 101356 101484 101612 101740 101868 101996 102124 102252 102380 102508 106604 106732 106860 106988 107116 107244 107372 107500 107628 107756 107884 108012 108140 108268 108396 108524 108652 108780 108908 109036 109164 109292 109420 109548 109676 109804 109932 110060 110188 110316 110444 110572 110700 114796 114924 115052 115180 115308 115436 115564 115692 115820 115948 116076 116204 116332 116460 116588 116716 116844 116972 117100 117228 117356 117484 117612 117740 117868 117996 118124 118252 118380 118508 118636 118764 118892 98414 98542 98670 98798 98926 99054 99182 99310 99438 99566 99694 99822 99950 100078 100206 100334 100462 100590 100718 100846 100974 101102 101230 101358 101486 101614 101742 101870 101998 102126 102254 102382 102510 106606 106734 106862 106990 107118 107246 107374 107502 107630 107758 107886 108014 108142 108270 108398 108526 108654 108782 108910 109038 109166 109294 109422 109550 109678 109806 109934 110062 110190 110318 110446 110574 110702 114798 114926 115054 115182 115310 115438 115566 115694 115822 115950 116078 116206 116334 116462 116590 116718 116846 116974 117102 117230 117358 117486 117614 117742 117870 117998 118126 118254 118382 118510 118638 118766 118894 98416 98544 98672 98800 98928 99056 99184 99312 99440 99568 99696 99824 99952 100080 100208 100336 100464 100592 100720 100848 100976 101104 101232 101360 101488 101616 101744 101872 102000 102128 102256 102384 102512 106608 106736 106864 106992 107120 107248 107376 107504 107632 107760 107888 108016 108144 108272 108400 108528 108656 108784 108912 109040 109168 109296 109424 109552 109680 109808 109936 110064 110192 110320 110448 110576 110704 114800 114928 115056 115184 115312 115440 115568 115696 115824 115952 116080 116208 116336 116464 116592 116720 116848 116976 117104 117232 117360 117488 117616 117744 117872 118000 118128 118256 118384 118512 118640 118768 118896 98418 98546 98674 98802 98930 99058 99186 99314 99442 99570 99698 99826 99954 100082 100210 100338 100466 100594 100722 100850 100978 101106 101234 101362 101490 101618 101746 101874 102002 102130 102258 102386 102514 106610 106738 106866 106994 107122 107250 107378 107506 107634 107762 107890 108018 108146 108274 108402 108530 108658 108786 108914 109042 109170 109298 109426 109554 109682 109810 109938 110066 110194 110322 110450 110578 110706 114802 114930 115058 115186 115314 115442 115570 115698 115826 115954 116082 116210 116338 116466 116594 116722 116850 116978 117106 117234 117362 117490 117618 117746 117874 118002 118130 118258 118386 118514 118642 118770 118898 98420 98548 98676 98804 98932 99060 99188 99316 99444 99572 99700 99828 99956 100084 100212 100340 100468 100596 100724 100852 100980 101108 101236 101364 101492 101620 101748 101876 102004 102132 102260 102388 102516 106612 106740 106868 106996 107124 107252 107380 107508 107636 107764 107892 108020 108148 108276 108404 108532 108660 108788 108916 109044 109172 109300 109428 109556 109684 109812 109940 110068 110196 110324 110452 110580 110708 114804 114932 115060 115188 115316 115444 115572 115700 115828 115956 116084 116212 116340 116468 116596 116724 116852 116980 117108 117236 117364 117492 117620 117748 117876 118004 118132 118260 118388 118516 118644 118772 118900 98422 98550 98678 98806 98934 99062 99190 99318 99446 99574 99702 99830 99958 100086 100214 100342 100470 100598 100726 100854 100982 101110 101238 101366 101494 101622 101750 101878 102006 102134 102262 102390 102518 106614 106742 106870 106998 107126 107254 107382 107510 107638 107766 107894 108022 108150 108278 108406 108534 108662 108790 108918 109046 109174 109302 109430 109558 109686 109814 109942 110070 110198 110326 110454 110582 110710 114806 114934 115062 115190 115318 115446 115574 115702 115830 115958 116086 116214 116342 116470 116598 116726 116854 116982 117110 117238 117366 117494 117622 117750 117878 118006 118134 118262 118390 118518 118646 118774 118902 98424 98552 98680 98808 98936 99064 99192 99320 99448 99576 99704 99832 99960 100088 100216 100344 100472 100600 100728 100856 100984 101112 101240 101368 101496 101624 101752 101880 102008 102136 102264 102392 102520 106616 106744 106872 107000 107128 107256 107384 107512 107640 107768 107896 108024 108152 108280 108408 108536 108664 108792 108920 109048 109176 109304 109432 109560 109688 109816 109944 110072 110200 110328 110456 110584 110712 114808 114936 115064 115192 115320 115448 115576 115704 115832 115960 116088 116216 116344 116472 116600 116728 116856 116984 117112 117240 117368 117496 117624 117752 117880 118008 118136 118264 118392 118520 118648 118776 118904 98426 98554 98682 98810 98938 99066 99194 99322 99450 99578 99706 99834 99962 100090 100218 100346 100474 100602 100730 100858 100986 101114 101242 101370 101498 101626 101754 101882 102010 102138 102266 102394 102522 106618 106746 106874 107002 107130 107258 107386 107514 107642 107770 107898 108026 108154 108282 108410 108538 108666 108794 108922 109050 109178 109306 109434 109562 109690 109818 109946 110074 110202 110330 110458 110586 110714 114810 114938 115066 115194 115322 115450 115578 115706 115834 115962 116090 116218 116346 116474 116602 116730 116858 116986 117114 117242 117370 117498 117626 117754 117882 118010 118138 118266 118394 118522 118650 118778 118906 98428 98556 98684 98812 98940 99068 99196 99324 99452 99580 99708 99836 99964 100092 100220 100348 100476 100604 100732 100860 100988 101116 101244 101372 101500 101628 101756 101884 102012 102140 102268 102396 102524 106620 106748 106876 107004 107132 107260 107388 107516 107644 107772 107900 108028 108156 108284 108412 108540 108668 108796 108924 109052 109180 109308 109436 109564 109692 109820 109948 110076 110204 110332 110460 110588 110716 114812 114940 115068 115196 115324 115452 115580 115708 115836 115964 116092 116220 116348 116476 116604 116732 116860 116988 117116 117244 117372 117500 117628 117756 117884 118012 118140 118268 118396 118524 118652 118780 118908 98430 98558 98686 98814 98942 99070 99198 99326 99454 99582 99710 99838 99966 100094 100222 100350 100478 100606 100734 100862 100990 101118 101246 101374 101502 101630 101758 101886 102014 102142 102270 102398 102526 106622 106750 106878 107006 107134 107262 107390 107518 107646 107774 107902 108030 108158 108286 108414 108542 108670 108798 108926 109054 109182 109310 109438 109566 109694 109822 109950 110078 110206 110334 110462 110590 110718 114814 114942 115070 115198 115326 115454 115582 115710 115838 115966 116094 116222 116350 116478 116606 116734 116862 116990 117118 117246 117374 117502 117630 117758 117886 118014 118142 118270 118398 118526 118654 118782 118910 122880 123008 123136 123264 123392 123520 123648 123776 123904 124032 124160 124288 124416 124544 124672 124800 124928 125056 125184 125312 125440 125568 125696 125824 125952 126080 126208 126336 126464 126592 126720 126848 126976 131072 131200 131328 131456 131584 131712 131840 131968 132096 132224 132352 132480 132608 132736 132864 132992 133120 133248 133376 133504 133632 133760 133888 134016 134144 134272 134400 134528 134656 134784 134912 135040 135168 139264 139392 139520 139648 139776 139904 140032 140160 140288 140416 140544 140672 140800 140928 141056 141184 141312 141440 141568 141696 141824 141952 142080 142208 142336 142464 142592 142720 142848 142976 143104 143232 143360 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x31x64.txt������������������������������������������0000664�0000000�0000000�00000022225�14364043643�0023247�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x32x63.txt������������������������������������������0000664�0000000�0000000�00000022474�14364043643�0023255�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x32x64.txt������������������������������������������0000664�0000000�0000000�00000022725�14364043643�0023255�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 4094 �������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x32x65.txt������������������������������������������0000664�0000000�0000000�00000023165�14364043643�0023255�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 4096 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 4224 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 4352 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 4480 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 4608 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 4736 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 4864 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 4992 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 5120 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 5248 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 5376 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 5504 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 5632 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 5760 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 5888 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 6016 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 6144 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 6272 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 6400 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 6528 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 6656 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 6784 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 6912 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 7040 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 7168 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 7296 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 7424 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 7552 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 7680 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 7808 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 7936 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 4094 8064 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x33x64.txt������������������������������������������0000664�0000000�0000000�00000023425�14364043643�0023254�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 4094 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 4222 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x4x127.txt������������������������������������������0000664�0000000�0000000�00000004265�14364043643�0023253�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 4224 4226 4228 4230 4232 4234 4236 4238 4240 4242 4244 4246 4248 4250 4252 4254 4256 4258 4260 4262 4264 4266 4268 4270 4272 4274 4276 4278 4280 4282 4284 4286 4288 4290 4292 4294 4296 4298 4300 4302 4304 4306 4308 4310 4312 4314 4316 4318 4320 4322 4324 4326 4328 4330 4332 4334 4336 4338 4340 4342 4344 4346 4348 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 4352 4354 4356 4358 4360 4362 4364 4366 4368 4370 4372 4374 4376 4378 4380 4382 4384 4386 4388 4390 4392 4394 4396 4398 4400 4402 4404 4406 4408 4410 4412 4414 4416 4418 4420 4422 4424 4426 4428 4430 4432 4434 4436 4438 4440 4442 4444 4446 4448 4450 4452 4454 4456 4458 4460 4462 4464 4466 4468 4470 4472 4474 4476 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 4480 4482 4484 4486 4488 4490 4492 4494 4496 4498 4500 4502 4504 4506 4508 4510 4512 4514 4516 4518 4520 4522 4524 4526 4528 4530 4532 4534 4536 4538 4540 4542 4544 4546 4548 4550 4552 4554 4556 4558 4560 4562 4564 4566 4568 4570 4572 4574 4576 4578 4580 4582 4584 4586 4588 4590 4592 4594 4596 4598 4600 4602 4604 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x4x128.txt������������������������������������������0000664�0000000�0000000�00000004311�14364043643�0023244�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 4222 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 4224 4226 4228 4230 4232 4234 4236 4238 4240 4242 4244 4246 4248 4250 4252 4254 4256 4258 4260 4262 4264 4266 4268 4270 4272 4274 4276 4278 4280 4282 4284 4286 4288 4290 4292 4294 4296 4298 4300 4302 4304 4306 4308 4310 4312 4314 4316 4318 4320 4322 4324 4326 4328 4330 4332 4334 4336 4338 4340 4342 4344 4346 4348 4350 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 4352 4354 4356 4358 4360 4362 4364 4366 4368 4370 4372 4374 4376 4378 4380 4382 4384 4386 4388 4390 4392 4394 4396 4398 4400 4402 4404 4406 4408 4410 4412 4414 4416 4418 4420 4422 4424 4426 4428 4430 4432 4434 4436 4438 4440 4442 4444 4446 4448 4450 4452 4454 4456 4458 4460 4462 4464 4466 4468 4470 4472 4474 4476 4478 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 4480 4482 4484 4486 4488 4490 4492 4494 4496 4498 4500 4502 4504 4506 4508 4510 4512 4514 4516 4518 4520 4522 4524 4526 4528 4530 4532 4534 4536 4538 4540 4542 4544 4546 4548 4550 4552 4554 4556 4558 4560 4562 4564 4566 4568 4570 4572 4574 4576 4578 4580 4582 4584 4586 4588 4590 4592 4594 4596 4598 4600 4602 4604 4606 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x4x129.txt������������������������������������������0000664�0000000�0000000�00000004335�14364043643�0023253�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 4222 8192 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 4224 4226 4228 4230 4232 4234 4236 4238 4240 4242 4244 4246 4248 4250 4252 4254 4256 4258 4260 4262 4264 4266 4268 4270 4272 4274 4276 4278 4280 4282 4284 4286 4288 4290 4292 4294 4296 4298 4300 4302 4304 4306 4308 4310 4312 4314 4316 4318 4320 4322 4324 4326 4328 4330 4332 4334 4336 4338 4340 4342 4344 4346 4348 4350 8320 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 4352 4354 4356 4358 4360 4362 4364 4366 4368 4370 4372 4374 4376 4378 4380 4382 4384 4386 4388 4390 4392 4394 4396 4398 4400 4402 4404 4406 4408 4410 4412 4414 4416 4418 4420 4422 4424 4426 4428 4430 4432 4434 4436 4438 4440 4442 4444 4446 4448 4450 4452 4454 4456 4458 4460 4462 4464 4466 4468 4470 4472 4474 4476 4478 8448 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 4480 4482 4484 4486 4488 4490 4492 4494 4496 4498 4500 4502 4504 4506 4508 4510 4512 4514 4516 4518 4520 4522 4524 4526 4528 4530 4532 4534 4536 4538 4540 4542 4544 4546 4548 4550 4552 4554 4556 4558 4560 4562 4564 4566 4568 4570 4572 4574 4576 4578 4580 4582 4584 4586 4588 4590 4592 4594 4596 4598 4600 4602 4604 4606 8576 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x63x4.txt�������������������������������������������0000664�0000000�0000000�00000002304�14364043643�0023162�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 128 130 132 134 256 258 260 262 384 386 388 390 512 514 516 518 640 642 644 646 768 770 772 774 896 898 900 902 1024 1026 1028 1030 1152 1154 1156 1158 1280 1282 1284 1286 1408 1410 1412 1414 1536 1538 1540 1542 1664 1666 1668 1670 1792 1794 1796 1798 1920 1922 1924 1926 2048 2050 2052 2054 2176 2178 2180 2182 2304 2306 2308 2310 2432 2434 2436 2438 2560 2562 2564 2566 2688 2690 2692 2694 2816 2818 2820 2822 2944 2946 2948 2950 3072 3074 3076 3078 3200 3202 3204 3206 3328 3330 3332 3334 3456 3458 3460 3462 3584 3586 3588 3590 3712 3714 3716 3718 3840 3842 3844 3846 3968 3970 3972 3974 4096 4098 4100 4102 4224 4226 4228 4230 4352 4354 4356 4358 4480 4482 4484 4486 4608 4610 4612 4614 4736 4738 4740 4742 4864 4866 4868 4870 4992 4994 4996 4998 5120 5122 5124 5126 5248 5250 5252 5254 5376 5378 5380 5382 5504 5506 5508 5510 5632 5634 5636 5638 5760 5762 5764 5766 5888 5890 5892 5894 6016 6018 6020 6022 6144 6146 6148 6150 6272 6274 6276 6278 6400 6402 6404 6406 6528 6530 6532 6534 6656 6658 6660 6662 6784 6786 6788 6790 6912 6914 6916 6918 7040 7042 7044 7046 7168 7170 7172 7174 7296 7298 7300 7302 7424 7426 7428 7430 7552 7554 7556 7558 7680 7682 7684 7686 7808 7810 7812 7814 7936 7938 7940 7942 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x64x4.txt�������������������������������������������0000664�0000000�0000000�00000002330�14364043643�0023162�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 128 130 132 134 256 258 260 262 384 386 388 390 512 514 516 518 640 642 644 646 768 770 772 774 896 898 900 902 1024 1026 1028 1030 1152 1154 1156 1158 1280 1282 1284 1286 1408 1410 1412 1414 1536 1538 1540 1542 1664 1666 1668 1670 1792 1794 1796 1798 1920 1922 1924 1926 2048 2050 2052 2054 2176 2178 2180 2182 2304 2306 2308 2310 2432 2434 2436 2438 2560 2562 2564 2566 2688 2690 2692 2694 2816 2818 2820 2822 2944 2946 2948 2950 3072 3074 3076 3078 3200 3202 3204 3206 3328 3330 3332 3334 3456 3458 3460 3462 3584 3586 3588 3590 3712 3714 3716 3718 3840 3842 3844 3846 3968 3970 3972 3974 4096 4098 4100 4102 4224 4226 4228 4230 4352 4354 4356 4358 4480 4482 4484 4486 4608 4610 4612 4614 4736 4738 4740 4742 4864 4866 4868 4870 4992 4994 4996 4998 5120 5122 5124 5126 5248 5250 5252 5254 5376 5378 5380 5382 5504 5506 5508 5510 5632 5634 5636 5638 5760 5762 5764 5766 5888 5890 5892 5894 6016 6018 6020 6022 6144 6146 6148 6150 6272 6274 6276 6278 6400 6402 6404 6406 6528 6530 6532 6534 6656 6658 6660 6662 6784 6786 6788 6790 6912 6914 6916 6918 7040 7042 7044 7046 7168 7170 7172 7174 7296 7298 7300 7302 7424 7426 7428 7430 7552 7554 7556 7558 7680 7682 7684 7686 7808 7810 7812 7814 7936 7938 7940 7942 8064 8066 8068 8070 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x1x65x4.txt�������������������������������������������0000664�0000000�0000000�00000002354�14364043643�0023171�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 128 130 132 134 256 258 260 262 384 386 388 390 512 514 516 518 640 642 644 646 768 770 772 774 896 898 900 902 1024 1026 1028 1030 1152 1154 1156 1158 1280 1282 1284 1286 1408 1410 1412 1414 1536 1538 1540 1542 1664 1666 1668 1670 1792 1794 1796 1798 1920 1922 1924 1926 2048 2050 2052 2054 2176 2178 2180 2182 2304 2306 2308 2310 2432 2434 2436 2438 2560 2562 2564 2566 2688 2690 2692 2694 2816 2818 2820 2822 2944 2946 2948 2950 3072 3074 3076 3078 3200 3202 3204 3206 3328 3330 3332 3334 3456 3458 3460 3462 3584 3586 3588 3590 3712 3714 3716 3718 3840 3842 3844 3846 3968 3970 3972 3974 4096 4098 4100 4102 4224 4226 4228 4230 4352 4354 4356 4358 4480 4482 4484 4486 4608 4610 4612 4614 4736 4738 4740 4742 4864 4866 4868 4870 4992 4994 4996 4998 5120 5122 5124 5126 5248 5250 5252 5254 5376 5378 5380 5382 5504 5506 5508 5510 5632 5634 5636 5638 5760 5762 5764 5766 5888 5890 5892 5894 6016 6018 6020 6022 6144 6146 6148 6150 6272 6274 6276 6278 6400 6402 6404 6406 6528 6530 6532 6534 6656 6658 6660 6662 6784 6786 6788 6790 6912 6914 6916 6918 7040 7042 7044 7046 7168 7170 7172 7174 7296 7298 7300 7302 7424 7426 7428 7430 7552 7554 7556 7558 7680 7682 7684 7686 7808 7810 7812 7814 7936 7938 7940 7942 8064 8066 8068 8070 8192 8194 8196 8198 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_1x2x3x4.txt��������������������������������������������0000664�0000000�0000000�00000000144�14364043643�0023075�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 128 130 132 134 256 258 260 262 4096 4098 4100 4102 4224 4226 4228 4230 4352 4354 4356 4358 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/offset_files/nhwc_2x3x33x129.txt�����������������������������������������0000664�0000000�0000000�00000457204�14364043643�0023347�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 24576 24578 24580 24582 24584 24586 24588 24590 24592 24594 24596 24598 24600 24602 24604 24606 24608 24610 24612 24614 24616 24618 24620 24622 24624 24626 24628 24630 24632 24634 24636 24638 24640 24642 24644 24646 24648 24650 24652 24654 24656 24658 24660 24662 24664 24666 24668 24670 24672 24674 24676 24678 24680 24682 24684 24686 24688 24690 24692 24694 24696 24698 24700 24702 49152 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 24704 24706 24708 24710 24712 24714 24716 24718 24720 24722 24724 24726 24728 24730 24732 24734 24736 24738 24740 24742 24744 24746 24748 24750 24752 24754 24756 24758 24760 24762 24764 24766 24768 24770 24772 24774 24776 24778 24780 24782 24784 24786 24788 24790 24792 24794 24796 24798 24800 24802 24804 24806 24808 24810 24812 24814 24816 24818 24820 24822 24824 24826 24828 24830 49280 256 258 260 262 264 266 268 270 272 274 276 278 280 282 284 286 288 290 292 294 296 298 300 302 304 306 308 310 312 314 316 318 320 322 324 326 328 330 332 334 336 338 340 342 344 346 348 350 352 354 356 358 360 362 364 366 368 370 372 374 376 378 380 382 24832 24834 24836 24838 24840 24842 24844 24846 24848 24850 24852 24854 24856 24858 24860 24862 24864 24866 24868 24870 24872 24874 24876 24878 24880 24882 24884 24886 24888 24890 24892 24894 24896 24898 24900 24902 24904 24906 24908 24910 24912 24914 24916 24918 24920 24922 24924 24926 24928 24930 24932 24934 24936 24938 24940 24942 24944 24946 24948 24950 24952 24954 24956 24958 49408 384 386 388 390 392 394 396 398 400 402 404 406 408 410 412 414 416 418 420 422 424 426 428 430 432 434 436 438 440 442 444 446 448 450 452 454 456 458 460 462 464 466 468 470 472 474 476 478 480 482 484 486 488 490 492 494 496 498 500 502 504 506 508 510 24960 24962 24964 24966 24968 24970 24972 24974 24976 24978 24980 24982 24984 24986 24988 24990 24992 24994 24996 24998 25000 25002 25004 25006 25008 25010 25012 25014 25016 25018 25020 25022 25024 25026 25028 25030 25032 25034 25036 25038 25040 25042 25044 25046 25048 25050 25052 25054 25056 25058 25060 25062 25064 25066 25068 25070 25072 25074 25076 25078 25080 25082 25084 25086 49536 512 514 516 518 520 522 524 526 528 530 532 534 536 538 540 542 544 546 548 550 552 554 556 558 560 562 564 566 568 570 572 574 576 578 580 582 584 586 588 590 592 594 596 598 600 602 604 606 608 610 612 614 616 618 620 622 624 626 628 630 632 634 636 638 25088 25090 25092 25094 25096 25098 25100 25102 25104 25106 25108 25110 25112 25114 25116 25118 25120 25122 25124 25126 25128 25130 25132 25134 25136 25138 25140 25142 25144 25146 25148 25150 25152 25154 25156 25158 25160 25162 25164 25166 25168 25170 25172 25174 25176 25178 25180 25182 25184 25186 25188 25190 25192 25194 25196 25198 25200 25202 25204 25206 25208 25210 25212 25214 49664 640 642 644 646 648 650 652 654 656 658 660 662 664 666 668 670 672 674 676 678 680 682 684 686 688 690 692 694 696 698 700 702 704 706 708 710 712 714 716 718 720 722 724 726 728 730 732 734 736 738 740 742 744 746 748 750 752 754 756 758 760 762 764 766 25216 25218 25220 25222 25224 25226 25228 25230 25232 25234 25236 25238 25240 25242 25244 25246 25248 25250 25252 25254 25256 25258 25260 25262 25264 25266 25268 25270 25272 25274 25276 25278 25280 25282 25284 25286 25288 25290 25292 25294 25296 25298 25300 25302 25304 25306 25308 25310 25312 25314 25316 25318 25320 25322 25324 25326 25328 25330 25332 25334 25336 25338 25340 25342 49792 768 770 772 774 776 778 780 782 784 786 788 790 792 794 796 798 800 802 804 806 808 810 812 814 816 818 820 822 824 826 828 830 832 834 836 838 840 842 844 846 848 850 852 854 856 858 860 862 864 866 868 870 872 874 876 878 880 882 884 886 888 890 892 894 25344 25346 25348 25350 25352 25354 25356 25358 25360 25362 25364 25366 25368 25370 25372 25374 25376 25378 25380 25382 25384 25386 25388 25390 25392 25394 25396 25398 25400 25402 25404 25406 25408 25410 25412 25414 25416 25418 25420 25422 25424 25426 25428 25430 25432 25434 25436 25438 25440 25442 25444 25446 25448 25450 25452 25454 25456 25458 25460 25462 25464 25466 25468 25470 49920 896 898 900 902 904 906 908 910 912 914 916 918 920 922 924 926 928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 25472 25474 25476 25478 25480 25482 25484 25486 25488 25490 25492 25494 25496 25498 25500 25502 25504 25506 25508 25510 25512 25514 25516 25518 25520 25522 25524 25526 25528 25530 25532 25534 25536 25538 25540 25542 25544 25546 25548 25550 25552 25554 25556 25558 25560 25562 25564 25566 25568 25570 25572 25574 25576 25578 25580 25582 25584 25586 25588 25590 25592 25594 25596 25598 50048 1024 1026 1028 1030 1032 1034 1036 1038 1040 1042 1044 1046 1048 1050 1052 1054 1056 1058 1060 1062 1064 1066 1068 1070 1072 1074 1076 1078 1080 1082 1084 1086 1088 1090 1092 1094 1096 1098 1100 1102 1104 1106 1108 1110 1112 1114 1116 1118 1120 1122 1124 1126 1128 1130 1132 1134 1136 1138 1140 1142 1144 1146 1148 1150 25600 25602 25604 25606 25608 25610 25612 25614 25616 25618 25620 25622 25624 25626 25628 25630 25632 25634 25636 25638 25640 25642 25644 25646 25648 25650 25652 25654 25656 25658 25660 25662 25664 25666 25668 25670 25672 25674 25676 25678 25680 25682 25684 25686 25688 25690 25692 25694 25696 25698 25700 25702 25704 25706 25708 25710 25712 25714 25716 25718 25720 25722 25724 25726 50176 1152 1154 1156 1158 1160 1162 1164 1166 1168 1170 1172 1174 1176 1178 1180 1182 1184 1186 1188 1190 1192 1194 1196 1198 1200 1202 1204 1206 1208 1210 1212 1214 1216 1218 1220 1222 1224 1226 1228 1230 1232 1234 1236 1238 1240 1242 1244 1246 1248 1250 1252 1254 1256 1258 1260 1262 1264 1266 1268 1270 1272 1274 1276 1278 25728 25730 25732 25734 25736 25738 25740 25742 25744 25746 25748 25750 25752 25754 25756 25758 25760 25762 25764 25766 25768 25770 25772 25774 25776 25778 25780 25782 25784 25786 25788 25790 25792 25794 25796 25798 25800 25802 25804 25806 25808 25810 25812 25814 25816 25818 25820 25822 25824 25826 25828 25830 25832 25834 25836 25838 25840 25842 25844 25846 25848 25850 25852 25854 50304 1280 1282 1284 1286 1288 1290 1292 1294 1296 1298 1300 1302 1304 1306 1308 1310 1312 1314 1316 1318 1320 1322 1324 1326 1328 1330 1332 1334 1336 1338 1340 1342 1344 1346 1348 1350 1352 1354 1356 1358 1360 1362 1364 1366 1368 1370 1372 1374 1376 1378 1380 1382 1384 1386 1388 1390 1392 1394 1396 1398 1400 1402 1404 1406 25856 25858 25860 25862 25864 25866 25868 25870 25872 25874 25876 25878 25880 25882 25884 25886 25888 25890 25892 25894 25896 25898 25900 25902 25904 25906 25908 25910 25912 25914 25916 25918 25920 25922 25924 25926 25928 25930 25932 25934 25936 25938 25940 25942 25944 25946 25948 25950 25952 25954 25956 25958 25960 25962 25964 25966 25968 25970 25972 25974 25976 25978 25980 25982 50432 1408 1410 1412 1414 1416 1418 1420 1422 1424 1426 1428 1430 1432 1434 1436 1438 1440 1442 1444 1446 1448 1450 1452 1454 1456 1458 1460 1462 1464 1466 1468 1470 1472 1474 1476 1478 1480 1482 1484 1486 1488 1490 1492 1494 1496 1498 1500 1502 1504 1506 1508 1510 1512 1514 1516 1518 1520 1522 1524 1526 1528 1530 1532 1534 25984 25986 25988 25990 25992 25994 25996 25998 26000 26002 26004 26006 26008 26010 26012 26014 26016 26018 26020 26022 26024 26026 26028 26030 26032 26034 26036 26038 26040 26042 26044 26046 26048 26050 26052 26054 26056 26058 26060 26062 26064 26066 26068 26070 26072 26074 26076 26078 26080 26082 26084 26086 26088 26090 26092 26094 26096 26098 26100 26102 26104 26106 26108 26110 50560 1536 1538 1540 1542 1544 1546 1548 1550 1552 1554 1556 1558 1560 1562 1564 1566 1568 1570 1572 1574 1576 1578 1580 1582 1584 1586 1588 1590 1592 1594 1596 1598 1600 1602 1604 1606 1608 1610 1612 1614 1616 1618 1620 1622 1624 1626 1628 1630 1632 1634 1636 1638 1640 1642 1644 1646 1648 1650 1652 1654 1656 1658 1660 1662 26112 26114 26116 26118 26120 26122 26124 26126 26128 26130 26132 26134 26136 26138 26140 26142 26144 26146 26148 26150 26152 26154 26156 26158 26160 26162 26164 26166 26168 26170 26172 26174 26176 26178 26180 26182 26184 26186 26188 26190 26192 26194 26196 26198 26200 26202 26204 26206 26208 26210 26212 26214 26216 26218 26220 26222 26224 26226 26228 26230 26232 26234 26236 26238 50688 1664 1666 1668 1670 1672 1674 1676 1678 1680 1682 1684 1686 1688 1690 1692 1694 1696 1698 1700 1702 1704 1706 1708 1710 1712 1714 1716 1718 1720 1722 1724 1726 1728 1730 1732 1734 1736 1738 1740 1742 1744 1746 1748 1750 1752 1754 1756 1758 1760 1762 1764 1766 1768 1770 1772 1774 1776 1778 1780 1782 1784 1786 1788 1790 26240 26242 26244 26246 26248 26250 26252 26254 26256 26258 26260 26262 26264 26266 26268 26270 26272 26274 26276 26278 26280 26282 26284 26286 26288 26290 26292 26294 26296 26298 26300 26302 26304 26306 26308 26310 26312 26314 26316 26318 26320 26322 26324 26326 26328 26330 26332 26334 26336 26338 26340 26342 26344 26346 26348 26350 26352 26354 26356 26358 26360 26362 26364 26366 50816 1792 1794 1796 1798 1800 1802 1804 1806 1808 1810 1812 1814 1816 1818 1820 1822 1824 1826 1828 1830 1832 1834 1836 1838 1840 1842 1844 1846 1848 1850 1852 1854 1856 1858 1860 1862 1864 1866 1868 1870 1872 1874 1876 1878 1880 1882 1884 1886 1888 1890 1892 1894 1896 1898 1900 1902 1904 1906 1908 1910 1912 1914 1916 1918 26368 26370 26372 26374 26376 26378 26380 26382 26384 26386 26388 26390 26392 26394 26396 26398 26400 26402 26404 26406 26408 26410 26412 26414 26416 26418 26420 26422 26424 26426 26428 26430 26432 26434 26436 26438 26440 26442 26444 26446 26448 26450 26452 26454 26456 26458 26460 26462 26464 26466 26468 26470 26472 26474 26476 26478 26480 26482 26484 26486 26488 26490 26492 26494 50944 1920 1922 1924 1926 1928 1930 1932 1934 1936 1938 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028 2030 2032 2034 2036 2038 2040 2042 2044 2046 26496 26498 26500 26502 26504 26506 26508 26510 26512 26514 26516 26518 26520 26522 26524 26526 26528 26530 26532 26534 26536 26538 26540 26542 26544 26546 26548 26550 26552 26554 26556 26558 26560 26562 26564 26566 26568 26570 26572 26574 26576 26578 26580 26582 26584 26586 26588 26590 26592 26594 26596 26598 26600 26602 26604 26606 26608 26610 26612 26614 26616 26618 26620 26622 51072 2048 2050 2052 2054 2056 2058 2060 2062 2064 2066 2068 2070 2072 2074 2076 2078 2080 2082 2084 2086 2088 2090 2092 2094 2096 2098 2100 2102 2104 2106 2108 2110 2112 2114 2116 2118 2120 2122 2124 2126 2128 2130 2132 2134 2136 2138 2140 2142 2144 2146 2148 2150 2152 2154 2156 2158 2160 2162 2164 2166 2168 2170 2172 2174 26624 26626 26628 26630 26632 26634 26636 26638 26640 26642 26644 26646 26648 26650 26652 26654 26656 26658 26660 26662 26664 26666 26668 26670 26672 26674 26676 26678 26680 26682 26684 26686 26688 26690 26692 26694 26696 26698 26700 26702 26704 26706 26708 26710 26712 26714 26716 26718 26720 26722 26724 26726 26728 26730 26732 26734 26736 26738 26740 26742 26744 26746 26748 26750 51200 2176 2178 2180 2182 2184 2186 2188 2190 2192 2194 2196 2198 2200 2202 2204 2206 2208 2210 2212 2214 2216 2218 2220 2222 2224 2226 2228 2230 2232 2234 2236 2238 2240 2242 2244 2246 2248 2250 2252 2254 2256 2258 2260 2262 2264 2266 2268 2270 2272 2274 2276 2278 2280 2282 2284 2286 2288 2290 2292 2294 2296 2298 2300 2302 26752 26754 26756 26758 26760 26762 26764 26766 26768 26770 26772 26774 26776 26778 26780 26782 26784 26786 26788 26790 26792 26794 26796 26798 26800 26802 26804 26806 26808 26810 26812 26814 26816 26818 26820 26822 26824 26826 26828 26830 26832 26834 26836 26838 26840 26842 26844 26846 26848 26850 26852 26854 26856 26858 26860 26862 26864 26866 26868 26870 26872 26874 26876 26878 51328 2304 2306 2308 2310 2312 2314 2316 2318 2320 2322 2324 2326 2328 2330 2332 2334 2336 2338 2340 2342 2344 2346 2348 2350 2352 2354 2356 2358 2360 2362 2364 2366 2368 2370 2372 2374 2376 2378 2380 2382 2384 2386 2388 2390 2392 2394 2396 2398 2400 2402 2404 2406 2408 2410 2412 2414 2416 2418 2420 2422 2424 2426 2428 2430 26880 26882 26884 26886 26888 26890 26892 26894 26896 26898 26900 26902 26904 26906 26908 26910 26912 26914 26916 26918 26920 26922 26924 26926 26928 26930 26932 26934 26936 26938 26940 26942 26944 26946 26948 26950 26952 26954 26956 26958 26960 26962 26964 26966 26968 26970 26972 26974 26976 26978 26980 26982 26984 26986 26988 26990 26992 26994 26996 26998 27000 27002 27004 27006 51456 2432 2434 2436 2438 2440 2442 2444 2446 2448 2450 2452 2454 2456 2458 2460 2462 2464 2466 2468 2470 2472 2474 2476 2478 2480 2482 2484 2486 2488 2490 2492 2494 2496 2498 2500 2502 2504 2506 2508 2510 2512 2514 2516 2518 2520 2522 2524 2526 2528 2530 2532 2534 2536 2538 2540 2542 2544 2546 2548 2550 2552 2554 2556 2558 27008 27010 27012 27014 27016 27018 27020 27022 27024 27026 27028 27030 27032 27034 27036 27038 27040 27042 27044 27046 27048 27050 27052 27054 27056 27058 27060 27062 27064 27066 27068 27070 27072 27074 27076 27078 27080 27082 27084 27086 27088 27090 27092 27094 27096 27098 27100 27102 27104 27106 27108 27110 27112 27114 27116 27118 27120 27122 27124 27126 27128 27130 27132 27134 51584 2560 2562 2564 2566 2568 2570 2572 2574 2576 2578 2580 2582 2584 2586 2588 2590 2592 2594 2596 2598 2600 2602 2604 2606 2608 2610 2612 2614 2616 2618 2620 2622 2624 2626 2628 2630 2632 2634 2636 2638 2640 2642 2644 2646 2648 2650 2652 2654 2656 2658 2660 2662 2664 2666 2668 2670 2672 2674 2676 2678 2680 2682 2684 2686 27136 27138 27140 27142 27144 27146 27148 27150 27152 27154 27156 27158 27160 27162 27164 27166 27168 27170 27172 27174 27176 27178 27180 27182 27184 27186 27188 27190 27192 27194 27196 27198 27200 27202 27204 27206 27208 27210 27212 27214 27216 27218 27220 27222 27224 27226 27228 27230 27232 27234 27236 27238 27240 27242 27244 27246 27248 27250 27252 27254 27256 27258 27260 27262 51712 2688 2690 2692 2694 2696 2698 2700 2702 2704 2706 2708 2710 2712 2714 2716 2718 2720 2722 2724 2726 2728 2730 2732 2734 2736 2738 2740 2742 2744 2746 2748 2750 2752 2754 2756 2758 2760 2762 2764 2766 2768 2770 2772 2774 2776 2778 2780 2782 2784 2786 2788 2790 2792 2794 2796 2798 2800 2802 2804 2806 2808 2810 2812 2814 27264 27266 27268 27270 27272 27274 27276 27278 27280 27282 27284 27286 27288 27290 27292 27294 27296 27298 27300 27302 27304 27306 27308 27310 27312 27314 27316 27318 27320 27322 27324 27326 27328 27330 27332 27334 27336 27338 27340 27342 27344 27346 27348 27350 27352 27354 27356 27358 27360 27362 27364 27366 27368 27370 27372 27374 27376 27378 27380 27382 27384 27386 27388 27390 51840 2816 2818 2820 2822 2824 2826 2828 2830 2832 2834 2836 2838 2840 2842 2844 2846 2848 2850 2852 2854 2856 2858 2860 2862 2864 2866 2868 2870 2872 2874 2876 2878 2880 2882 2884 2886 2888 2890 2892 2894 2896 2898 2900 2902 2904 2906 2908 2910 2912 2914 2916 2918 2920 2922 2924 2926 2928 2930 2932 2934 2936 2938 2940 2942 27392 27394 27396 27398 27400 27402 27404 27406 27408 27410 27412 27414 27416 27418 27420 27422 27424 27426 27428 27430 27432 27434 27436 27438 27440 27442 27444 27446 27448 27450 27452 27454 27456 27458 27460 27462 27464 27466 27468 27470 27472 27474 27476 27478 27480 27482 27484 27486 27488 27490 27492 27494 27496 27498 27500 27502 27504 27506 27508 27510 27512 27514 27516 27518 51968 2944 2946 2948 2950 2952 2954 2956 2958 2960 2962 2964 2966 2968 2970 2972 2974 2976 2978 2980 2982 2984 2986 2988 2990 2992 2994 2996 2998 3000 3002 3004 3006 3008 3010 3012 3014 3016 3018 3020 3022 3024 3026 3028 3030 3032 3034 3036 3038 3040 3042 3044 3046 3048 3050 3052 3054 3056 3058 3060 3062 3064 3066 3068 3070 27520 27522 27524 27526 27528 27530 27532 27534 27536 27538 27540 27542 27544 27546 27548 27550 27552 27554 27556 27558 27560 27562 27564 27566 27568 27570 27572 27574 27576 27578 27580 27582 27584 27586 27588 27590 27592 27594 27596 27598 27600 27602 27604 27606 27608 27610 27612 27614 27616 27618 27620 27622 27624 27626 27628 27630 27632 27634 27636 27638 27640 27642 27644 27646 52096 3072 3074 3076 3078 3080 3082 3084 3086 3088 3090 3092 3094 3096 3098 3100 3102 3104 3106 3108 3110 3112 3114 3116 3118 3120 3122 3124 3126 3128 3130 3132 3134 3136 3138 3140 3142 3144 3146 3148 3150 3152 3154 3156 3158 3160 3162 3164 3166 3168 3170 3172 3174 3176 3178 3180 3182 3184 3186 3188 3190 3192 3194 3196 3198 27648 27650 27652 27654 27656 27658 27660 27662 27664 27666 27668 27670 27672 27674 27676 27678 27680 27682 27684 27686 27688 27690 27692 27694 27696 27698 27700 27702 27704 27706 27708 27710 27712 27714 27716 27718 27720 27722 27724 27726 27728 27730 27732 27734 27736 27738 27740 27742 27744 27746 27748 27750 27752 27754 27756 27758 27760 27762 27764 27766 27768 27770 27772 27774 52224 3200 3202 3204 3206 3208 3210 3212 3214 3216 3218 3220 3222 3224 3226 3228 3230 3232 3234 3236 3238 3240 3242 3244 3246 3248 3250 3252 3254 3256 3258 3260 3262 3264 3266 3268 3270 3272 3274 3276 3278 3280 3282 3284 3286 3288 3290 3292 3294 3296 3298 3300 3302 3304 3306 3308 3310 3312 3314 3316 3318 3320 3322 3324 3326 27776 27778 27780 27782 27784 27786 27788 27790 27792 27794 27796 27798 27800 27802 27804 27806 27808 27810 27812 27814 27816 27818 27820 27822 27824 27826 27828 27830 27832 27834 27836 27838 27840 27842 27844 27846 27848 27850 27852 27854 27856 27858 27860 27862 27864 27866 27868 27870 27872 27874 27876 27878 27880 27882 27884 27886 27888 27890 27892 27894 27896 27898 27900 27902 52352 3328 3330 3332 3334 3336 3338 3340 3342 3344 3346 3348 3350 3352 3354 3356 3358 3360 3362 3364 3366 3368 3370 3372 3374 3376 3378 3380 3382 3384 3386 3388 3390 3392 3394 3396 3398 3400 3402 3404 3406 3408 3410 3412 3414 3416 3418 3420 3422 3424 3426 3428 3430 3432 3434 3436 3438 3440 3442 3444 3446 3448 3450 3452 3454 27904 27906 27908 27910 27912 27914 27916 27918 27920 27922 27924 27926 27928 27930 27932 27934 27936 27938 27940 27942 27944 27946 27948 27950 27952 27954 27956 27958 27960 27962 27964 27966 27968 27970 27972 27974 27976 27978 27980 27982 27984 27986 27988 27990 27992 27994 27996 27998 28000 28002 28004 28006 28008 28010 28012 28014 28016 28018 28020 28022 28024 28026 28028 28030 52480 3456 3458 3460 3462 3464 3466 3468 3470 3472 3474 3476 3478 3480 3482 3484 3486 3488 3490 3492 3494 3496 3498 3500 3502 3504 3506 3508 3510 3512 3514 3516 3518 3520 3522 3524 3526 3528 3530 3532 3534 3536 3538 3540 3542 3544 3546 3548 3550 3552 3554 3556 3558 3560 3562 3564 3566 3568 3570 3572 3574 3576 3578 3580 3582 28032 28034 28036 28038 28040 28042 28044 28046 28048 28050 28052 28054 28056 28058 28060 28062 28064 28066 28068 28070 28072 28074 28076 28078 28080 28082 28084 28086 28088 28090 28092 28094 28096 28098 28100 28102 28104 28106 28108 28110 28112 28114 28116 28118 28120 28122 28124 28126 28128 28130 28132 28134 28136 28138 28140 28142 28144 28146 28148 28150 28152 28154 28156 28158 52608 3584 3586 3588 3590 3592 3594 3596 3598 3600 3602 3604 3606 3608 3610 3612 3614 3616 3618 3620 3622 3624 3626 3628 3630 3632 3634 3636 3638 3640 3642 3644 3646 3648 3650 3652 3654 3656 3658 3660 3662 3664 3666 3668 3670 3672 3674 3676 3678 3680 3682 3684 3686 3688 3690 3692 3694 3696 3698 3700 3702 3704 3706 3708 3710 28160 28162 28164 28166 28168 28170 28172 28174 28176 28178 28180 28182 28184 28186 28188 28190 28192 28194 28196 28198 28200 28202 28204 28206 28208 28210 28212 28214 28216 28218 28220 28222 28224 28226 28228 28230 28232 28234 28236 28238 28240 28242 28244 28246 28248 28250 28252 28254 28256 28258 28260 28262 28264 28266 28268 28270 28272 28274 28276 28278 28280 28282 28284 28286 52736 3712 3714 3716 3718 3720 3722 3724 3726 3728 3730 3732 3734 3736 3738 3740 3742 3744 3746 3748 3750 3752 3754 3756 3758 3760 3762 3764 3766 3768 3770 3772 3774 3776 3778 3780 3782 3784 3786 3788 3790 3792 3794 3796 3798 3800 3802 3804 3806 3808 3810 3812 3814 3816 3818 3820 3822 3824 3826 3828 3830 3832 3834 3836 3838 28288 28290 28292 28294 28296 28298 28300 28302 28304 28306 28308 28310 28312 28314 28316 28318 28320 28322 28324 28326 28328 28330 28332 28334 28336 28338 28340 28342 28344 28346 28348 28350 28352 28354 28356 28358 28360 28362 28364 28366 28368 28370 28372 28374 28376 28378 28380 28382 28384 28386 28388 28390 28392 28394 28396 28398 28400 28402 28404 28406 28408 28410 28412 28414 52864 3840 3842 3844 3846 3848 3850 3852 3854 3856 3858 3860 3862 3864 3866 3868 3870 3872 3874 3876 3878 3880 3882 3884 3886 3888 3890 3892 3894 3896 3898 3900 3902 3904 3906 3908 3910 3912 3914 3916 3918 3920 3922 3924 3926 3928 3930 3932 3934 3936 3938 3940 3942 3944 3946 3948 3950 3952 3954 3956 3958 3960 3962 3964 3966 28416 28418 28420 28422 28424 28426 28428 28430 28432 28434 28436 28438 28440 28442 28444 28446 28448 28450 28452 28454 28456 28458 28460 28462 28464 28466 28468 28470 28472 28474 28476 28478 28480 28482 28484 28486 28488 28490 28492 28494 28496 28498 28500 28502 28504 28506 28508 28510 28512 28514 28516 28518 28520 28522 28524 28526 28528 28530 28532 28534 28536 28538 28540 28542 52992 3968 3970 3972 3974 3976 3978 3980 3982 3984 3986 3988 3990 3992 3994 3996 3998 4000 4002 4004 4006 4008 4010 4012 4014 4016 4018 4020 4022 4024 4026 4028 4030 4032 4034 4036 4038 4040 4042 4044 4046 4048 4050 4052 4054 4056 4058 4060 4062 4064 4066 4068 4070 4072 4074 4076 4078 4080 4082 4084 4086 4088 4090 4092 4094 28544 28546 28548 28550 28552 28554 28556 28558 28560 28562 28564 28566 28568 28570 28572 28574 28576 28578 28580 28582 28584 28586 28588 28590 28592 28594 28596 28598 28600 28602 28604 28606 28608 28610 28612 28614 28616 28618 28620 28622 28624 28626 28628 28630 28632 28634 28636 28638 28640 28642 28644 28646 28648 28650 28652 28654 28656 28658 28660 28662 28664 28666 28668 28670 53120 4096 4098 4100 4102 4104 4106 4108 4110 4112 4114 4116 4118 4120 4122 4124 4126 4128 4130 4132 4134 4136 4138 4140 4142 4144 4146 4148 4150 4152 4154 4156 4158 4160 4162 4164 4166 4168 4170 4172 4174 4176 4178 4180 4182 4184 4186 4188 4190 4192 4194 4196 4198 4200 4202 4204 4206 4208 4210 4212 4214 4216 4218 4220 4222 28672 28674 28676 28678 28680 28682 28684 28686 28688 28690 28692 28694 28696 28698 28700 28702 28704 28706 28708 28710 28712 28714 28716 28718 28720 28722 28724 28726 28728 28730 28732 28734 28736 28738 28740 28742 28744 28746 28748 28750 28752 28754 28756 28758 28760 28762 28764 28766 28768 28770 28772 28774 28776 28778 28780 28782 28784 28786 28788 28790 28792 28794 28796 28798 53248 8192 8194 8196 8198 8200 8202 8204 8206 8208 8210 8212 8214 8216 8218 8220 8222 8224 8226 8228 8230 8232 8234 8236 8238 8240 8242 8244 8246 8248 8250 8252 8254 8256 8258 8260 8262 8264 8266 8268 8270 8272 8274 8276 8278 8280 8282 8284 8286 8288 8290 8292 8294 8296 8298 8300 8302 8304 8306 8308 8310 8312 8314 8316 8318 32768 32770 32772 32774 32776 32778 32780 32782 32784 32786 32788 32790 32792 32794 32796 32798 32800 32802 32804 32806 32808 32810 32812 32814 32816 32818 32820 32822 32824 32826 32828 32830 32832 32834 32836 32838 32840 32842 32844 32846 32848 32850 32852 32854 32856 32858 32860 32862 32864 32866 32868 32870 32872 32874 32876 32878 32880 32882 32884 32886 32888 32890 32892 32894 57344 8320 8322 8324 8326 8328 8330 8332 8334 8336 8338 8340 8342 8344 8346 8348 8350 8352 8354 8356 8358 8360 8362 8364 8366 8368 8370 8372 8374 8376 8378 8380 8382 8384 8386 8388 8390 8392 8394 8396 8398 8400 8402 8404 8406 8408 8410 8412 8414 8416 8418 8420 8422 8424 8426 8428 8430 8432 8434 8436 8438 8440 8442 8444 8446 32896 32898 32900 32902 32904 32906 32908 32910 32912 32914 32916 32918 32920 32922 32924 32926 32928 32930 32932 32934 32936 32938 32940 32942 32944 32946 32948 32950 32952 32954 32956 32958 32960 32962 32964 32966 32968 32970 32972 32974 32976 32978 32980 32982 32984 32986 32988 32990 32992 32994 32996 32998 33000 33002 33004 33006 33008 33010 33012 33014 33016 33018 33020 33022 57472 8448 8450 8452 8454 8456 8458 8460 8462 8464 8466 8468 8470 8472 8474 8476 8478 8480 8482 8484 8486 8488 8490 8492 8494 8496 8498 8500 8502 8504 8506 8508 8510 8512 8514 8516 8518 8520 8522 8524 8526 8528 8530 8532 8534 8536 8538 8540 8542 8544 8546 8548 8550 8552 8554 8556 8558 8560 8562 8564 8566 8568 8570 8572 8574 33024 33026 33028 33030 33032 33034 33036 33038 33040 33042 33044 33046 33048 33050 33052 33054 33056 33058 33060 33062 33064 33066 33068 33070 33072 33074 33076 33078 33080 33082 33084 33086 33088 33090 33092 33094 33096 33098 33100 33102 33104 33106 33108 33110 33112 33114 33116 33118 33120 33122 33124 33126 33128 33130 33132 33134 33136 33138 33140 33142 33144 33146 33148 33150 57600 8576 8578 8580 8582 8584 8586 8588 8590 8592 8594 8596 8598 8600 8602 8604 8606 8608 8610 8612 8614 8616 8618 8620 8622 8624 8626 8628 8630 8632 8634 8636 8638 8640 8642 8644 8646 8648 8650 8652 8654 8656 8658 8660 8662 8664 8666 8668 8670 8672 8674 8676 8678 8680 8682 8684 8686 8688 8690 8692 8694 8696 8698 8700 8702 33152 33154 33156 33158 33160 33162 33164 33166 33168 33170 33172 33174 33176 33178 33180 33182 33184 33186 33188 33190 33192 33194 33196 33198 33200 33202 33204 33206 33208 33210 33212 33214 33216 33218 33220 33222 33224 33226 33228 33230 33232 33234 33236 33238 33240 33242 33244 33246 33248 33250 33252 33254 33256 33258 33260 33262 33264 33266 33268 33270 33272 33274 33276 33278 57728 8704 8706 8708 8710 8712 8714 8716 8718 8720 8722 8724 8726 8728 8730 8732 8734 8736 8738 8740 8742 8744 8746 8748 8750 8752 8754 8756 8758 8760 8762 8764 8766 8768 8770 8772 8774 8776 8778 8780 8782 8784 8786 8788 8790 8792 8794 8796 8798 8800 8802 8804 8806 8808 8810 8812 8814 8816 8818 8820 8822 8824 8826 8828 8830 33280 33282 33284 33286 33288 33290 33292 33294 33296 33298 33300 33302 33304 33306 33308 33310 33312 33314 33316 33318 33320 33322 33324 33326 33328 33330 33332 33334 33336 33338 33340 33342 33344 33346 33348 33350 33352 33354 33356 33358 33360 33362 33364 33366 33368 33370 33372 33374 33376 33378 33380 33382 33384 33386 33388 33390 33392 33394 33396 33398 33400 33402 33404 33406 57856 8832 8834 8836 8838 8840 8842 8844 8846 8848 8850 8852 8854 8856 8858 8860 8862 8864 8866 8868 8870 8872 8874 8876 8878 8880 8882 8884 8886 8888 8890 8892 8894 8896 8898 8900 8902 8904 8906 8908 8910 8912 8914 8916 8918 8920 8922 8924 8926 8928 8930 8932 8934 8936 8938 8940 8942 8944 8946 8948 8950 8952 8954 8956 8958 33408 33410 33412 33414 33416 33418 33420 33422 33424 33426 33428 33430 33432 33434 33436 33438 33440 33442 33444 33446 33448 33450 33452 33454 33456 33458 33460 33462 33464 33466 33468 33470 33472 33474 33476 33478 33480 33482 33484 33486 33488 33490 33492 33494 33496 33498 33500 33502 33504 33506 33508 33510 33512 33514 33516 33518 33520 33522 33524 33526 33528 33530 33532 33534 57984 8960 8962 8964 8966 8968 8970 8972 8974 8976 8978 8980 8982 8984 8986 8988 8990 8992 8994 8996 8998 9000 9002 9004 9006 9008 9010 9012 9014 9016 9018 9020 9022 9024 9026 9028 9030 9032 9034 9036 9038 9040 9042 9044 9046 9048 9050 9052 9054 9056 9058 9060 9062 9064 9066 9068 9070 9072 9074 9076 9078 9080 9082 9084 9086 33536 33538 33540 33542 33544 33546 33548 33550 33552 33554 33556 33558 33560 33562 33564 33566 33568 33570 33572 33574 33576 33578 33580 33582 33584 33586 33588 33590 33592 33594 33596 33598 33600 33602 33604 33606 33608 33610 33612 33614 33616 33618 33620 33622 33624 33626 33628 33630 33632 33634 33636 33638 33640 33642 33644 33646 33648 33650 33652 33654 33656 33658 33660 33662 58112 9088 9090 9092 9094 9096 9098 9100 9102 9104 9106 9108 9110 9112 9114 9116 9118 9120 9122 9124 9126 9128 9130 9132 9134 9136 9138 9140 9142 9144 9146 9148 9150 9152 9154 9156 9158 9160 9162 9164 9166 9168 9170 9172 9174 9176 9178 9180 9182 9184 9186 9188 9190 9192 9194 9196 9198 9200 9202 9204 9206 9208 9210 9212 9214 33664 33666 33668 33670 33672 33674 33676 33678 33680 33682 33684 33686 33688 33690 33692 33694 33696 33698 33700 33702 33704 33706 33708 33710 33712 33714 33716 33718 33720 33722 33724 33726 33728 33730 33732 33734 33736 33738 33740 33742 33744 33746 33748 33750 33752 33754 33756 33758 33760 33762 33764 33766 33768 33770 33772 33774 33776 33778 33780 33782 33784 33786 33788 33790 58240 9216 9218 9220 9222 9224 9226 9228 9230 9232 9234 9236 9238 9240 9242 9244 9246 9248 9250 9252 9254 9256 9258 9260 9262 9264 9266 9268 9270 9272 9274 9276 9278 9280 9282 9284 9286 9288 9290 9292 9294 9296 9298 9300 9302 9304 9306 9308 9310 9312 9314 9316 9318 9320 9322 9324 9326 9328 9330 9332 9334 9336 9338 9340 9342 33792 33794 33796 33798 33800 33802 33804 33806 33808 33810 33812 33814 33816 33818 33820 33822 33824 33826 33828 33830 33832 33834 33836 33838 33840 33842 33844 33846 33848 33850 33852 33854 33856 33858 33860 33862 33864 33866 33868 33870 33872 33874 33876 33878 33880 33882 33884 33886 33888 33890 33892 33894 33896 33898 33900 33902 33904 33906 33908 33910 33912 33914 33916 33918 58368 9344 9346 9348 9350 9352 9354 9356 9358 9360 9362 9364 9366 9368 9370 9372 9374 9376 9378 9380 9382 9384 9386 9388 9390 9392 9394 9396 9398 9400 9402 9404 9406 9408 9410 9412 9414 9416 9418 9420 9422 9424 9426 9428 9430 9432 9434 9436 9438 9440 9442 9444 9446 9448 9450 9452 9454 9456 9458 9460 9462 9464 9466 9468 9470 33920 33922 33924 33926 33928 33930 33932 33934 33936 33938 33940 33942 33944 33946 33948 33950 33952 33954 33956 33958 33960 33962 33964 33966 33968 33970 33972 33974 33976 33978 33980 33982 33984 33986 33988 33990 33992 33994 33996 33998 34000 34002 34004 34006 34008 34010 34012 34014 34016 34018 34020 34022 34024 34026 34028 34030 34032 34034 34036 34038 34040 34042 34044 34046 58496 9472 9474 9476 9478 9480 9482 9484 9486 9488 9490 9492 9494 9496 9498 9500 9502 9504 9506 9508 9510 9512 9514 9516 9518 9520 9522 9524 9526 9528 9530 9532 9534 9536 9538 9540 9542 9544 9546 9548 9550 9552 9554 9556 9558 9560 9562 9564 9566 9568 9570 9572 9574 9576 9578 9580 9582 9584 9586 9588 9590 9592 9594 9596 9598 34048 34050 34052 34054 34056 34058 34060 34062 34064 34066 34068 34070 34072 34074 34076 34078 34080 34082 34084 34086 34088 34090 34092 34094 34096 34098 34100 34102 34104 34106 34108 34110 34112 34114 34116 34118 34120 34122 34124 34126 34128 34130 34132 34134 34136 34138 34140 34142 34144 34146 34148 34150 34152 34154 34156 34158 34160 34162 34164 34166 34168 34170 34172 34174 58624 9600 9602 9604 9606 9608 9610 9612 9614 9616 9618 9620 9622 9624 9626 9628 9630 9632 9634 9636 9638 9640 9642 9644 9646 9648 9650 9652 9654 9656 9658 9660 9662 9664 9666 9668 9670 9672 9674 9676 9678 9680 9682 9684 9686 9688 9690 9692 9694 9696 9698 9700 9702 9704 9706 9708 9710 9712 9714 9716 9718 9720 9722 9724 9726 34176 34178 34180 34182 34184 34186 34188 34190 34192 34194 34196 34198 34200 34202 34204 34206 34208 34210 34212 34214 34216 34218 34220 34222 34224 34226 34228 34230 34232 34234 34236 34238 34240 34242 34244 34246 34248 34250 34252 34254 34256 34258 34260 34262 34264 34266 34268 34270 34272 34274 34276 34278 34280 34282 34284 34286 34288 34290 34292 34294 34296 34298 34300 34302 58752 9728 9730 9732 9734 9736 9738 9740 9742 9744 9746 9748 9750 9752 9754 9756 9758 9760 9762 9764 9766 9768 9770 9772 9774 9776 9778 9780 9782 9784 9786 9788 9790 9792 9794 9796 9798 9800 9802 9804 9806 9808 9810 9812 9814 9816 9818 9820 9822 9824 9826 9828 9830 9832 9834 9836 9838 9840 9842 9844 9846 9848 9850 9852 9854 34304 34306 34308 34310 34312 34314 34316 34318 34320 34322 34324 34326 34328 34330 34332 34334 34336 34338 34340 34342 34344 34346 34348 34350 34352 34354 34356 34358 34360 34362 34364 34366 34368 34370 34372 34374 34376 34378 34380 34382 34384 34386 34388 34390 34392 34394 34396 34398 34400 34402 34404 34406 34408 34410 34412 34414 34416 34418 34420 34422 34424 34426 34428 34430 58880 9856 9858 9860 9862 9864 9866 9868 9870 9872 9874 9876 9878 9880 9882 9884 9886 9888 9890 9892 9894 9896 9898 9900 9902 9904 9906 9908 9910 9912 9914 9916 9918 9920 9922 9924 9926 9928 9930 9932 9934 9936 9938 9940 9942 9944 9946 9948 9950 9952 9954 9956 9958 9960 9962 9964 9966 9968 9970 9972 9974 9976 9978 9980 9982 34432 34434 34436 34438 34440 34442 34444 34446 34448 34450 34452 34454 34456 34458 34460 34462 34464 34466 34468 34470 34472 34474 34476 34478 34480 34482 34484 34486 34488 34490 34492 34494 34496 34498 34500 34502 34504 34506 34508 34510 34512 34514 34516 34518 34520 34522 34524 34526 34528 34530 34532 34534 34536 34538 34540 34542 34544 34546 34548 34550 34552 34554 34556 34558 59008 9984 9986 9988 9990 9992 9994 9996 9998 10000 10002 10004 10006 10008 10010 10012 10014 10016 10018 10020 10022 10024 10026 10028 10030 10032 10034 10036 10038 10040 10042 10044 10046 10048 10050 10052 10054 10056 10058 10060 10062 10064 10066 10068 10070 10072 10074 10076 10078 10080 10082 10084 10086 10088 10090 10092 10094 10096 10098 10100 10102 10104 10106 10108 10110 34560 34562 34564 34566 34568 34570 34572 34574 34576 34578 34580 34582 34584 34586 34588 34590 34592 34594 34596 34598 34600 34602 34604 34606 34608 34610 34612 34614 34616 34618 34620 34622 34624 34626 34628 34630 34632 34634 34636 34638 34640 34642 34644 34646 34648 34650 34652 34654 34656 34658 34660 34662 34664 34666 34668 34670 34672 34674 34676 34678 34680 34682 34684 34686 59136 10112 10114 10116 10118 10120 10122 10124 10126 10128 10130 10132 10134 10136 10138 10140 10142 10144 10146 10148 10150 10152 10154 10156 10158 10160 10162 10164 10166 10168 10170 10172 10174 10176 10178 10180 10182 10184 10186 10188 10190 10192 10194 10196 10198 10200 10202 10204 10206 10208 10210 10212 10214 10216 10218 10220 10222 10224 10226 10228 10230 10232 10234 10236 10238 34688 34690 34692 34694 34696 34698 34700 34702 34704 34706 34708 34710 34712 34714 34716 34718 34720 34722 34724 34726 34728 34730 34732 34734 34736 34738 34740 34742 34744 34746 34748 34750 34752 34754 34756 34758 34760 34762 34764 34766 34768 34770 34772 34774 34776 34778 34780 34782 34784 34786 34788 34790 34792 34794 34796 34798 34800 34802 34804 34806 34808 34810 34812 34814 59264 10240 10242 10244 10246 10248 10250 10252 10254 10256 10258 10260 10262 10264 10266 10268 10270 10272 10274 10276 10278 10280 10282 10284 10286 10288 10290 10292 10294 10296 10298 10300 10302 10304 10306 10308 10310 10312 10314 10316 10318 10320 10322 10324 10326 10328 10330 10332 10334 10336 10338 10340 10342 10344 10346 10348 10350 10352 10354 10356 10358 10360 10362 10364 10366 34816 34818 34820 34822 34824 34826 34828 34830 34832 34834 34836 34838 34840 34842 34844 34846 34848 34850 34852 34854 34856 34858 34860 34862 34864 34866 34868 34870 34872 34874 34876 34878 34880 34882 34884 34886 34888 34890 34892 34894 34896 34898 34900 34902 34904 34906 34908 34910 34912 34914 34916 34918 34920 34922 34924 34926 34928 34930 34932 34934 34936 34938 34940 34942 59392 10368 10370 10372 10374 10376 10378 10380 10382 10384 10386 10388 10390 10392 10394 10396 10398 10400 10402 10404 10406 10408 10410 10412 10414 10416 10418 10420 10422 10424 10426 10428 10430 10432 10434 10436 10438 10440 10442 10444 10446 10448 10450 10452 10454 10456 10458 10460 10462 10464 10466 10468 10470 10472 10474 10476 10478 10480 10482 10484 10486 10488 10490 10492 10494 34944 34946 34948 34950 34952 34954 34956 34958 34960 34962 34964 34966 34968 34970 34972 34974 34976 34978 34980 34982 34984 34986 34988 34990 34992 34994 34996 34998 35000 35002 35004 35006 35008 35010 35012 35014 35016 35018 35020 35022 35024 35026 35028 35030 35032 35034 35036 35038 35040 35042 35044 35046 35048 35050 35052 35054 35056 35058 35060 35062 35064 35066 35068 35070 59520 10496 10498 10500 10502 10504 10506 10508 10510 10512 10514 10516 10518 10520 10522 10524 10526 10528 10530 10532 10534 10536 10538 10540 10542 10544 10546 10548 10550 10552 10554 10556 10558 10560 10562 10564 10566 10568 10570 10572 10574 10576 10578 10580 10582 10584 10586 10588 10590 10592 10594 10596 10598 10600 10602 10604 10606 10608 10610 10612 10614 10616 10618 10620 10622 35072 35074 35076 35078 35080 35082 35084 35086 35088 35090 35092 35094 35096 35098 35100 35102 35104 35106 35108 35110 35112 35114 35116 35118 35120 35122 35124 35126 35128 35130 35132 35134 35136 35138 35140 35142 35144 35146 35148 35150 35152 35154 35156 35158 35160 35162 35164 35166 35168 35170 35172 35174 35176 35178 35180 35182 35184 35186 35188 35190 35192 35194 35196 35198 59648 10624 10626 10628 10630 10632 10634 10636 10638 10640 10642 10644 10646 10648 10650 10652 10654 10656 10658 10660 10662 10664 10666 10668 10670 10672 10674 10676 10678 10680 10682 10684 10686 10688 10690 10692 10694 10696 10698 10700 10702 10704 10706 10708 10710 10712 10714 10716 10718 10720 10722 10724 10726 10728 10730 10732 10734 10736 10738 10740 10742 10744 10746 10748 10750 35200 35202 35204 35206 35208 35210 35212 35214 35216 35218 35220 35222 35224 35226 35228 35230 35232 35234 35236 35238 35240 35242 35244 35246 35248 35250 35252 35254 35256 35258 35260 35262 35264 35266 35268 35270 35272 35274 35276 35278 35280 35282 35284 35286 35288 35290 35292 35294 35296 35298 35300 35302 35304 35306 35308 35310 35312 35314 35316 35318 35320 35322 35324 35326 59776 10752 10754 10756 10758 10760 10762 10764 10766 10768 10770 10772 10774 10776 10778 10780 10782 10784 10786 10788 10790 10792 10794 10796 10798 10800 10802 10804 10806 10808 10810 10812 10814 10816 10818 10820 10822 10824 10826 10828 10830 10832 10834 10836 10838 10840 10842 10844 10846 10848 10850 10852 10854 10856 10858 10860 10862 10864 10866 10868 10870 10872 10874 10876 10878 35328 35330 35332 35334 35336 35338 35340 35342 35344 35346 35348 35350 35352 35354 35356 35358 35360 35362 35364 35366 35368 35370 35372 35374 35376 35378 35380 35382 35384 35386 35388 35390 35392 35394 35396 35398 35400 35402 35404 35406 35408 35410 35412 35414 35416 35418 35420 35422 35424 35426 35428 35430 35432 35434 35436 35438 35440 35442 35444 35446 35448 35450 35452 35454 59904 10880 10882 10884 10886 10888 10890 10892 10894 10896 10898 10900 10902 10904 10906 10908 10910 10912 10914 10916 10918 10920 10922 10924 10926 10928 10930 10932 10934 10936 10938 10940 10942 10944 10946 10948 10950 10952 10954 10956 10958 10960 10962 10964 10966 10968 10970 10972 10974 10976 10978 10980 10982 10984 10986 10988 10990 10992 10994 10996 10998 11000 11002 11004 11006 35456 35458 35460 35462 35464 35466 35468 35470 35472 35474 35476 35478 35480 35482 35484 35486 35488 35490 35492 35494 35496 35498 35500 35502 35504 35506 35508 35510 35512 35514 35516 35518 35520 35522 35524 35526 35528 35530 35532 35534 35536 35538 35540 35542 35544 35546 35548 35550 35552 35554 35556 35558 35560 35562 35564 35566 35568 35570 35572 35574 35576 35578 35580 35582 60032 11008 11010 11012 11014 11016 11018 11020 11022 11024 11026 11028 11030 11032 11034 11036 11038 11040 11042 11044 11046 11048 11050 11052 11054 11056 11058 11060 11062 11064 11066 11068 11070 11072 11074 11076 11078 11080 11082 11084 11086 11088 11090 11092 11094 11096 11098 11100 11102 11104 11106 11108 11110 11112 11114 11116 11118 11120 11122 11124 11126 11128 11130 11132 11134 35584 35586 35588 35590 35592 35594 35596 35598 35600 35602 35604 35606 35608 35610 35612 35614 35616 35618 35620 35622 35624 35626 35628 35630 35632 35634 35636 35638 35640 35642 35644 35646 35648 35650 35652 35654 35656 35658 35660 35662 35664 35666 35668 35670 35672 35674 35676 35678 35680 35682 35684 35686 35688 35690 35692 35694 35696 35698 35700 35702 35704 35706 35708 35710 60160 11136 11138 11140 11142 11144 11146 11148 11150 11152 11154 11156 11158 11160 11162 11164 11166 11168 11170 11172 11174 11176 11178 11180 11182 11184 11186 11188 11190 11192 11194 11196 11198 11200 11202 11204 11206 11208 11210 11212 11214 11216 11218 11220 11222 11224 11226 11228 11230 11232 11234 11236 11238 11240 11242 11244 11246 11248 11250 11252 11254 11256 11258 11260 11262 35712 35714 35716 35718 35720 35722 35724 35726 35728 35730 35732 35734 35736 35738 35740 35742 35744 35746 35748 35750 35752 35754 35756 35758 35760 35762 35764 35766 35768 35770 35772 35774 35776 35778 35780 35782 35784 35786 35788 35790 35792 35794 35796 35798 35800 35802 35804 35806 35808 35810 35812 35814 35816 35818 35820 35822 35824 35826 35828 35830 35832 35834 35836 35838 60288 11264 11266 11268 11270 11272 11274 11276 11278 11280 11282 11284 11286 11288 11290 11292 11294 11296 11298 11300 11302 11304 11306 11308 11310 11312 11314 11316 11318 11320 11322 11324 11326 11328 11330 11332 11334 11336 11338 11340 11342 11344 11346 11348 11350 11352 11354 11356 11358 11360 11362 11364 11366 11368 11370 11372 11374 11376 11378 11380 11382 11384 11386 11388 11390 35840 35842 35844 35846 35848 35850 35852 35854 35856 35858 35860 35862 35864 35866 35868 35870 35872 35874 35876 35878 35880 35882 35884 35886 35888 35890 35892 35894 35896 35898 35900 35902 35904 35906 35908 35910 35912 35914 35916 35918 35920 35922 35924 35926 35928 35930 35932 35934 35936 35938 35940 35942 35944 35946 35948 35950 35952 35954 35956 35958 35960 35962 35964 35966 60416 11392 11394 11396 11398 11400 11402 11404 11406 11408 11410 11412 11414 11416 11418 11420 11422 11424 11426 11428 11430 11432 11434 11436 11438 11440 11442 11444 11446 11448 11450 11452 11454 11456 11458 11460 11462 11464 11466 11468 11470 11472 11474 11476 11478 11480 11482 11484 11486 11488 11490 11492 11494 11496 11498 11500 11502 11504 11506 11508 11510 11512 11514 11516 11518 35968 35970 35972 35974 35976 35978 35980 35982 35984 35986 35988 35990 35992 35994 35996 35998 36000 36002 36004 36006 36008 36010 36012 36014 36016 36018 36020 36022 36024 36026 36028 36030 36032 36034 36036 36038 36040 36042 36044 36046 36048 36050 36052 36054 36056 36058 36060 36062 36064 36066 36068 36070 36072 36074 36076 36078 36080 36082 36084 36086 36088 36090 36092 36094 60544 11520 11522 11524 11526 11528 11530 11532 11534 11536 11538 11540 11542 11544 11546 11548 11550 11552 11554 11556 11558 11560 11562 11564 11566 11568 11570 11572 11574 11576 11578 11580 11582 11584 11586 11588 11590 11592 11594 11596 11598 11600 11602 11604 11606 11608 11610 11612 11614 11616 11618 11620 11622 11624 11626 11628 11630 11632 11634 11636 11638 11640 11642 11644 11646 36096 36098 36100 36102 36104 36106 36108 36110 36112 36114 36116 36118 36120 36122 36124 36126 36128 36130 36132 36134 36136 36138 36140 36142 36144 36146 36148 36150 36152 36154 36156 36158 36160 36162 36164 36166 36168 36170 36172 36174 36176 36178 36180 36182 36184 36186 36188 36190 36192 36194 36196 36198 36200 36202 36204 36206 36208 36210 36212 36214 36216 36218 36220 36222 60672 11648 11650 11652 11654 11656 11658 11660 11662 11664 11666 11668 11670 11672 11674 11676 11678 11680 11682 11684 11686 11688 11690 11692 11694 11696 11698 11700 11702 11704 11706 11708 11710 11712 11714 11716 11718 11720 11722 11724 11726 11728 11730 11732 11734 11736 11738 11740 11742 11744 11746 11748 11750 11752 11754 11756 11758 11760 11762 11764 11766 11768 11770 11772 11774 36224 36226 36228 36230 36232 36234 36236 36238 36240 36242 36244 36246 36248 36250 36252 36254 36256 36258 36260 36262 36264 36266 36268 36270 36272 36274 36276 36278 36280 36282 36284 36286 36288 36290 36292 36294 36296 36298 36300 36302 36304 36306 36308 36310 36312 36314 36316 36318 36320 36322 36324 36326 36328 36330 36332 36334 36336 36338 36340 36342 36344 36346 36348 36350 60800 11776 11778 11780 11782 11784 11786 11788 11790 11792 11794 11796 11798 11800 11802 11804 11806 11808 11810 11812 11814 11816 11818 11820 11822 11824 11826 11828 11830 11832 11834 11836 11838 11840 11842 11844 11846 11848 11850 11852 11854 11856 11858 11860 11862 11864 11866 11868 11870 11872 11874 11876 11878 11880 11882 11884 11886 11888 11890 11892 11894 11896 11898 11900 11902 36352 36354 36356 36358 36360 36362 36364 36366 36368 36370 36372 36374 36376 36378 36380 36382 36384 36386 36388 36390 36392 36394 36396 36398 36400 36402 36404 36406 36408 36410 36412 36414 36416 36418 36420 36422 36424 36426 36428 36430 36432 36434 36436 36438 36440 36442 36444 36446 36448 36450 36452 36454 36456 36458 36460 36462 36464 36466 36468 36470 36472 36474 36476 36478 60928 11904 11906 11908 11910 11912 11914 11916 11918 11920 11922 11924 11926 11928 11930 11932 11934 11936 11938 11940 11942 11944 11946 11948 11950 11952 11954 11956 11958 11960 11962 11964 11966 11968 11970 11972 11974 11976 11978 11980 11982 11984 11986 11988 11990 11992 11994 11996 11998 12000 12002 12004 12006 12008 12010 12012 12014 12016 12018 12020 12022 12024 12026 12028 12030 36480 36482 36484 36486 36488 36490 36492 36494 36496 36498 36500 36502 36504 36506 36508 36510 36512 36514 36516 36518 36520 36522 36524 36526 36528 36530 36532 36534 36536 36538 36540 36542 36544 36546 36548 36550 36552 36554 36556 36558 36560 36562 36564 36566 36568 36570 36572 36574 36576 36578 36580 36582 36584 36586 36588 36590 36592 36594 36596 36598 36600 36602 36604 36606 61056 12032 12034 12036 12038 12040 12042 12044 12046 12048 12050 12052 12054 12056 12058 12060 12062 12064 12066 12068 12070 12072 12074 12076 12078 12080 12082 12084 12086 12088 12090 12092 12094 12096 12098 12100 12102 12104 12106 12108 12110 12112 12114 12116 12118 12120 12122 12124 12126 12128 12130 12132 12134 12136 12138 12140 12142 12144 12146 12148 12150 12152 12154 12156 12158 36608 36610 36612 36614 36616 36618 36620 36622 36624 36626 36628 36630 36632 36634 36636 36638 36640 36642 36644 36646 36648 36650 36652 36654 36656 36658 36660 36662 36664 36666 36668 36670 36672 36674 36676 36678 36680 36682 36684 36686 36688 36690 36692 36694 36696 36698 36700 36702 36704 36706 36708 36710 36712 36714 36716 36718 36720 36722 36724 36726 36728 36730 36732 36734 61184 12160 12162 12164 12166 12168 12170 12172 12174 12176 12178 12180 12182 12184 12186 12188 12190 12192 12194 12196 12198 12200 12202 12204 12206 12208 12210 12212 12214 12216 12218 12220 12222 12224 12226 12228 12230 12232 12234 12236 12238 12240 12242 12244 12246 12248 12250 12252 12254 12256 12258 12260 12262 12264 12266 12268 12270 12272 12274 12276 12278 12280 12282 12284 12286 36736 36738 36740 36742 36744 36746 36748 36750 36752 36754 36756 36758 36760 36762 36764 36766 36768 36770 36772 36774 36776 36778 36780 36782 36784 36786 36788 36790 36792 36794 36796 36798 36800 36802 36804 36806 36808 36810 36812 36814 36816 36818 36820 36822 36824 36826 36828 36830 36832 36834 36836 36838 36840 36842 36844 36846 36848 36850 36852 36854 36856 36858 36860 36862 61312 12288 12290 12292 12294 12296 12298 12300 12302 12304 12306 12308 12310 12312 12314 12316 12318 12320 12322 12324 12326 12328 12330 12332 12334 12336 12338 12340 12342 12344 12346 12348 12350 12352 12354 12356 12358 12360 12362 12364 12366 12368 12370 12372 12374 12376 12378 12380 12382 12384 12386 12388 12390 12392 12394 12396 12398 12400 12402 12404 12406 12408 12410 12412 12414 36864 36866 36868 36870 36872 36874 36876 36878 36880 36882 36884 36886 36888 36890 36892 36894 36896 36898 36900 36902 36904 36906 36908 36910 36912 36914 36916 36918 36920 36922 36924 36926 36928 36930 36932 36934 36936 36938 36940 36942 36944 36946 36948 36950 36952 36954 36956 36958 36960 36962 36964 36966 36968 36970 36972 36974 36976 36978 36980 36982 36984 36986 36988 36990 61440 16384 16386 16388 16390 16392 16394 16396 16398 16400 16402 16404 16406 16408 16410 16412 16414 16416 16418 16420 16422 16424 16426 16428 16430 16432 16434 16436 16438 16440 16442 16444 16446 16448 16450 16452 16454 16456 16458 16460 16462 16464 16466 16468 16470 16472 16474 16476 16478 16480 16482 16484 16486 16488 16490 16492 16494 16496 16498 16500 16502 16504 16506 16508 16510 40960 40962 40964 40966 40968 40970 40972 40974 40976 40978 40980 40982 40984 40986 40988 40990 40992 40994 40996 40998 41000 41002 41004 41006 41008 41010 41012 41014 41016 41018 41020 41022 41024 41026 41028 41030 41032 41034 41036 41038 41040 41042 41044 41046 41048 41050 41052 41054 41056 41058 41060 41062 41064 41066 41068 41070 41072 41074 41076 41078 41080 41082 41084 41086 65536 16512 16514 16516 16518 16520 16522 16524 16526 16528 16530 16532 16534 16536 16538 16540 16542 16544 16546 16548 16550 16552 16554 16556 16558 16560 16562 16564 16566 16568 16570 16572 16574 16576 16578 16580 16582 16584 16586 16588 16590 16592 16594 16596 16598 16600 16602 16604 16606 16608 16610 16612 16614 16616 16618 16620 16622 16624 16626 16628 16630 16632 16634 16636 16638 41088 41090 41092 41094 41096 41098 41100 41102 41104 41106 41108 41110 41112 41114 41116 41118 41120 41122 41124 41126 41128 41130 41132 41134 41136 41138 41140 41142 41144 41146 41148 41150 41152 41154 41156 41158 41160 41162 41164 41166 41168 41170 41172 41174 41176 41178 41180 41182 41184 41186 41188 41190 41192 41194 41196 41198 41200 41202 41204 41206 41208 41210 41212 41214 65664 16640 16642 16644 16646 16648 16650 16652 16654 16656 16658 16660 16662 16664 16666 16668 16670 16672 16674 16676 16678 16680 16682 16684 16686 16688 16690 16692 16694 16696 16698 16700 16702 16704 16706 16708 16710 16712 16714 16716 16718 16720 16722 16724 16726 16728 16730 16732 16734 16736 16738 16740 16742 16744 16746 16748 16750 16752 16754 16756 16758 16760 16762 16764 16766 41216 41218 41220 41222 41224 41226 41228 41230 41232 41234 41236 41238 41240 41242 41244 41246 41248 41250 41252 41254 41256 41258 41260 41262 41264 41266 41268 41270 41272 41274 41276 41278 41280 41282 41284 41286 41288 41290 41292 41294 41296 41298 41300 41302 41304 41306 41308 41310 41312 41314 41316 41318 41320 41322 41324 41326 41328 41330 41332 41334 41336 41338 41340 41342 65792 16768 16770 16772 16774 16776 16778 16780 16782 16784 16786 16788 16790 16792 16794 16796 16798 16800 16802 16804 16806 16808 16810 16812 16814 16816 16818 16820 16822 16824 16826 16828 16830 16832 16834 16836 16838 16840 16842 16844 16846 16848 16850 16852 16854 16856 16858 16860 16862 16864 16866 16868 16870 16872 16874 16876 16878 16880 16882 16884 16886 16888 16890 16892 16894 41344 41346 41348 41350 41352 41354 41356 41358 41360 41362 41364 41366 41368 41370 41372 41374 41376 41378 41380 41382 41384 41386 41388 41390 41392 41394 41396 41398 41400 41402 41404 41406 41408 41410 41412 41414 41416 41418 41420 41422 41424 41426 41428 41430 41432 41434 41436 41438 41440 41442 41444 41446 41448 41450 41452 41454 41456 41458 41460 41462 41464 41466 41468 41470 65920 16896 16898 16900 16902 16904 16906 16908 16910 16912 16914 16916 16918 16920 16922 16924 16926 16928 16930 16932 16934 16936 16938 16940 16942 16944 16946 16948 16950 16952 16954 16956 16958 16960 16962 16964 16966 16968 16970 16972 16974 16976 16978 16980 16982 16984 16986 16988 16990 16992 16994 16996 16998 17000 17002 17004 17006 17008 17010 17012 17014 17016 17018 17020 17022 41472 41474 41476 41478 41480 41482 41484 41486 41488 41490 41492 41494 41496 41498 41500 41502 41504 41506 41508 41510 41512 41514 41516 41518 41520 41522 41524 41526 41528 41530 41532 41534 41536 41538 41540 41542 41544 41546 41548 41550 41552 41554 41556 41558 41560 41562 41564 41566 41568 41570 41572 41574 41576 41578 41580 41582 41584 41586 41588 41590 41592 41594 41596 41598 66048 17024 17026 17028 17030 17032 17034 17036 17038 17040 17042 17044 17046 17048 17050 17052 17054 17056 17058 17060 17062 17064 17066 17068 17070 17072 17074 17076 17078 17080 17082 17084 17086 17088 17090 17092 17094 17096 17098 17100 17102 17104 17106 17108 17110 17112 17114 17116 17118 17120 17122 17124 17126 17128 17130 17132 17134 17136 17138 17140 17142 17144 17146 17148 17150 41600 41602 41604 41606 41608 41610 41612 41614 41616 41618 41620 41622 41624 41626 41628 41630 41632 41634 41636 41638 41640 41642 41644 41646 41648 41650 41652 41654 41656 41658 41660 41662 41664 41666 41668 41670 41672 41674 41676 41678 41680 41682 41684 41686 41688 41690 41692 41694 41696 41698 41700 41702 41704 41706 41708 41710 41712 41714 41716 41718 41720 41722 41724 41726 66176 17152 17154 17156 17158 17160 17162 17164 17166 17168 17170 17172 17174 17176 17178 17180 17182 17184 17186 17188 17190 17192 17194 17196 17198 17200 17202 17204 17206 17208 17210 17212 17214 17216 17218 17220 17222 17224 17226 17228 17230 17232 17234 17236 17238 17240 17242 17244 17246 17248 17250 17252 17254 17256 17258 17260 17262 17264 17266 17268 17270 17272 17274 17276 17278 41728 41730 41732 41734 41736 41738 41740 41742 41744 41746 41748 41750 41752 41754 41756 41758 41760 41762 41764 41766 41768 41770 41772 41774 41776 41778 41780 41782 41784 41786 41788 41790 41792 41794 41796 41798 41800 41802 41804 41806 41808 41810 41812 41814 41816 41818 41820 41822 41824 41826 41828 41830 41832 41834 41836 41838 41840 41842 41844 41846 41848 41850 41852 41854 66304 17280 17282 17284 17286 17288 17290 17292 17294 17296 17298 17300 17302 17304 17306 17308 17310 17312 17314 17316 17318 17320 17322 17324 17326 17328 17330 17332 17334 17336 17338 17340 17342 17344 17346 17348 17350 17352 17354 17356 17358 17360 17362 17364 17366 17368 17370 17372 17374 17376 17378 17380 17382 17384 17386 17388 17390 17392 17394 17396 17398 17400 17402 17404 17406 41856 41858 41860 41862 41864 41866 41868 41870 41872 41874 41876 41878 41880 41882 41884 41886 41888 41890 41892 41894 41896 41898 41900 41902 41904 41906 41908 41910 41912 41914 41916 41918 41920 41922 41924 41926 41928 41930 41932 41934 41936 41938 41940 41942 41944 41946 41948 41950 41952 41954 41956 41958 41960 41962 41964 41966 41968 41970 41972 41974 41976 41978 41980 41982 66432 17408 17410 17412 17414 17416 17418 17420 17422 17424 17426 17428 17430 17432 17434 17436 17438 17440 17442 17444 17446 17448 17450 17452 17454 17456 17458 17460 17462 17464 17466 17468 17470 17472 17474 17476 17478 17480 17482 17484 17486 17488 17490 17492 17494 17496 17498 17500 17502 17504 17506 17508 17510 17512 17514 17516 17518 17520 17522 17524 17526 17528 17530 17532 17534 41984 41986 41988 41990 41992 41994 41996 41998 42000 42002 42004 42006 42008 42010 42012 42014 42016 42018 42020 42022 42024 42026 42028 42030 42032 42034 42036 42038 42040 42042 42044 42046 42048 42050 42052 42054 42056 42058 42060 42062 42064 42066 42068 42070 42072 42074 42076 42078 42080 42082 42084 42086 42088 42090 42092 42094 42096 42098 42100 42102 42104 42106 42108 42110 66560 17536 17538 17540 17542 17544 17546 17548 17550 17552 17554 17556 17558 17560 17562 17564 17566 17568 17570 17572 17574 17576 17578 17580 17582 17584 17586 17588 17590 17592 17594 17596 17598 17600 17602 17604 17606 17608 17610 17612 17614 17616 17618 17620 17622 17624 17626 17628 17630 17632 17634 17636 17638 17640 17642 17644 17646 17648 17650 17652 17654 17656 17658 17660 17662 42112 42114 42116 42118 42120 42122 42124 42126 42128 42130 42132 42134 42136 42138 42140 42142 42144 42146 42148 42150 42152 42154 42156 42158 42160 42162 42164 42166 42168 42170 42172 42174 42176 42178 42180 42182 42184 42186 42188 42190 42192 42194 42196 42198 42200 42202 42204 42206 42208 42210 42212 42214 42216 42218 42220 42222 42224 42226 42228 42230 42232 42234 42236 42238 66688 17664 17666 17668 17670 17672 17674 17676 17678 17680 17682 17684 17686 17688 17690 17692 17694 17696 17698 17700 17702 17704 17706 17708 17710 17712 17714 17716 17718 17720 17722 17724 17726 17728 17730 17732 17734 17736 17738 17740 17742 17744 17746 17748 17750 17752 17754 17756 17758 17760 17762 17764 17766 17768 17770 17772 17774 17776 17778 17780 17782 17784 17786 17788 17790 42240 42242 42244 42246 42248 42250 42252 42254 42256 42258 42260 42262 42264 42266 42268 42270 42272 42274 42276 42278 42280 42282 42284 42286 42288 42290 42292 42294 42296 42298 42300 42302 42304 42306 42308 42310 42312 42314 42316 42318 42320 42322 42324 42326 42328 42330 42332 42334 42336 42338 42340 42342 42344 42346 42348 42350 42352 42354 42356 42358 42360 42362 42364 42366 66816 17792 17794 17796 17798 17800 17802 17804 17806 17808 17810 17812 17814 17816 17818 17820 17822 17824 17826 17828 17830 17832 17834 17836 17838 17840 17842 17844 17846 17848 17850 17852 17854 17856 17858 17860 17862 17864 17866 17868 17870 17872 17874 17876 17878 17880 17882 17884 17886 17888 17890 17892 17894 17896 17898 17900 17902 17904 17906 17908 17910 17912 17914 17916 17918 42368 42370 42372 42374 42376 42378 42380 42382 42384 42386 42388 42390 42392 42394 42396 42398 42400 42402 42404 42406 42408 42410 42412 42414 42416 42418 42420 42422 42424 42426 42428 42430 42432 42434 42436 42438 42440 42442 42444 42446 42448 42450 42452 42454 42456 42458 42460 42462 42464 42466 42468 42470 42472 42474 42476 42478 42480 42482 42484 42486 42488 42490 42492 42494 66944 17920 17922 17924 17926 17928 17930 17932 17934 17936 17938 17940 17942 17944 17946 17948 17950 17952 17954 17956 17958 17960 17962 17964 17966 17968 17970 17972 17974 17976 17978 17980 17982 17984 17986 17988 17990 17992 17994 17996 17998 18000 18002 18004 18006 18008 18010 18012 18014 18016 18018 18020 18022 18024 18026 18028 18030 18032 18034 18036 18038 18040 18042 18044 18046 42496 42498 42500 42502 42504 42506 42508 42510 42512 42514 42516 42518 42520 42522 42524 42526 42528 42530 42532 42534 42536 42538 42540 42542 42544 42546 42548 42550 42552 42554 42556 42558 42560 42562 42564 42566 42568 42570 42572 42574 42576 42578 42580 42582 42584 42586 42588 42590 42592 42594 42596 42598 42600 42602 42604 42606 42608 42610 42612 42614 42616 42618 42620 42622 67072 18048 18050 18052 18054 18056 18058 18060 18062 18064 18066 18068 18070 18072 18074 18076 18078 18080 18082 18084 18086 18088 18090 18092 18094 18096 18098 18100 18102 18104 18106 18108 18110 18112 18114 18116 18118 18120 18122 18124 18126 18128 18130 18132 18134 18136 18138 18140 18142 18144 18146 18148 18150 18152 18154 18156 18158 18160 18162 18164 18166 18168 18170 18172 18174 42624 42626 42628 42630 42632 42634 42636 42638 42640 42642 42644 42646 42648 42650 42652 42654 42656 42658 42660 42662 42664 42666 42668 42670 42672 42674 42676 42678 42680 42682 42684 42686 42688 42690 42692 42694 42696 42698 42700 42702 42704 42706 42708 42710 42712 42714 42716 42718 42720 42722 42724 42726 42728 42730 42732 42734 42736 42738 42740 42742 42744 42746 42748 42750 67200 18176 18178 18180 18182 18184 18186 18188 18190 18192 18194 18196 18198 18200 18202 18204 18206 18208 18210 18212 18214 18216 18218 18220 18222 18224 18226 18228 18230 18232 18234 18236 18238 18240 18242 18244 18246 18248 18250 18252 18254 18256 18258 18260 18262 18264 18266 18268 18270 18272 18274 18276 18278 18280 18282 18284 18286 18288 18290 18292 18294 18296 18298 18300 18302 42752 42754 42756 42758 42760 42762 42764 42766 42768 42770 42772 42774 42776 42778 42780 42782 42784 42786 42788 42790 42792 42794 42796 42798 42800 42802 42804 42806 42808 42810 42812 42814 42816 42818 42820 42822 42824 42826 42828 42830 42832 42834 42836 42838 42840 42842 42844 42846 42848 42850 42852 42854 42856 42858 42860 42862 42864 42866 42868 42870 42872 42874 42876 42878 67328 18304 18306 18308 18310 18312 18314 18316 18318 18320 18322 18324 18326 18328 18330 18332 18334 18336 18338 18340 18342 18344 18346 18348 18350 18352 18354 18356 18358 18360 18362 18364 18366 18368 18370 18372 18374 18376 18378 18380 18382 18384 18386 18388 18390 18392 18394 18396 18398 18400 18402 18404 18406 18408 18410 18412 18414 18416 18418 18420 18422 18424 18426 18428 18430 42880 42882 42884 42886 42888 42890 42892 42894 42896 42898 42900 42902 42904 42906 42908 42910 42912 42914 42916 42918 42920 42922 42924 42926 42928 42930 42932 42934 42936 42938 42940 42942 42944 42946 42948 42950 42952 42954 42956 42958 42960 42962 42964 42966 42968 42970 42972 42974 42976 42978 42980 42982 42984 42986 42988 42990 42992 42994 42996 42998 43000 43002 43004 43006 67456 18432 18434 18436 18438 18440 18442 18444 18446 18448 18450 18452 18454 18456 18458 18460 18462 18464 18466 18468 18470 18472 18474 18476 18478 18480 18482 18484 18486 18488 18490 18492 18494 18496 18498 18500 18502 18504 18506 18508 18510 18512 18514 18516 18518 18520 18522 18524 18526 18528 18530 18532 18534 18536 18538 18540 18542 18544 18546 18548 18550 18552 18554 18556 18558 43008 43010 43012 43014 43016 43018 43020 43022 43024 43026 43028 43030 43032 43034 43036 43038 43040 43042 43044 43046 43048 43050 43052 43054 43056 43058 43060 43062 43064 43066 43068 43070 43072 43074 43076 43078 43080 43082 43084 43086 43088 43090 43092 43094 43096 43098 43100 43102 43104 43106 43108 43110 43112 43114 43116 43118 43120 43122 43124 43126 43128 43130 43132 43134 67584 18560 18562 18564 18566 18568 18570 18572 18574 18576 18578 18580 18582 18584 18586 18588 18590 18592 18594 18596 18598 18600 18602 18604 18606 18608 18610 18612 18614 18616 18618 18620 18622 18624 18626 18628 18630 18632 18634 18636 18638 18640 18642 18644 18646 18648 18650 18652 18654 18656 18658 18660 18662 18664 18666 18668 18670 18672 18674 18676 18678 18680 18682 18684 18686 43136 43138 43140 43142 43144 43146 43148 43150 43152 43154 43156 43158 43160 43162 43164 43166 43168 43170 43172 43174 43176 43178 43180 43182 43184 43186 43188 43190 43192 43194 43196 43198 43200 43202 43204 43206 43208 43210 43212 43214 43216 43218 43220 43222 43224 43226 43228 43230 43232 43234 43236 43238 43240 43242 43244 43246 43248 43250 43252 43254 43256 43258 43260 43262 67712 18688 18690 18692 18694 18696 18698 18700 18702 18704 18706 18708 18710 18712 18714 18716 18718 18720 18722 18724 18726 18728 18730 18732 18734 18736 18738 18740 18742 18744 18746 18748 18750 18752 18754 18756 18758 18760 18762 18764 18766 18768 18770 18772 18774 18776 18778 18780 18782 18784 18786 18788 18790 18792 18794 18796 18798 18800 18802 18804 18806 18808 18810 18812 18814 43264 43266 43268 43270 43272 43274 43276 43278 43280 43282 43284 43286 43288 43290 43292 43294 43296 43298 43300 43302 43304 43306 43308 43310 43312 43314 43316 43318 43320 43322 43324 43326 43328 43330 43332 43334 43336 43338 43340 43342 43344 43346 43348 43350 43352 43354 43356 43358 43360 43362 43364 43366 43368 43370 43372 43374 43376 43378 43380 43382 43384 43386 43388 43390 67840 18816 18818 18820 18822 18824 18826 18828 18830 18832 18834 18836 18838 18840 18842 18844 18846 18848 18850 18852 18854 18856 18858 18860 18862 18864 18866 18868 18870 18872 18874 18876 18878 18880 18882 18884 18886 18888 18890 18892 18894 18896 18898 18900 18902 18904 18906 18908 18910 18912 18914 18916 18918 18920 18922 18924 18926 18928 18930 18932 18934 18936 18938 18940 18942 43392 43394 43396 43398 43400 43402 43404 43406 43408 43410 43412 43414 43416 43418 43420 43422 43424 43426 43428 43430 43432 43434 43436 43438 43440 43442 43444 43446 43448 43450 43452 43454 43456 43458 43460 43462 43464 43466 43468 43470 43472 43474 43476 43478 43480 43482 43484 43486 43488 43490 43492 43494 43496 43498 43500 43502 43504 43506 43508 43510 43512 43514 43516 43518 67968 18944 18946 18948 18950 18952 18954 18956 18958 18960 18962 18964 18966 18968 18970 18972 18974 18976 18978 18980 18982 18984 18986 18988 18990 18992 18994 18996 18998 19000 19002 19004 19006 19008 19010 19012 19014 19016 19018 19020 19022 19024 19026 19028 19030 19032 19034 19036 19038 19040 19042 19044 19046 19048 19050 19052 19054 19056 19058 19060 19062 19064 19066 19068 19070 43520 43522 43524 43526 43528 43530 43532 43534 43536 43538 43540 43542 43544 43546 43548 43550 43552 43554 43556 43558 43560 43562 43564 43566 43568 43570 43572 43574 43576 43578 43580 43582 43584 43586 43588 43590 43592 43594 43596 43598 43600 43602 43604 43606 43608 43610 43612 43614 43616 43618 43620 43622 43624 43626 43628 43630 43632 43634 43636 43638 43640 43642 43644 43646 68096 19072 19074 19076 19078 19080 19082 19084 19086 19088 19090 19092 19094 19096 19098 19100 19102 19104 19106 19108 19110 19112 19114 19116 19118 19120 19122 19124 19126 19128 19130 19132 19134 19136 19138 19140 19142 19144 19146 19148 19150 19152 19154 19156 19158 19160 19162 19164 19166 19168 19170 19172 19174 19176 19178 19180 19182 19184 19186 19188 19190 19192 19194 19196 19198 43648 43650 43652 43654 43656 43658 43660 43662 43664 43666 43668 43670 43672 43674 43676 43678 43680 43682 43684 43686 43688 43690 43692 43694 43696 43698 43700 43702 43704 43706 43708 43710 43712 43714 43716 43718 43720 43722 43724 43726 43728 43730 43732 43734 43736 43738 43740 43742 43744 43746 43748 43750 43752 43754 43756 43758 43760 43762 43764 43766 43768 43770 43772 43774 68224 19200 19202 19204 19206 19208 19210 19212 19214 19216 19218 19220 19222 19224 19226 19228 19230 19232 19234 19236 19238 19240 19242 19244 19246 19248 19250 19252 19254 19256 19258 19260 19262 19264 19266 19268 19270 19272 19274 19276 19278 19280 19282 19284 19286 19288 19290 19292 19294 19296 19298 19300 19302 19304 19306 19308 19310 19312 19314 19316 19318 19320 19322 19324 19326 43776 43778 43780 43782 43784 43786 43788 43790 43792 43794 43796 43798 43800 43802 43804 43806 43808 43810 43812 43814 43816 43818 43820 43822 43824 43826 43828 43830 43832 43834 43836 43838 43840 43842 43844 43846 43848 43850 43852 43854 43856 43858 43860 43862 43864 43866 43868 43870 43872 43874 43876 43878 43880 43882 43884 43886 43888 43890 43892 43894 43896 43898 43900 43902 68352 19328 19330 19332 19334 19336 19338 19340 19342 19344 19346 19348 19350 19352 19354 19356 19358 19360 19362 19364 19366 19368 19370 19372 19374 19376 19378 19380 19382 19384 19386 19388 19390 19392 19394 19396 19398 19400 19402 19404 19406 19408 19410 19412 19414 19416 19418 19420 19422 19424 19426 19428 19430 19432 19434 19436 19438 19440 19442 19444 19446 19448 19450 19452 19454 43904 43906 43908 43910 43912 43914 43916 43918 43920 43922 43924 43926 43928 43930 43932 43934 43936 43938 43940 43942 43944 43946 43948 43950 43952 43954 43956 43958 43960 43962 43964 43966 43968 43970 43972 43974 43976 43978 43980 43982 43984 43986 43988 43990 43992 43994 43996 43998 44000 44002 44004 44006 44008 44010 44012 44014 44016 44018 44020 44022 44024 44026 44028 44030 68480 19456 19458 19460 19462 19464 19466 19468 19470 19472 19474 19476 19478 19480 19482 19484 19486 19488 19490 19492 19494 19496 19498 19500 19502 19504 19506 19508 19510 19512 19514 19516 19518 19520 19522 19524 19526 19528 19530 19532 19534 19536 19538 19540 19542 19544 19546 19548 19550 19552 19554 19556 19558 19560 19562 19564 19566 19568 19570 19572 19574 19576 19578 19580 19582 44032 44034 44036 44038 44040 44042 44044 44046 44048 44050 44052 44054 44056 44058 44060 44062 44064 44066 44068 44070 44072 44074 44076 44078 44080 44082 44084 44086 44088 44090 44092 44094 44096 44098 44100 44102 44104 44106 44108 44110 44112 44114 44116 44118 44120 44122 44124 44126 44128 44130 44132 44134 44136 44138 44140 44142 44144 44146 44148 44150 44152 44154 44156 44158 68608 19584 19586 19588 19590 19592 19594 19596 19598 19600 19602 19604 19606 19608 19610 19612 19614 19616 19618 19620 19622 19624 19626 19628 19630 19632 19634 19636 19638 19640 19642 19644 19646 19648 19650 19652 19654 19656 19658 19660 19662 19664 19666 19668 19670 19672 19674 19676 19678 19680 19682 19684 19686 19688 19690 19692 19694 19696 19698 19700 19702 19704 19706 19708 19710 44160 44162 44164 44166 44168 44170 44172 44174 44176 44178 44180 44182 44184 44186 44188 44190 44192 44194 44196 44198 44200 44202 44204 44206 44208 44210 44212 44214 44216 44218 44220 44222 44224 44226 44228 44230 44232 44234 44236 44238 44240 44242 44244 44246 44248 44250 44252 44254 44256 44258 44260 44262 44264 44266 44268 44270 44272 44274 44276 44278 44280 44282 44284 44286 68736 19712 19714 19716 19718 19720 19722 19724 19726 19728 19730 19732 19734 19736 19738 19740 19742 19744 19746 19748 19750 19752 19754 19756 19758 19760 19762 19764 19766 19768 19770 19772 19774 19776 19778 19780 19782 19784 19786 19788 19790 19792 19794 19796 19798 19800 19802 19804 19806 19808 19810 19812 19814 19816 19818 19820 19822 19824 19826 19828 19830 19832 19834 19836 19838 44288 44290 44292 44294 44296 44298 44300 44302 44304 44306 44308 44310 44312 44314 44316 44318 44320 44322 44324 44326 44328 44330 44332 44334 44336 44338 44340 44342 44344 44346 44348 44350 44352 44354 44356 44358 44360 44362 44364 44366 44368 44370 44372 44374 44376 44378 44380 44382 44384 44386 44388 44390 44392 44394 44396 44398 44400 44402 44404 44406 44408 44410 44412 44414 68864 19840 19842 19844 19846 19848 19850 19852 19854 19856 19858 19860 19862 19864 19866 19868 19870 19872 19874 19876 19878 19880 19882 19884 19886 19888 19890 19892 19894 19896 19898 19900 19902 19904 19906 19908 19910 19912 19914 19916 19918 19920 19922 19924 19926 19928 19930 19932 19934 19936 19938 19940 19942 19944 19946 19948 19950 19952 19954 19956 19958 19960 19962 19964 19966 44416 44418 44420 44422 44424 44426 44428 44430 44432 44434 44436 44438 44440 44442 44444 44446 44448 44450 44452 44454 44456 44458 44460 44462 44464 44466 44468 44470 44472 44474 44476 44478 44480 44482 44484 44486 44488 44490 44492 44494 44496 44498 44500 44502 44504 44506 44508 44510 44512 44514 44516 44518 44520 44522 44524 44526 44528 44530 44532 44534 44536 44538 44540 44542 68992 19968 19970 19972 19974 19976 19978 19980 19982 19984 19986 19988 19990 19992 19994 19996 19998 20000 20002 20004 20006 20008 20010 20012 20014 20016 20018 20020 20022 20024 20026 20028 20030 20032 20034 20036 20038 20040 20042 20044 20046 20048 20050 20052 20054 20056 20058 20060 20062 20064 20066 20068 20070 20072 20074 20076 20078 20080 20082 20084 20086 20088 20090 20092 20094 44544 44546 44548 44550 44552 44554 44556 44558 44560 44562 44564 44566 44568 44570 44572 44574 44576 44578 44580 44582 44584 44586 44588 44590 44592 44594 44596 44598 44600 44602 44604 44606 44608 44610 44612 44614 44616 44618 44620 44622 44624 44626 44628 44630 44632 44634 44636 44638 44640 44642 44644 44646 44648 44650 44652 44654 44656 44658 44660 44662 44664 44666 44668 44670 69120 20096 20098 20100 20102 20104 20106 20108 20110 20112 20114 20116 20118 20120 20122 20124 20126 20128 20130 20132 20134 20136 20138 20140 20142 20144 20146 20148 20150 20152 20154 20156 20158 20160 20162 20164 20166 20168 20170 20172 20174 20176 20178 20180 20182 20184 20186 20188 20190 20192 20194 20196 20198 20200 20202 20204 20206 20208 20210 20212 20214 20216 20218 20220 20222 44672 44674 44676 44678 44680 44682 44684 44686 44688 44690 44692 44694 44696 44698 44700 44702 44704 44706 44708 44710 44712 44714 44716 44718 44720 44722 44724 44726 44728 44730 44732 44734 44736 44738 44740 44742 44744 44746 44748 44750 44752 44754 44756 44758 44760 44762 44764 44766 44768 44770 44772 44774 44776 44778 44780 44782 44784 44786 44788 44790 44792 44794 44796 44798 69248 20224 20226 20228 20230 20232 20234 20236 20238 20240 20242 20244 20246 20248 20250 20252 20254 20256 20258 20260 20262 20264 20266 20268 20270 20272 20274 20276 20278 20280 20282 20284 20286 20288 20290 20292 20294 20296 20298 20300 20302 20304 20306 20308 20310 20312 20314 20316 20318 20320 20322 20324 20326 20328 20330 20332 20334 20336 20338 20340 20342 20344 20346 20348 20350 44800 44802 44804 44806 44808 44810 44812 44814 44816 44818 44820 44822 44824 44826 44828 44830 44832 44834 44836 44838 44840 44842 44844 44846 44848 44850 44852 44854 44856 44858 44860 44862 44864 44866 44868 44870 44872 44874 44876 44878 44880 44882 44884 44886 44888 44890 44892 44894 44896 44898 44900 44902 44904 44906 44908 44910 44912 44914 44916 44918 44920 44922 44924 44926 69376 20352 20354 20356 20358 20360 20362 20364 20366 20368 20370 20372 20374 20376 20378 20380 20382 20384 20386 20388 20390 20392 20394 20396 20398 20400 20402 20404 20406 20408 20410 20412 20414 20416 20418 20420 20422 20424 20426 20428 20430 20432 20434 20436 20438 20440 20442 20444 20446 20448 20450 20452 20454 20456 20458 20460 20462 20464 20466 20468 20470 20472 20474 20476 20478 44928 44930 44932 44934 44936 44938 44940 44942 44944 44946 44948 44950 44952 44954 44956 44958 44960 44962 44964 44966 44968 44970 44972 44974 44976 44978 44980 44982 44984 44986 44988 44990 44992 44994 44996 44998 45000 45002 45004 45006 45008 45010 45012 45014 45016 45018 45020 45022 45024 45026 45028 45030 45032 45034 45036 45038 45040 45042 45044 45046 45048 45050 45052 45054 69504 20480 20482 20484 20486 20488 20490 20492 20494 20496 20498 20500 20502 20504 20506 20508 20510 20512 20514 20516 20518 20520 20522 20524 20526 20528 20530 20532 20534 20536 20538 20540 20542 20544 20546 20548 20550 20552 20554 20556 20558 20560 20562 20564 20566 20568 20570 20572 20574 20576 20578 20580 20582 20584 20586 20588 20590 20592 20594 20596 20598 20600 20602 20604 20606 45056 45058 45060 45062 45064 45066 45068 45070 45072 45074 45076 45078 45080 45082 45084 45086 45088 45090 45092 45094 45096 45098 45100 45102 45104 45106 45108 45110 45112 45114 45116 45118 45120 45122 45124 45126 45128 45130 45132 45134 45136 45138 45140 45142 45144 45146 45148 45150 45152 45154 45156 45158 45160 45162 45164 45166 45168 45170 45172 45174 45176 45178 45180 45182 69632 73728 73730 73732 73734 73736 73738 73740 73742 73744 73746 73748 73750 73752 73754 73756 73758 73760 73762 73764 73766 73768 73770 73772 73774 73776 73778 73780 73782 73784 73786 73788 73790 73792 73794 73796 73798 73800 73802 73804 73806 73808 73810 73812 73814 73816 73818 73820 73822 73824 73826 73828 73830 73832 73834 73836 73838 73840 73842 73844 73846 73848 73850 73852 73854 98304 98306 98308 98310 98312 98314 98316 98318 98320 98322 98324 98326 98328 98330 98332 98334 98336 98338 98340 98342 98344 98346 98348 98350 98352 98354 98356 98358 98360 98362 98364 98366 98368 98370 98372 98374 98376 98378 98380 98382 98384 98386 98388 98390 98392 98394 98396 98398 98400 98402 98404 98406 98408 98410 98412 98414 98416 98418 98420 98422 98424 98426 98428 98430 122880 73856 73858 73860 73862 73864 73866 73868 73870 73872 73874 73876 73878 73880 73882 73884 73886 73888 73890 73892 73894 73896 73898 73900 73902 73904 73906 73908 73910 73912 73914 73916 73918 73920 73922 73924 73926 73928 73930 73932 73934 73936 73938 73940 73942 73944 73946 73948 73950 73952 73954 73956 73958 73960 73962 73964 73966 73968 73970 73972 73974 73976 73978 73980 73982 98432 98434 98436 98438 98440 98442 98444 98446 98448 98450 98452 98454 98456 98458 98460 98462 98464 98466 98468 98470 98472 98474 98476 98478 98480 98482 98484 98486 98488 98490 98492 98494 98496 98498 98500 98502 98504 98506 98508 98510 98512 98514 98516 98518 98520 98522 98524 98526 98528 98530 98532 98534 98536 98538 98540 98542 98544 98546 98548 98550 98552 98554 98556 98558 123008 73984 73986 73988 73990 73992 73994 73996 73998 74000 74002 74004 74006 74008 74010 74012 74014 74016 74018 74020 74022 74024 74026 74028 74030 74032 74034 74036 74038 74040 74042 74044 74046 74048 74050 74052 74054 74056 74058 74060 74062 74064 74066 74068 74070 74072 74074 74076 74078 74080 74082 74084 74086 74088 74090 74092 74094 74096 74098 74100 74102 74104 74106 74108 74110 98560 98562 98564 98566 98568 98570 98572 98574 98576 98578 98580 98582 98584 98586 98588 98590 98592 98594 98596 98598 98600 98602 98604 98606 98608 98610 98612 98614 98616 98618 98620 98622 98624 98626 98628 98630 98632 98634 98636 98638 98640 98642 98644 98646 98648 98650 98652 98654 98656 98658 98660 98662 98664 98666 98668 98670 98672 98674 98676 98678 98680 98682 98684 98686 123136 74112 74114 74116 74118 74120 74122 74124 74126 74128 74130 74132 74134 74136 74138 74140 74142 74144 74146 74148 74150 74152 74154 74156 74158 74160 74162 74164 74166 74168 74170 74172 74174 74176 74178 74180 74182 74184 74186 74188 74190 74192 74194 74196 74198 74200 74202 74204 74206 74208 74210 74212 74214 74216 74218 74220 74222 74224 74226 74228 74230 74232 74234 74236 74238 98688 98690 98692 98694 98696 98698 98700 98702 98704 98706 98708 98710 98712 98714 98716 98718 98720 98722 98724 98726 98728 98730 98732 98734 98736 98738 98740 98742 98744 98746 98748 98750 98752 98754 98756 98758 98760 98762 98764 98766 98768 98770 98772 98774 98776 98778 98780 98782 98784 98786 98788 98790 98792 98794 98796 98798 98800 98802 98804 98806 98808 98810 98812 98814 123264 74240 74242 74244 74246 74248 74250 74252 74254 74256 74258 74260 74262 74264 74266 74268 74270 74272 74274 74276 74278 74280 74282 74284 74286 74288 74290 74292 74294 74296 74298 74300 74302 74304 74306 74308 74310 74312 74314 74316 74318 74320 74322 74324 74326 74328 74330 74332 74334 74336 74338 74340 74342 74344 74346 74348 74350 74352 74354 74356 74358 74360 74362 74364 74366 98816 98818 98820 98822 98824 98826 98828 98830 98832 98834 98836 98838 98840 98842 98844 98846 98848 98850 98852 98854 98856 98858 98860 98862 98864 98866 98868 98870 98872 98874 98876 98878 98880 98882 98884 98886 98888 98890 98892 98894 98896 98898 98900 98902 98904 98906 98908 98910 98912 98914 98916 98918 98920 98922 98924 98926 98928 98930 98932 98934 98936 98938 98940 98942 123392 74368 74370 74372 74374 74376 74378 74380 74382 74384 74386 74388 74390 74392 74394 74396 74398 74400 74402 74404 74406 74408 74410 74412 74414 74416 74418 74420 74422 74424 74426 74428 74430 74432 74434 74436 74438 74440 74442 74444 74446 74448 74450 74452 74454 74456 74458 74460 74462 74464 74466 74468 74470 74472 74474 74476 74478 74480 74482 74484 74486 74488 74490 74492 74494 98944 98946 98948 98950 98952 98954 98956 98958 98960 98962 98964 98966 98968 98970 98972 98974 98976 98978 98980 98982 98984 98986 98988 98990 98992 98994 98996 98998 99000 99002 99004 99006 99008 99010 99012 99014 99016 99018 99020 99022 99024 99026 99028 99030 99032 99034 99036 99038 99040 99042 99044 99046 99048 99050 99052 99054 99056 99058 99060 99062 99064 99066 99068 99070 123520 74496 74498 74500 74502 74504 74506 74508 74510 74512 74514 74516 74518 74520 74522 74524 74526 74528 74530 74532 74534 74536 74538 74540 74542 74544 74546 74548 74550 74552 74554 74556 74558 74560 74562 74564 74566 74568 74570 74572 74574 74576 74578 74580 74582 74584 74586 74588 74590 74592 74594 74596 74598 74600 74602 74604 74606 74608 74610 74612 74614 74616 74618 74620 74622 99072 99074 99076 99078 99080 99082 99084 99086 99088 99090 99092 99094 99096 99098 99100 99102 99104 99106 99108 99110 99112 99114 99116 99118 99120 99122 99124 99126 99128 99130 99132 99134 99136 99138 99140 99142 99144 99146 99148 99150 99152 99154 99156 99158 99160 99162 99164 99166 99168 99170 99172 99174 99176 99178 99180 99182 99184 99186 99188 99190 99192 99194 99196 99198 123648 74624 74626 74628 74630 74632 74634 74636 74638 74640 74642 74644 74646 74648 74650 74652 74654 74656 74658 74660 74662 74664 74666 74668 74670 74672 74674 74676 74678 74680 74682 74684 74686 74688 74690 74692 74694 74696 74698 74700 74702 74704 74706 74708 74710 74712 74714 74716 74718 74720 74722 74724 74726 74728 74730 74732 74734 74736 74738 74740 74742 74744 74746 74748 74750 99200 99202 99204 99206 99208 99210 99212 99214 99216 99218 99220 99222 99224 99226 99228 99230 99232 99234 99236 99238 99240 99242 99244 99246 99248 99250 99252 99254 99256 99258 99260 99262 99264 99266 99268 99270 99272 99274 99276 99278 99280 99282 99284 99286 99288 99290 99292 99294 99296 99298 99300 99302 99304 99306 99308 99310 99312 99314 99316 99318 99320 99322 99324 99326 123776 74752 74754 74756 74758 74760 74762 74764 74766 74768 74770 74772 74774 74776 74778 74780 74782 74784 74786 74788 74790 74792 74794 74796 74798 74800 74802 74804 74806 74808 74810 74812 74814 74816 74818 74820 74822 74824 74826 74828 74830 74832 74834 74836 74838 74840 74842 74844 74846 74848 74850 74852 74854 74856 74858 74860 74862 74864 74866 74868 74870 74872 74874 74876 74878 99328 99330 99332 99334 99336 99338 99340 99342 99344 99346 99348 99350 99352 99354 99356 99358 99360 99362 99364 99366 99368 99370 99372 99374 99376 99378 99380 99382 99384 99386 99388 99390 99392 99394 99396 99398 99400 99402 99404 99406 99408 99410 99412 99414 99416 99418 99420 99422 99424 99426 99428 99430 99432 99434 99436 99438 99440 99442 99444 99446 99448 99450 99452 99454 123904 74880 74882 74884 74886 74888 74890 74892 74894 74896 74898 74900 74902 74904 74906 74908 74910 74912 74914 74916 74918 74920 74922 74924 74926 74928 74930 74932 74934 74936 74938 74940 74942 74944 74946 74948 74950 74952 74954 74956 74958 74960 74962 74964 74966 74968 74970 74972 74974 74976 74978 74980 74982 74984 74986 74988 74990 74992 74994 74996 74998 75000 75002 75004 75006 99456 99458 99460 99462 99464 99466 99468 99470 99472 99474 99476 99478 99480 99482 99484 99486 99488 99490 99492 99494 99496 99498 99500 99502 99504 99506 99508 99510 99512 99514 99516 99518 99520 99522 99524 99526 99528 99530 99532 99534 99536 99538 99540 99542 99544 99546 99548 99550 99552 99554 99556 99558 99560 99562 99564 99566 99568 99570 99572 99574 99576 99578 99580 99582 124032 75008 75010 75012 75014 75016 75018 75020 75022 75024 75026 75028 75030 75032 75034 75036 75038 75040 75042 75044 75046 75048 75050 75052 75054 75056 75058 75060 75062 75064 75066 75068 75070 75072 75074 75076 75078 75080 75082 75084 75086 75088 75090 75092 75094 75096 75098 75100 75102 75104 75106 75108 75110 75112 75114 75116 75118 75120 75122 75124 75126 75128 75130 75132 75134 99584 99586 99588 99590 99592 99594 99596 99598 99600 99602 99604 99606 99608 99610 99612 99614 99616 99618 99620 99622 99624 99626 99628 99630 99632 99634 99636 99638 99640 99642 99644 99646 99648 99650 99652 99654 99656 99658 99660 99662 99664 99666 99668 99670 99672 99674 99676 99678 99680 99682 99684 99686 99688 99690 99692 99694 99696 99698 99700 99702 99704 99706 99708 99710 124160 75136 75138 75140 75142 75144 75146 75148 75150 75152 75154 75156 75158 75160 75162 75164 75166 75168 75170 75172 75174 75176 75178 75180 75182 75184 75186 75188 75190 75192 75194 75196 75198 75200 75202 75204 75206 75208 75210 75212 75214 75216 75218 75220 75222 75224 75226 75228 75230 75232 75234 75236 75238 75240 75242 75244 75246 75248 75250 75252 75254 75256 75258 75260 75262 99712 99714 99716 99718 99720 99722 99724 99726 99728 99730 99732 99734 99736 99738 99740 99742 99744 99746 99748 99750 99752 99754 99756 99758 99760 99762 99764 99766 99768 99770 99772 99774 99776 99778 99780 99782 99784 99786 99788 99790 99792 99794 99796 99798 99800 99802 99804 99806 99808 99810 99812 99814 99816 99818 99820 99822 99824 99826 99828 99830 99832 99834 99836 99838 124288 75264 75266 75268 75270 75272 75274 75276 75278 75280 75282 75284 75286 75288 75290 75292 75294 75296 75298 75300 75302 75304 75306 75308 75310 75312 75314 75316 75318 75320 75322 75324 75326 75328 75330 75332 75334 75336 75338 75340 75342 75344 75346 75348 75350 75352 75354 75356 75358 75360 75362 75364 75366 75368 75370 75372 75374 75376 75378 75380 75382 75384 75386 75388 75390 99840 99842 99844 99846 99848 99850 99852 99854 99856 99858 99860 99862 99864 99866 99868 99870 99872 99874 99876 99878 99880 99882 99884 99886 99888 99890 99892 99894 99896 99898 99900 99902 99904 99906 99908 99910 99912 99914 99916 99918 99920 99922 99924 99926 99928 99930 99932 99934 99936 99938 99940 99942 99944 99946 99948 99950 99952 99954 99956 99958 99960 99962 99964 99966 124416 75392 75394 75396 75398 75400 75402 75404 75406 75408 75410 75412 75414 75416 75418 75420 75422 75424 75426 75428 75430 75432 75434 75436 75438 75440 75442 75444 75446 75448 75450 75452 75454 75456 75458 75460 75462 75464 75466 75468 75470 75472 75474 75476 75478 75480 75482 75484 75486 75488 75490 75492 75494 75496 75498 75500 75502 75504 75506 75508 75510 75512 75514 75516 75518 99968 99970 99972 99974 99976 99978 99980 99982 99984 99986 99988 99990 99992 99994 99996 99998 100000 100002 100004 100006 100008 100010 100012 100014 100016 100018 100020 100022 100024 100026 100028 100030 100032 100034 100036 100038 100040 100042 100044 100046 100048 100050 100052 100054 100056 100058 100060 100062 100064 100066 100068 100070 100072 100074 100076 100078 100080 100082 100084 100086 100088 100090 100092 100094 124544 75520 75522 75524 75526 75528 75530 75532 75534 75536 75538 75540 75542 75544 75546 75548 75550 75552 75554 75556 75558 75560 75562 75564 75566 75568 75570 75572 75574 75576 75578 75580 75582 75584 75586 75588 75590 75592 75594 75596 75598 75600 75602 75604 75606 75608 75610 75612 75614 75616 75618 75620 75622 75624 75626 75628 75630 75632 75634 75636 75638 75640 75642 75644 75646 100096 100098 100100 100102 100104 100106 100108 100110 100112 100114 100116 100118 100120 100122 100124 100126 100128 100130 100132 100134 100136 100138 100140 100142 100144 100146 100148 100150 100152 100154 100156 100158 100160 100162 100164 100166 100168 100170 100172 100174 100176 100178 100180 100182 100184 100186 100188 100190 100192 100194 100196 100198 100200 100202 100204 100206 100208 100210 100212 100214 100216 100218 100220 100222 124672 75648 75650 75652 75654 75656 75658 75660 75662 75664 75666 75668 75670 75672 75674 75676 75678 75680 75682 75684 75686 75688 75690 75692 75694 75696 75698 75700 75702 75704 75706 75708 75710 75712 75714 75716 75718 75720 75722 75724 75726 75728 75730 75732 75734 75736 75738 75740 75742 75744 75746 75748 75750 75752 75754 75756 75758 75760 75762 75764 75766 75768 75770 75772 75774 100224 100226 100228 100230 100232 100234 100236 100238 100240 100242 100244 100246 100248 100250 100252 100254 100256 100258 100260 100262 100264 100266 100268 100270 100272 100274 100276 100278 100280 100282 100284 100286 100288 100290 100292 100294 100296 100298 100300 100302 100304 100306 100308 100310 100312 100314 100316 100318 100320 100322 100324 100326 100328 100330 100332 100334 100336 100338 100340 100342 100344 100346 100348 100350 124800 75776 75778 75780 75782 75784 75786 75788 75790 75792 75794 75796 75798 75800 75802 75804 75806 75808 75810 75812 75814 75816 75818 75820 75822 75824 75826 75828 75830 75832 75834 75836 75838 75840 75842 75844 75846 75848 75850 75852 75854 75856 75858 75860 75862 75864 75866 75868 75870 75872 75874 75876 75878 75880 75882 75884 75886 75888 75890 75892 75894 75896 75898 75900 75902 100352 100354 100356 100358 100360 100362 100364 100366 100368 100370 100372 100374 100376 100378 100380 100382 100384 100386 100388 100390 100392 100394 100396 100398 100400 100402 100404 100406 100408 100410 100412 100414 100416 100418 100420 100422 100424 100426 100428 100430 100432 100434 100436 100438 100440 100442 100444 100446 100448 100450 100452 100454 100456 100458 100460 100462 100464 100466 100468 100470 100472 100474 100476 100478 124928 75904 75906 75908 75910 75912 75914 75916 75918 75920 75922 75924 75926 75928 75930 75932 75934 75936 75938 75940 75942 75944 75946 75948 75950 75952 75954 75956 75958 75960 75962 75964 75966 75968 75970 75972 75974 75976 75978 75980 75982 75984 75986 75988 75990 75992 75994 75996 75998 76000 76002 76004 76006 76008 76010 76012 76014 76016 76018 76020 76022 76024 76026 76028 76030 100480 100482 100484 100486 100488 100490 100492 100494 100496 100498 100500 100502 100504 100506 100508 100510 100512 100514 100516 100518 100520 100522 100524 100526 100528 100530 100532 100534 100536 100538 100540 100542 100544 100546 100548 100550 100552 100554 100556 100558 100560 100562 100564 100566 100568 100570 100572 100574 100576 100578 100580 100582 100584 100586 100588 100590 100592 100594 100596 100598 100600 100602 100604 100606 125056 76032 76034 76036 76038 76040 76042 76044 76046 76048 76050 76052 76054 76056 76058 76060 76062 76064 76066 76068 76070 76072 76074 76076 76078 76080 76082 76084 76086 76088 76090 76092 76094 76096 76098 76100 76102 76104 76106 76108 76110 76112 76114 76116 76118 76120 76122 76124 76126 76128 76130 76132 76134 76136 76138 76140 76142 76144 76146 76148 76150 76152 76154 76156 76158 100608 100610 100612 100614 100616 100618 100620 100622 100624 100626 100628 100630 100632 100634 100636 100638 100640 100642 100644 100646 100648 100650 100652 100654 100656 100658 100660 100662 100664 100666 100668 100670 100672 100674 100676 100678 100680 100682 100684 100686 100688 100690 100692 100694 100696 100698 100700 100702 100704 100706 100708 100710 100712 100714 100716 100718 100720 100722 100724 100726 100728 100730 100732 100734 125184 76160 76162 76164 76166 76168 76170 76172 76174 76176 76178 76180 76182 76184 76186 76188 76190 76192 76194 76196 76198 76200 76202 76204 76206 76208 76210 76212 76214 76216 76218 76220 76222 76224 76226 76228 76230 76232 76234 76236 76238 76240 76242 76244 76246 76248 76250 76252 76254 76256 76258 76260 76262 76264 76266 76268 76270 76272 76274 76276 76278 76280 76282 76284 76286 100736 100738 100740 100742 100744 100746 100748 100750 100752 100754 100756 100758 100760 100762 100764 100766 100768 100770 100772 100774 100776 100778 100780 100782 100784 100786 100788 100790 100792 100794 100796 100798 100800 100802 100804 100806 100808 100810 100812 100814 100816 100818 100820 100822 100824 100826 100828 100830 100832 100834 100836 100838 100840 100842 100844 100846 100848 100850 100852 100854 100856 100858 100860 100862 125312 76288 76290 76292 76294 76296 76298 76300 76302 76304 76306 76308 76310 76312 76314 76316 76318 76320 76322 76324 76326 76328 76330 76332 76334 76336 76338 76340 76342 76344 76346 76348 76350 76352 76354 76356 76358 76360 76362 76364 76366 76368 76370 76372 76374 76376 76378 76380 76382 76384 76386 76388 76390 76392 76394 76396 76398 76400 76402 76404 76406 76408 76410 76412 76414 100864 100866 100868 100870 100872 100874 100876 100878 100880 100882 100884 100886 100888 100890 100892 100894 100896 100898 100900 100902 100904 100906 100908 100910 100912 100914 100916 100918 100920 100922 100924 100926 100928 100930 100932 100934 100936 100938 100940 100942 100944 100946 100948 100950 100952 100954 100956 100958 100960 100962 100964 100966 100968 100970 100972 100974 100976 100978 100980 100982 100984 100986 100988 100990 125440 76416 76418 76420 76422 76424 76426 76428 76430 76432 76434 76436 76438 76440 76442 76444 76446 76448 76450 76452 76454 76456 76458 76460 76462 76464 76466 76468 76470 76472 76474 76476 76478 76480 76482 76484 76486 76488 76490 76492 76494 76496 76498 76500 76502 76504 76506 76508 76510 76512 76514 76516 76518 76520 76522 76524 76526 76528 76530 76532 76534 76536 76538 76540 76542 100992 100994 100996 100998 101000 101002 101004 101006 101008 101010 101012 101014 101016 101018 101020 101022 101024 101026 101028 101030 101032 101034 101036 101038 101040 101042 101044 101046 101048 101050 101052 101054 101056 101058 101060 101062 101064 101066 101068 101070 101072 101074 101076 101078 101080 101082 101084 101086 101088 101090 101092 101094 101096 101098 101100 101102 101104 101106 101108 101110 101112 101114 101116 101118 125568 76544 76546 76548 76550 76552 76554 76556 76558 76560 76562 76564 76566 76568 76570 76572 76574 76576 76578 76580 76582 76584 76586 76588 76590 76592 76594 76596 76598 76600 76602 76604 76606 76608 76610 76612 76614 76616 76618 76620 76622 76624 76626 76628 76630 76632 76634 76636 76638 76640 76642 76644 76646 76648 76650 76652 76654 76656 76658 76660 76662 76664 76666 76668 76670 101120 101122 101124 101126 101128 101130 101132 101134 101136 101138 101140 101142 101144 101146 101148 101150 101152 101154 101156 101158 101160 101162 101164 101166 101168 101170 101172 101174 101176 101178 101180 101182 101184 101186 101188 101190 101192 101194 101196 101198 101200 101202 101204 101206 101208 101210 101212 101214 101216 101218 101220 101222 101224 101226 101228 101230 101232 101234 101236 101238 101240 101242 101244 101246 125696 76672 76674 76676 76678 76680 76682 76684 76686 76688 76690 76692 76694 76696 76698 76700 76702 76704 76706 76708 76710 76712 76714 76716 76718 76720 76722 76724 76726 76728 76730 76732 76734 76736 76738 76740 76742 76744 76746 76748 76750 76752 76754 76756 76758 76760 76762 76764 76766 76768 76770 76772 76774 76776 76778 76780 76782 76784 76786 76788 76790 76792 76794 76796 76798 101248 101250 101252 101254 101256 101258 101260 101262 101264 101266 101268 101270 101272 101274 101276 101278 101280 101282 101284 101286 101288 101290 101292 101294 101296 101298 101300 101302 101304 101306 101308 101310 101312 101314 101316 101318 101320 101322 101324 101326 101328 101330 101332 101334 101336 101338 101340 101342 101344 101346 101348 101350 101352 101354 101356 101358 101360 101362 101364 101366 101368 101370 101372 101374 125824 76800 76802 76804 76806 76808 76810 76812 76814 76816 76818 76820 76822 76824 76826 76828 76830 76832 76834 76836 76838 76840 76842 76844 76846 76848 76850 76852 76854 76856 76858 76860 76862 76864 76866 76868 76870 76872 76874 76876 76878 76880 76882 76884 76886 76888 76890 76892 76894 76896 76898 76900 76902 76904 76906 76908 76910 76912 76914 76916 76918 76920 76922 76924 76926 101376 101378 101380 101382 101384 101386 101388 101390 101392 101394 101396 101398 101400 101402 101404 101406 101408 101410 101412 101414 101416 101418 101420 101422 101424 101426 101428 101430 101432 101434 101436 101438 101440 101442 101444 101446 101448 101450 101452 101454 101456 101458 101460 101462 101464 101466 101468 101470 101472 101474 101476 101478 101480 101482 101484 101486 101488 101490 101492 101494 101496 101498 101500 101502 125952 76928 76930 76932 76934 76936 76938 76940 76942 76944 76946 76948 76950 76952 76954 76956 76958 76960 76962 76964 76966 76968 76970 76972 76974 76976 76978 76980 76982 76984 76986 76988 76990 76992 76994 76996 76998 77000 77002 77004 77006 77008 77010 77012 77014 77016 77018 77020 77022 77024 77026 77028 77030 77032 77034 77036 77038 77040 77042 77044 77046 77048 77050 77052 77054 101504 101506 101508 101510 101512 101514 101516 101518 101520 101522 101524 101526 101528 101530 101532 101534 101536 101538 101540 101542 101544 101546 101548 101550 101552 101554 101556 101558 101560 101562 101564 101566 101568 101570 101572 101574 101576 101578 101580 101582 101584 101586 101588 101590 101592 101594 101596 101598 101600 101602 101604 101606 101608 101610 101612 101614 101616 101618 101620 101622 101624 101626 101628 101630 126080 77056 77058 77060 77062 77064 77066 77068 77070 77072 77074 77076 77078 77080 77082 77084 77086 77088 77090 77092 77094 77096 77098 77100 77102 77104 77106 77108 77110 77112 77114 77116 77118 77120 77122 77124 77126 77128 77130 77132 77134 77136 77138 77140 77142 77144 77146 77148 77150 77152 77154 77156 77158 77160 77162 77164 77166 77168 77170 77172 77174 77176 77178 77180 77182 101632 101634 101636 101638 101640 101642 101644 101646 101648 101650 101652 101654 101656 101658 101660 101662 101664 101666 101668 101670 101672 101674 101676 101678 101680 101682 101684 101686 101688 101690 101692 101694 101696 101698 101700 101702 101704 101706 101708 101710 101712 101714 101716 101718 101720 101722 101724 101726 101728 101730 101732 101734 101736 101738 101740 101742 101744 101746 101748 101750 101752 101754 101756 101758 126208 77184 77186 77188 77190 77192 77194 77196 77198 77200 77202 77204 77206 77208 77210 77212 77214 77216 77218 77220 77222 77224 77226 77228 77230 77232 77234 77236 77238 77240 77242 77244 77246 77248 77250 77252 77254 77256 77258 77260 77262 77264 77266 77268 77270 77272 77274 77276 77278 77280 77282 77284 77286 77288 77290 77292 77294 77296 77298 77300 77302 77304 77306 77308 77310 101760 101762 101764 101766 101768 101770 101772 101774 101776 101778 101780 101782 101784 101786 101788 101790 101792 101794 101796 101798 101800 101802 101804 101806 101808 101810 101812 101814 101816 101818 101820 101822 101824 101826 101828 101830 101832 101834 101836 101838 101840 101842 101844 101846 101848 101850 101852 101854 101856 101858 101860 101862 101864 101866 101868 101870 101872 101874 101876 101878 101880 101882 101884 101886 126336 77312 77314 77316 77318 77320 77322 77324 77326 77328 77330 77332 77334 77336 77338 77340 77342 77344 77346 77348 77350 77352 77354 77356 77358 77360 77362 77364 77366 77368 77370 77372 77374 77376 77378 77380 77382 77384 77386 77388 77390 77392 77394 77396 77398 77400 77402 77404 77406 77408 77410 77412 77414 77416 77418 77420 77422 77424 77426 77428 77430 77432 77434 77436 77438 101888 101890 101892 101894 101896 101898 101900 101902 101904 101906 101908 101910 101912 101914 101916 101918 101920 101922 101924 101926 101928 101930 101932 101934 101936 101938 101940 101942 101944 101946 101948 101950 101952 101954 101956 101958 101960 101962 101964 101966 101968 101970 101972 101974 101976 101978 101980 101982 101984 101986 101988 101990 101992 101994 101996 101998 102000 102002 102004 102006 102008 102010 102012 102014 126464 77440 77442 77444 77446 77448 77450 77452 77454 77456 77458 77460 77462 77464 77466 77468 77470 77472 77474 77476 77478 77480 77482 77484 77486 77488 77490 77492 77494 77496 77498 77500 77502 77504 77506 77508 77510 77512 77514 77516 77518 77520 77522 77524 77526 77528 77530 77532 77534 77536 77538 77540 77542 77544 77546 77548 77550 77552 77554 77556 77558 77560 77562 77564 77566 102016 102018 102020 102022 102024 102026 102028 102030 102032 102034 102036 102038 102040 102042 102044 102046 102048 102050 102052 102054 102056 102058 102060 102062 102064 102066 102068 102070 102072 102074 102076 102078 102080 102082 102084 102086 102088 102090 102092 102094 102096 102098 102100 102102 102104 102106 102108 102110 102112 102114 102116 102118 102120 102122 102124 102126 102128 102130 102132 102134 102136 102138 102140 102142 126592 77568 77570 77572 77574 77576 77578 77580 77582 77584 77586 77588 77590 77592 77594 77596 77598 77600 77602 77604 77606 77608 77610 77612 77614 77616 77618 77620 77622 77624 77626 77628 77630 77632 77634 77636 77638 77640 77642 77644 77646 77648 77650 77652 77654 77656 77658 77660 77662 77664 77666 77668 77670 77672 77674 77676 77678 77680 77682 77684 77686 77688 77690 77692 77694 102144 102146 102148 102150 102152 102154 102156 102158 102160 102162 102164 102166 102168 102170 102172 102174 102176 102178 102180 102182 102184 102186 102188 102190 102192 102194 102196 102198 102200 102202 102204 102206 102208 102210 102212 102214 102216 102218 102220 102222 102224 102226 102228 102230 102232 102234 102236 102238 102240 102242 102244 102246 102248 102250 102252 102254 102256 102258 102260 102262 102264 102266 102268 102270 126720 77696 77698 77700 77702 77704 77706 77708 77710 77712 77714 77716 77718 77720 77722 77724 77726 77728 77730 77732 77734 77736 77738 77740 77742 77744 77746 77748 77750 77752 77754 77756 77758 77760 77762 77764 77766 77768 77770 77772 77774 77776 77778 77780 77782 77784 77786 77788 77790 77792 77794 77796 77798 77800 77802 77804 77806 77808 77810 77812 77814 77816 77818 77820 77822 102272 102274 102276 102278 102280 102282 102284 102286 102288 102290 102292 102294 102296 102298 102300 102302 102304 102306 102308 102310 102312 102314 102316 102318 102320 102322 102324 102326 102328 102330 102332 102334 102336 102338 102340 102342 102344 102346 102348 102350 102352 102354 102356 102358 102360 102362 102364 102366 102368 102370 102372 102374 102376 102378 102380 102382 102384 102386 102388 102390 102392 102394 102396 102398 126848 77824 77826 77828 77830 77832 77834 77836 77838 77840 77842 77844 77846 77848 77850 77852 77854 77856 77858 77860 77862 77864 77866 77868 77870 77872 77874 77876 77878 77880 77882 77884 77886 77888 77890 77892 77894 77896 77898 77900 77902 77904 77906 77908 77910 77912 77914 77916 77918 77920 77922 77924 77926 77928 77930 77932 77934 77936 77938 77940 77942 77944 77946 77948 77950 102400 102402 102404 102406 102408 102410 102412 102414 102416 102418 102420 102422 102424 102426 102428 102430 102432 102434 102436 102438 102440 102442 102444 102446 102448 102450 102452 102454 102456 102458 102460 102462 102464 102466 102468 102470 102472 102474 102476 102478 102480 102482 102484 102486 102488 102490 102492 102494 102496 102498 102500 102502 102504 102506 102508 102510 102512 102514 102516 102518 102520 102522 102524 102526 126976 81920 81922 81924 81926 81928 81930 81932 81934 81936 81938 81940 81942 81944 81946 81948 81950 81952 81954 81956 81958 81960 81962 81964 81966 81968 81970 81972 81974 81976 81978 81980 81982 81984 81986 81988 81990 81992 81994 81996 81998 82000 82002 82004 82006 82008 82010 82012 82014 82016 82018 82020 82022 82024 82026 82028 82030 82032 82034 82036 82038 82040 82042 82044 82046 106496 106498 106500 106502 106504 106506 106508 106510 106512 106514 106516 106518 106520 106522 106524 106526 106528 106530 106532 106534 106536 106538 106540 106542 106544 106546 106548 106550 106552 106554 106556 106558 106560 106562 106564 106566 106568 106570 106572 106574 106576 106578 106580 106582 106584 106586 106588 106590 106592 106594 106596 106598 106600 106602 106604 106606 106608 106610 106612 106614 106616 106618 106620 106622 131072 82048 82050 82052 82054 82056 82058 82060 82062 82064 82066 82068 82070 82072 82074 82076 82078 82080 82082 82084 82086 82088 82090 82092 82094 82096 82098 82100 82102 82104 82106 82108 82110 82112 82114 82116 82118 82120 82122 82124 82126 82128 82130 82132 82134 82136 82138 82140 82142 82144 82146 82148 82150 82152 82154 82156 82158 82160 82162 82164 82166 82168 82170 82172 82174 106624 106626 106628 106630 106632 106634 106636 106638 106640 106642 106644 106646 106648 106650 106652 106654 106656 106658 106660 106662 106664 106666 106668 106670 106672 106674 106676 106678 106680 106682 106684 106686 106688 106690 106692 106694 106696 106698 106700 106702 106704 106706 106708 106710 106712 106714 106716 106718 106720 106722 106724 106726 106728 106730 106732 106734 106736 106738 106740 106742 106744 106746 106748 106750 131200 82176 82178 82180 82182 82184 82186 82188 82190 82192 82194 82196 82198 82200 82202 82204 82206 82208 82210 82212 82214 82216 82218 82220 82222 82224 82226 82228 82230 82232 82234 82236 82238 82240 82242 82244 82246 82248 82250 82252 82254 82256 82258 82260 82262 82264 82266 82268 82270 82272 82274 82276 82278 82280 82282 82284 82286 82288 82290 82292 82294 82296 82298 82300 82302 106752 106754 106756 106758 106760 106762 106764 106766 106768 106770 106772 106774 106776 106778 106780 106782 106784 106786 106788 106790 106792 106794 106796 106798 106800 106802 106804 106806 106808 106810 106812 106814 106816 106818 106820 106822 106824 106826 106828 106830 106832 106834 106836 106838 106840 106842 106844 106846 106848 106850 106852 106854 106856 106858 106860 106862 106864 106866 106868 106870 106872 106874 106876 106878 131328 82304 82306 82308 82310 82312 82314 82316 82318 82320 82322 82324 82326 82328 82330 82332 82334 82336 82338 82340 82342 82344 82346 82348 82350 82352 82354 82356 82358 82360 82362 82364 82366 82368 82370 82372 82374 82376 82378 82380 82382 82384 82386 82388 82390 82392 82394 82396 82398 82400 82402 82404 82406 82408 82410 82412 82414 82416 82418 82420 82422 82424 82426 82428 82430 106880 106882 106884 106886 106888 106890 106892 106894 106896 106898 106900 106902 106904 106906 106908 106910 106912 106914 106916 106918 106920 106922 106924 106926 106928 106930 106932 106934 106936 106938 106940 106942 106944 106946 106948 106950 106952 106954 106956 106958 106960 106962 106964 106966 106968 106970 106972 106974 106976 106978 106980 106982 106984 106986 106988 106990 106992 106994 106996 106998 107000 107002 107004 107006 131456 82432 82434 82436 82438 82440 82442 82444 82446 82448 82450 82452 82454 82456 82458 82460 82462 82464 82466 82468 82470 82472 82474 82476 82478 82480 82482 82484 82486 82488 82490 82492 82494 82496 82498 82500 82502 82504 82506 82508 82510 82512 82514 82516 82518 82520 82522 82524 82526 82528 82530 82532 82534 82536 82538 82540 82542 82544 82546 82548 82550 82552 82554 82556 82558 107008 107010 107012 107014 107016 107018 107020 107022 107024 107026 107028 107030 107032 107034 107036 107038 107040 107042 107044 107046 107048 107050 107052 107054 107056 107058 107060 107062 107064 107066 107068 107070 107072 107074 107076 107078 107080 107082 107084 107086 107088 107090 107092 107094 107096 107098 107100 107102 107104 107106 107108 107110 107112 107114 107116 107118 107120 107122 107124 107126 107128 107130 107132 107134 131584 82560 82562 82564 82566 82568 82570 82572 82574 82576 82578 82580 82582 82584 82586 82588 82590 82592 82594 82596 82598 82600 82602 82604 82606 82608 82610 82612 82614 82616 82618 82620 82622 82624 82626 82628 82630 82632 82634 82636 82638 82640 82642 82644 82646 82648 82650 82652 82654 82656 82658 82660 82662 82664 82666 82668 82670 82672 82674 82676 82678 82680 82682 82684 82686 107136 107138 107140 107142 107144 107146 107148 107150 107152 107154 107156 107158 107160 107162 107164 107166 107168 107170 107172 107174 107176 107178 107180 107182 107184 107186 107188 107190 107192 107194 107196 107198 107200 107202 107204 107206 107208 107210 107212 107214 107216 107218 107220 107222 107224 107226 107228 107230 107232 107234 107236 107238 107240 107242 107244 107246 107248 107250 107252 107254 107256 107258 107260 107262 131712 82688 82690 82692 82694 82696 82698 82700 82702 82704 82706 82708 82710 82712 82714 82716 82718 82720 82722 82724 82726 82728 82730 82732 82734 82736 82738 82740 82742 82744 82746 82748 82750 82752 82754 82756 82758 82760 82762 82764 82766 82768 82770 82772 82774 82776 82778 82780 82782 82784 82786 82788 82790 82792 82794 82796 82798 82800 82802 82804 82806 82808 82810 82812 82814 107264 107266 107268 107270 107272 107274 107276 107278 107280 107282 107284 107286 107288 107290 107292 107294 107296 107298 107300 107302 107304 107306 107308 107310 107312 107314 107316 107318 107320 107322 107324 107326 107328 107330 107332 107334 107336 107338 107340 107342 107344 107346 107348 107350 107352 107354 107356 107358 107360 107362 107364 107366 107368 107370 107372 107374 107376 107378 107380 107382 107384 107386 107388 107390 131840 82816 82818 82820 82822 82824 82826 82828 82830 82832 82834 82836 82838 82840 82842 82844 82846 82848 82850 82852 82854 82856 82858 82860 82862 82864 82866 82868 82870 82872 82874 82876 82878 82880 82882 82884 82886 82888 82890 82892 82894 82896 82898 82900 82902 82904 82906 82908 82910 82912 82914 82916 82918 82920 82922 82924 82926 82928 82930 82932 82934 82936 82938 82940 82942 107392 107394 107396 107398 107400 107402 107404 107406 107408 107410 107412 107414 107416 107418 107420 107422 107424 107426 107428 107430 107432 107434 107436 107438 107440 107442 107444 107446 107448 107450 107452 107454 107456 107458 107460 107462 107464 107466 107468 107470 107472 107474 107476 107478 107480 107482 107484 107486 107488 107490 107492 107494 107496 107498 107500 107502 107504 107506 107508 107510 107512 107514 107516 107518 131968 82944 82946 82948 82950 82952 82954 82956 82958 82960 82962 82964 82966 82968 82970 82972 82974 82976 82978 82980 82982 82984 82986 82988 82990 82992 82994 82996 82998 83000 83002 83004 83006 83008 83010 83012 83014 83016 83018 83020 83022 83024 83026 83028 83030 83032 83034 83036 83038 83040 83042 83044 83046 83048 83050 83052 83054 83056 83058 83060 83062 83064 83066 83068 83070 107520 107522 107524 107526 107528 107530 107532 107534 107536 107538 107540 107542 107544 107546 107548 107550 107552 107554 107556 107558 107560 107562 107564 107566 107568 107570 107572 107574 107576 107578 107580 107582 107584 107586 107588 107590 107592 107594 107596 107598 107600 107602 107604 107606 107608 107610 107612 107614 107616 107618 107620 107622 107624 107626 107628 107630 107632 107634 107636 107638 107640 107642 107644 107646 132096 83072 83074 83076 83078 83080 83082 83084 83086 83088 83090 83092 83094 83096 83098 83100 83102 83104 83106 83108 83110 83112 83114 83116 83118 83120 83122 83124 83126 83128 83130 83132 83134 83136 83138 83140 83142 83144 83146 83148 83150 83152 83154 83156 83158 83160 83162 83164 83166 83168 83170 83172 83174 83176 83178 83180 83182 83184 83186 83188 83190 83192 83194 83196 83198 107648 107650 107652 107654 107656 107658 107660 107662 107664 107666 107668 107670 107672 107674 107676 107678 107680 107682 107684 107686 107688 107690 107692 107694 107696 107698 107700 107702 107704 107706 107708 107710 107712 107714 107716 107718 107720 107722 107724 107726 107728 107730 107732 107734 107736 107738 107740 107742 107744 107746 107748 107750 107752 107754 107756 107758 107760 107762 107764 107766 107768 107770 107772 107774 132224 83200 83202 83204 83206 83208 83210 83212 83214 83216 83218 83220 83222 83224 83226 83228 83230 83232 83234 83236 83238 83240 83242 83244 83246 83248 83250 83252 83254 83256 83258 83260 83262 83264 83266 83268 83270 83272 83274 83276 83278 83280 83282 83284 83286 83288 83290 83292 83294 83296 83298 83300 83302 83304 83306 83308 83310 83312 83314 83316 83318 83320 83322 83324 83326 107776 107778 107780 107782 107784 107786 107788 107790 107792 107794 107796 107798 107800 107802 107804 107806 107808 107810 107812 107814 107816 107818 107820 107822 107824 107826 107828 107830 107832 107834 107836 107838 107840 107842 107844 107846 107848 107850 107852 107854 107856 107858 107860 107862 107864 107866 107868 107870 107872 107874 107876 107878 107880 107882 107884 107886 107888 107890 107892 107894 107896 107898 107900 107902 132352 83328 83330 83332 83334 83336 83338 83340 83342 83344 83346 83348 83350 83352 83354 83356 83358 83360 83362 83364 83366 83368 83370 83372 83374 83376 83378 83380 83382 83384 83386 83388 83390 83392 83394 83396 83398 83400 83402 83404 83406 83408 83410 83412 83414 83416 83418 83420 83422 83424 83426 83428 83430 83432 83434 83436 83438 83440 83442 83444 83446 83448 83450 83452 83454 107904 107906 107908 107910 107912 107914 107916 107918 107920 107922 107924 107926 107928 107930 107932 107934 107936 107938 107940 107942 107944 107946 107948 107950 107952 107954 107956 107958 107960 107962 107964 107966 107968 107970 107972 107974 107976 107978 107980 107982 107984 107986 107988 107990 107992 107994 107996 107998 108000 108002 108004 108006 108008 108010 108012 108014 108016 108018 108020 108022 108024 108026 108028 108030 132480 83456 83458 83460 83462 83464 83466 83468 83470 83472 83474 83476 83478 83480 83482 83484 83486 83488 83490 83492 83494 83496 83498 83500 83502 83504 83506 83508 83510 83512 83514 83516 83518 83520 83522 83524 83526 83528 83530 83532 83534 83536 83538 83540 83542 83544 83546 83548 83550 83552 83554 83556 83558 83560 83562 83564 83566 83568 83570 83572 83574 83576 83578 83580 83582 108032 108034 108036 108038 108040 108042 108044 108046 108048 108050 108052 108054 108056 108058 108060 108062 108064 108066 108068 108070 108072 108074 108076 108078 108080 108082 108084 108086 108088 108090 108092 108094 108096 108098 108100 108102 108104 108106 108108 108110 108112 108114 108116 108118 108120 108122 108124 108126 108128 108130 108132 108134 108136 108138 108140 108142 108144 108146 108148 108150 108152 108154 108156 108158 132608 83584 83586 83588 83590 83592 83594 83596 83598 83600 83602 83604 83606 83608 83610 83612 83614 83616 83618 83620 83622 83624 83626 83628 83630 83632 83634 83636 83638 83640 83642 83644 83646 83648 83650 83652 83654 83656 83658 83660 83662 83664 83666 83668 83670 83672 83674 83676 83678 83680 83682 83684 83686 83688 83690 83692 83694 83696 83698 83700 83702 83704 83706 83708 83710 108160 108162 108164 108166 108168 108170 108172 108174 108176 108178 108180 108182 108184 108186 108188 108190 108192 108194 108196 108198 108200 108202 108204 108206 108208 108210 108212 108214 108216 108218 108220 108222 108224 108226 108228 108230 108232 108234 108236 108238 108240 108242 108244 108246 108248 108250 108252 108254 108256 108258 108260 108262 108264 108266 108268 108270 108272 108274 108276 108278 108280 108282 108284 108286 132736 83712 83714 83716 83718 83720 83722 83724 83726 83728 83730 83732 83734 83736 83738 83740 83742 83744 83746 83748 83750 83752 83754 83756 83758 83760 83762 83764 83766 83768 83770 83772 83774 83776 83778 83780 83782 83784 83786 83788 83790 83792 83794 83796 83798 83800 83802 83804 83806 83808 83810 83812 83814 83816 83818 83820 83822 83824 83826 83828 83830 83832 83834 83836 83838 108288 108290 108292 108294 108296 108298 108300 108302 108304 108306 108308 108310 108312 108314 108316 108318 108320 108322 108324 108326 108328 108330 108332 108334 108336 108338 108340 108342 108344 108346 108348 108350 108352 108354 108356 108358 108360 108362 108364 108366 108368 108370 108372 108374 108376 108378 108380 108382 108384 108386 108388 108390 108392 108394 108396 108398 108400 108402 108404 108406 108408 108410 108412 108414 132864 83840 83842 83844 83846 83848 83850 83852 83854 83856 83858 83860 83862 83864 83866 83868 83870 83872 83874 83876 83878 83880 83882 83884 83886 83888 83890 83892 83894 83896 83898 83900 83902 83904 83906 83908 83910 83912 83914 83916 83918 83920 83922 83924 83926 83928 83930 83932 83934 83936 83938 83940 83942 83944 83946 83948 83950 83952 83954 83956 83958 83960 83962 83964 83966 108416 108418 108420 108422 108424 108426 108428 108430 108432 108434 108436 108438 108440 108442 108444 108446 108448 108450 108452 108454 108456 108458 108460 108462 108464 108466 108468 108470 108472 108474 108476 108478 108480 108482 108484 108486 108488 108490 108492 108494 108496 108498 108500 108502 108504 108506 108508 108510 108512 108514 108516 108518 108520 108522 108524 108526 108528 108530 108532 108534 108536 108538 108540 108542 132992 83968 83970 83972 83974 83976 83978 83980 83982 83984 83986 83988 83990 83992 83994 83996 83998 84000 84002 84004 84006 84008 84010 84012 84014 84016 84018 84020 84022 84024 84026 84028 84030 84032 84034 84036 84038 84040 84042 84044 84046 84048 84050 84052 84054 84056 84058 84060 84062 84064 84066 84068 84070 84072 84074 84076 84078 84080 84082 84084 84086 84088 84090 84092 84094 108544 108546 108548 108550 108552 108554 108556 108558 108560 108562 108564 108566 108568 108570 108572 108574 108576 108578 108580 108582 108584 108586 108588 108590 108592 108594 108596 108598 108600 108602 108604 108606 108608 108610 108612 108614 108616 108618 108620 108622 108624 108626 108628 108630 108632 108634 108636 108638 108640 108642 108644 108646 108648 108650 108652 108654 108656 108658 108660 108662 108664 108666 108668 108670 133120 84096 84098 84100 84102 84104 84106 84108 84110 84112 84114 84116 84118 84120 84122 84124 84126 84128 84130 84132 84134 84136 84138 84140 84142 84144 84146 84148 84150 84152 84154 84156 84158 84160 84162 84164 84166 84168 84170 84172 84174 84176 84178 84180 84182 84184 84186 84188 84190 84192 84194 84196 84198 84200 84202 84204 84206 84208 84210 84212 84214 84216 84218 84220 84222 108672 108674 108676 108678 108680 108682 108684 108686 108688 108690 108692 108694 108696 108698 108700 108702 108704 108706 108708 108710 108712 108714 108716 108718 108720 108722 108724 108726 108728 108730 108732 108734 108736 108738 108740 108742 108744 108746 108748 108750 108752 108754 108756 108758 108760 108762 108764 108766 108768 108770 108772 108774 108776 108778 108780 108782 108784 108786 108788 108790 108792 108794 108796 108798 133248 84224 84226 84228 84230 84232 84234 84236 84238 84240 84242 84244 84246 84248 84250 84252 84254 84256 84258 84260 84262 84264 84266 84268 84270 84272 84274 84276 84278 84280 84282 84284 84286 84288 84290 84292 84294 84296 84298 84300 84302 84304 84306 84308 84310 84312 84314 84316 84318 84320 84322 84324 84326 84328 84330 84332 84334 84336 84338 84340 84342 84344 84346 84348 84350 108800 108802 108804 108806 108808 108810 108812 108814 108816 108818 108820 108822 108824 108826 108828 108830 108832 108834 108836 108838 108840 108842 108844 108846 108848 108850 108852 108854 108856 108858 108860 108862 108864 108866 108868 108870 108872 108874 108876 108878 108880 108882 108884 108886 108888 108890 108892 108894 108896 108898 108900 108902 108904 108906 108908 108910 108912 108914 108916 108918 108920 108922 108924 108926 133376 84352 84354 84356 84358 84360 84362 84364 84366 84368 84370 84372 84374 84376 84378 84380 84382 84384 84386 84388 84390 84392 84394 84396 84398 84400 84402 84404 84406 84408 84410 84412 84414 84416 84418 84420 84422 84424 84426 84428 84430 84432 84434 84436 84438 84440 84442 84444 84446 84448 84450 84452 84454 84456 84458 84460 84462 84464 84466 84468 84470 84472 84474 84476 84478 108928 108930 108932 108934 108936 108938 108940 108942 108944 108946 108948 108950 108952 108954 108956 108958 108960 108962 108964 108966 108968 108970 108972 108974 108976 108978 108980 108982 108984 108986 108988 108990 108992 108994 108996 108998 109000 109002 109004 109006 109008 109010 109012 109014 109016 109018 109020 109022 109024 109026 109028 109030 109032 109034 109036 109038 109040 109042 109044 109046 109048 109050 109052 109054 133504 84480 84482 84484 84486 84488 84490 84492 84494 84496 84498 84500 84502 84504 84506 84508 84510 84512 84514 84516 84518 84520 84522 84524 84526 84528 84530 84532 84534 84536 84538 84540 84542 84544 84546 84548 84550 84552 84554 84556 84558 84560 84562 84564 84566 84568 84570 84572 84574 84576 84578 84580 84582 84584 84586 84588 84590 84592 84594 84596 84598 84600 84602 84604 84606 109056 109058 109060 109062 109064 109066 109068 109070 109072 109074 109076 109078 109080 109082 109084 109086 109088 109090 109092 109094 109096 109098 109100 109102 109104 109106 109108 109110 109112 109114 109116 109118 109120 109122 109124 109126 109128 109130 109132 109134 109136 109138 109140 109142 109144 109146 109148 109150 109152 109154 109156 109158 109160 109162 109164 109166 109168 109170 109172 109174 109176 109178 109180 109182 133632 84608 84610 84612 84614 84616 84618 84620 84622 84624 84626 84628 84630 84632 84634 84636 84638 84640 84642 84644 84646 84648 84650 84652 84654 84656 84658 84660 84662 84664 84666 84668 84670 84672 84674 84676 84678 84680 84682 84684 84686 84688 84690 84692 84694 84696 84698 84700 84702 84704 84706 84708 84710 84712 84714 84716 84718 84720 84722 84724 84726 84728 84730 84732 84734 109184 109186 109188 109190 109192 109194 109196 109198 109200 109202 109204 109206 109208 109210 109212 109214 109216 109218 109220 109222 109224 109226 109228 109230 109232 109234 109236 109238 109240 109242 109244 109246 109248 109250 109252 109254 109256 109258 109260 109262 109264 109266 109268 109270 109272 109274 109276 109278 109280 109282 109284 109286 109288 109290 109292 109294 109296 109298 109300 109302 109304 109306 109308 109310 133760 84736 84738 84740 84742 84744 84746 84748 84750 84752 84754 84756 84758 84760 84762 84764 84766 84768 84770 84772 84774 84776 84778 84780 84782 84784 84786 84788 84790 84792 84794 84796 84798 84800 84802 84804 84806 84808 84810 84812 84814 84816 84818 84820 84822 84824 84826 84828 84830 84832 84834 84836 84838 84840 84842 84844 84846 84848 84850 84852 84854 84856 84858 84860 84862 109312 109314 109316 109318 109320 109322 109324 109326 109328 109330 109332 109334 109336 109338 109340 109342 109344 109346 109348 109350 109352 109354 109356 109358 109360 109362 109364 109366 109368 109370 109372 109374 109376 109378 109380 109382 109384 109386 109388 109390 109392 109394 109396 109398 109400 109402 109404 109406 109408 109410 109412 109414 109416 109418 109420 109422 109424 109426 109428 109430 109432 109434 109436 109438 133888 84864 84866 84868 84870 84872 84874 84876 84878 84880 84882 84884 84886 84888 84890 84892 84894 84896 84898 84900 84902 84904 84906 84908 84910 84912 84914 84916 84918 84920 84922 84924 84926 84928 84930 84932 84934 84936 84938 84940 84942 84944 84946 84948 84950 84952 84954 84956 84958 84960 84962 84964 84966 84968 84970 84972 84974 84976 84978 84980 84982 84984 84986 84988 84990 109440 109442 109444 109446 109448 109450 109452 109454 109456 109458 109460 109462 109464 109466 109468 109470 109472 109474 109476 109478 109480 109482 109484 109486 109488 109490 109492 109494 109496 109498 109500 109502 109504 109506 109508 109510 109512 109514 109516 109518 109520 109522 109524 109526 109528 109530 109532 109534 109536 109538 109540 109542 109544 109546 109548 109550 109552 109554 109556 109558 109560 109562 109564 109566 134016 84992 84994 84996 84998 85000 85002 85004 85006 85008 85010 85012 85014 85016 85018 85020 85022 85024 85026 85028 85030 85032 85034 85036 85038 85040 85042 85044 85046 85048 85050 85052 85054 85056 85058 85060 85062 85064 85066 85068 85070 85072 85074 85076 85078 85080 85082 85084 85086 85088 85090 85092 85094 85096 85098 85100 85102 85104 85106 85108 85110 85112 85114 85116 85118 109568 109570 109572 109574 109576 109578 109580 109582 109584 109586 109588 109590 109592 109594 109596 109598 109600 109602 109604 109606 109608 109610 109612 109614 109616 109618 109620 109622 109624 109626 109628 109630 109632 109634 109636 109638 109640 109642 109644 109646 109648 109650 109652 109654 109656 109658 109660 109662 109664 109666 109668 109670 109672 109674 109676 109678 109680 109682 109684 109686 109688 109690 109692 109694 134144 85120 85122 85124 85126 85128 85130 85132 85134 85136 85138 85140 85142 85144 85146 85148 85150 85152 85154 85156 85158 85160 85162 85164 85166 85168 85170 85172 85174 85176 85178 85180 85182 85184 85186 85188 85190 85192 85194 85196 85198 85200 85202 85204 85206 85208 85210 85212 85214 85216 85218 85220 85222 85224 85226 85228 85230 85232 85234 85236 85238 85240 85242 85244 85246 109696 109698 109700 109702 109704 109706 109708 109710 109712 109714 109716 109718 109720 109722 109724 109726 109728 109730 109732 109734 109736 109738 109740 109742 109744 109746 109748 109750 109752 109754 109756 109758 109760 109762 109764 109766 109768 109770 109772 109774 109776 109778 109780 109782 109784 109786 109788 109790 109792 109794 109796 109798 109800 109802 109804 109806 109808 109810 109812 109814 109816 109818 109820 109822 134272 85248 85250 85252 85254 85256 85258 85260 85262 85264 85266 85268 85270 85272 85274 85276 85278 85280 85282 85284 85286 85288 85290 85292 85294 85296 85298 85300 85302 85304 85306 85308 85310 85312 85314 85316 85318 85320 85322 85324 85326 85328 85330 85332 85334 85336 85338 85340 85342 85344 85346 85348 85350 85352 85354 85356 85358 85360 85362 85364 85366 85368 85370 85372 85374 109824 109826 109828 109830 109832 109834 109836 109838 109840 109842 109844 109846 109848 109850 109852 109854 109856 109858 109860 109862 109864 109866 109868 109870 109872 109874 109876 109878 109880 109882 109884 109886 109888 109890 109892 109894 109896 109898 109900 109902 109904 109906 109908 109910 109912 109914 109916 109918 109920 109922 109924 109926 109928 109930 109932 109934 109936 109938 109940 109942 109944 109946 109948 109950 134400 85376 85378 85380 85382 85384 85386 85388 85390 85392 85394 85396 85398 85400 85402 85404 85406 85408 85410 85412 85414 85416 85418 85420 85422 85424 85426 85428 85430 85432 85434 85436 85438 85440 85442 85444 85446 85448 85450 85452 85454 85456 85458 85460 85462 85464 85466 85468 85470 85472 85474 85476 85478 85480 85482 85484 85486 85488 85490 85492 85494 85496 85498 85500 85502 109952 109954 109956 109958 109960 109962 109964 109966 109968 109970 109972 109974 109976 109978 109980 109982 109984 109986 109988 109990 109992 109994 109996 109998 110000 110002 110004 110006 110008 110010 110012 110014 110016 110018 110020 110022 110024 110026 110028 110030 110032 110034 110036 110038 110040 110042 110044 110046 110048 110050 110052 110054 110056 110058 110060 110062 110064 110066 110068 110070 110072 110074 110076 110078 134528 85504 85506 85508 85510 85512 85514 85516 85518 85520 85522 85524 85526 85528 85530 85532 85534 85536 85538 85540 85542 85544 85546 85548 85550 85552 85554 85556 85558 85560 85562 85564 85566 85568 85570 85572 85574 85576 85578 85580 85582 85584 85586 85588 85590 85592 85594 85596 85598 85600 85602 85604 85606 85608 85610 85612 85614 85616 85618 85620 85622 85624 85626 85628 85630 110080 110082 110084 110086 110088 110090 110092 110094 110096 110098 110100 110102 110104 110106 110108 110110 110112 110114 110116 110118 110120 110122 110124 110126 110128 110130 110132 110134 110136 110138 110140 110142 110144 110146 110148 110150 110152 110154 110156 110158 110160 110162 110164 110166 110168 110170 110172 110174 110176 110178 110180 110182 110184 110186 110188 110190 110192 110194 110196 110198 110200 110202 110204 110206 134656 85632 85634 85636 85638 85640 85642 85644 85646 85648 85650 85652 85654 85656 85658 85660 85662 85664 85666 85668 85670 85672 85674 85676 85678 85680 85682 85684 85686 85688 85690 85692 85694 85696 85698 85700 85702 85704 85706 85708 85710 85712 85714 85716 85718 85720 85722 85724 85726 85728 85730 85732 85734 85736 85738 85740 85742 85744 85746 85748 85750 85752 85754 85756 85758 110208 110210 110212 110214 110216 110218 110220 110222 110224 110226 110228 110230 110232 110234 110236 110238 110240 110242 110244 110246 110248 110250 110252 110254 110256 110258 110260 110262 110264 110266 110268 110270 110272 110274 110276 110278 110280 110282 110284 110286 110288 110290 110292 110294 110296 110298 110300 110302 110304 110306 110308 110310 110312 110314 110316 110318 110320 110322 110324 110326 110328 110330 110332 110334 134784 85760 85762 85764 85766 85768 85770 85772 85774 85776 85778 85780 85782 85784 85786 85788 85790 85792 85794 85796 85798 85800 85802 85804 85806 85808 85810 85812 85814 85816 85818 85820 85822 85824 85826 85828 85830 85832 85834 85836 85838 85840 85842 85844 85846 85848 85850 85852 85854 85856 85858 85860 85862 85864 85866 85868 85870 85872 85874 85876 85878 85880 85882 85884 85886 110336 110338 110340 110342 110344 110346 110348 110350 110352 110354 110356 110358 110360 110362 110364 110366 110368 110370 110372 110374 110376 110378 110380 110382 110384 110386 110388 110390 110392 110394 110396 110398 110400 110402 110404 110406 110408 110410 110412 110414 110416 110418 110420 110422 110424 110426 110428 110430 110432 110434 110436 110438 110440 110442 110444 110446 110448 110450 110452 110454 110456 110458 110460 110462 134912 85888 85890 85892 85894 85896 85898 85900 85902 85904 85906 85908 85910 85912 85914 85916 85918 85920 85922 85924 85926 85928 85930 85932 85934 85936 85938 85940 85942 85944 85946 85948 85950 85952 85954 85956 85958 85960 85962 85964 85966 85968 85970 85972 85974 85976 85978 85980 85982 85984 85986 85988 85990 85992 85994 85996 85998 86000 86002 86004 86006 86008 86010 86012 86014 110464 110466 110468 110470 110472 110474 110476 110478 110480 110482 110484 110486 110488 110490 110492 110494 110496 110498 110500 110502 110504 110506 110508 110510 110512 110514 110516 110518 110520 110522 110524 110526 110528 110530 110532 110534 110536 110538 110540 110542 110544 110546 110548 110550 110552 110554 110556 110558 110560 110562 110564 110566 110568 110570 110572 110574 110576 110578 110580 110582 110584 110586 110588 110590 135040 86016 86018 86020 86022 86024 86026 86028 86030 86032 86034 86036 86038 86040 86042 86044 86046 86048 86050 86052 86054 86056 86058 86060 86062 86064 86066 86068 86070 86072 86074 86076 86078 86080 86082 86084 86086 86088 86090 86092 86094 86096 86098 86100 86102 86104 86106 86108 86110 86112 86114 86116 86118 86120 86122 86124 86126 86128 86130 86132 86134 86136 86138 86140 86142 110592 110594 110596 110598 110600 110602 110604 110606 110608 110610 110612 110614 110616 110618 110620 110622 110624 110626 110628 110630 110632 110634 110636 110638 110640 110642 110644 110646 110648 110650 110652 110654 110656 110658 110660 110662 110664 110666 110668 110670 110672 110674 110676 110678 110680 110682 110684 110686 110688 110690 110692 110694 110696 110698 110700 110702 110704 110706 110708 110710 110712 110714 110716 110718 135168 90112 90114 90116 90118 90120 90122 90124 90126 90128 90130 90132 90134 90136 90138 90140 90142 90144 90146 90148 90150 90152 90154 90156 90158 90160 90162 90164 90166 90168 90170 90172 90174 90176 90178 90180 90182 90184 90186 90188 90190 90192 90194 90196 90198 90200 90202 90204 90206 90208 90210 90212 90214 90216 90218 90220 90222 90224 90226 90228 90230 90232 90234 90236 90238 114688 114690 114692 114694 114696 114698 114700 114702 114704 114706 114708 114710 114712 114714 114716 114718 114720 114722 114724 114726 114728 114730 114732 114734 114736 114738 114740 114742 114744 114746 114748 114750 114752 114754 114756 114758 114760 114762 114764 114766 114768 114770 114772 114774 114776 114778 114780 114782 114784 114786 114788 114790 114792 114794 114796 114798 114800 114802 114804 114806 114808 114810 114812 114814 139264 90240 90242 90244 90246 90248 90250 90252 90254 90256 90258 90260 90262 90264 90266 90268 90270 90272 90274 90276 90278 90280 90282 90284 90286 90288 90290 90292 90294 90296 90298 90300 90302 90304 90306 90308 90310 90312 90314 90316 90318 90320 90322 90324 90326 90328 90330 90332 90334 90336 90338 90340 90342 90344 90346 90348 90350 90352 90354 90356 90358 90360 90362 90364 90366 114816 114818 114820 114822 114824 114826 114828 114830 114832 114834 114836 114838 114840 114842 114844 114846 114848 114850 114852 114854 114856 114858 114860 114862 114864 114866 114868 114870 114872 114874 114876 114878 114880 114882 114884 114886 114888 114890 114892 114894 114896 114898 114900 114902 114904 114906 114908 114910 114912 114914 114916 114918 114920 114922 114924 114926 114928 114930 114932 114934 114936 114938 114940 114942 139392 90368 90370 90372 90374 90376 90378 90380 90382 90384 90386 90388 90390 90392 90394 90396 90398 90400 90402 90404 90406 90408 90410 90412 90414 90416 90418 90420 90422 90424 90426 90428 90430 90432 90434 90436 90438 90440 90442 90444 90446 90448 90450 90452 90454 90456 90458 90460 90462 90464 90466 90468 90470 90472 90474 90476 90478 90480 90482 90484 90486 90488 90490 90492 90494 114944 114946 114948 114950 114952 114954 114956 114958 114960 114962 114964 114966 114968 114970 114972 114974 114976 114978 114980 114982 114984 114986 114988 114990 114992 114994 114996 114998 115000 115002 115004 115006 115008 115010 115012 115014 115016 115018 115020 115022 115024 115026 115028 115030 115032 115034 115036 115038 115040 115042 115044 115046 115048 115050 115052 115054 115056 115058 115060 115062 115064 115066 115068 115070 139520 90496 90498 90500 90502 90504 90506 90508 90510 90512 90514 90516 90518 90520 90522 90524 90526 90528 90530 90532 90534 90536 90538 90540 90542 90544 90546 90548 90550 90552 90554 90556 90558 90560 90562 90564 90566 90568 90570 90572 90574 90576 90578 90580 90582 90584 90586 90588 90590 90592 90594 90596 90598 90600 90602 90604 90606 90608 90610 90612 90614 90616 90618 90620 90622 115072 115074 115076 115078 115080 115082 115084 115086 115088 115090 115092 115094 115096 115098 115100 115102 115104 115106 115108 115110 115112 115114 115116 115118 115120 115122 115124 115126 115128 115130 115132 115134 115136 115138 115140 115142 115144 115146 115148 115150 115152 115154 115156 115158 115160 115162 115164 115166 115168 115170 115172 115174 115176 115178 115180 115182 115184 115186 115188 115190 115192 115194 115196 115198 139648 90624 90626 90628 90630 90632 90634 90636 90638 90640 90642 90644 90646 90648 90650 90652 90654 90656 90658 90660 90662 90664 90666 90668 90670 90672 90674 90676 90678 90680 90682 90684 90686 90688 90690 90692 90694 90696 90698 90700 90702 90704 90706 90708 90710 90712 90714 90716 90718 90720 90722 90724 90726 90728 90730 90732 90734 90736 90738 90740 90742 90744 90746 90748 90750 115200 115202 115204 115206 115208 115210 115212 115214 115216 115218 115220 115222 115224 115226 115228 115230 115232 115234 115236 115238 115240 115242 115244 115246 115248 115250 115252 115254 115256 115258 115260 115262 115264 115266 115268 115270 115272 115274 115276 115278 115280 115282 115284 115286 115288 115290 115292 115294 115296 115298 115300 115302 115304 115306 115308 115310 115312 115314 115316 115318 115320 115322 115324 115326 139776 90752 90754 90756 90758 90760 90762 90764 90766 90768 90770 90772 90774 90776 90778 90780 90782 90784 90786 90788 90790 90792 90794 90796 90798 90800 90802 90804 90806 90808 90810 90812 90814 90816 90818 90820 90822 90824 90826 90828 90830 90832 90834 90836 90838 90840 90842 90844 90846 90848 90850 90852 90854 90856 90858 90860 90862 90864 90866 90868 90870 90872 90874 90876 90878 115328 115330 115332 115334 115336 115338 115340 115342 115344 115346 115348 115350 115352 115354 115356 115358 115360 115362 115364 115366 115368 115370 115372 115374 115376 115378 115380 115382 115384 115386 115388 115390 115392 115394 115396 115398 115400 115402 115404 115406 115408 115410 115412 115414 115416 115418 115420 115422 115424 115426 115428 115430 115432 115434 115436 115438 115440 115442 115444 115446 115448 115450 115452 115454 139904 90880 90882 90884 90886 90888 90890 90892 90894 90896 90898 90900 90902 90904 90906 90908 90910 90912 90914 90916 90918 90920 90922 90924 90926 90928 90930 90932 90934 90936 90938 90940 90942 90944 90946 90948 90950 90952 90954 90956 90958 90960 90962 90964 90966 90968 90970 90972 90974 90976 90978 90980 90982 90984 90986 90988 90990 90992 90994 90996 90998 91000 91002 91004 91006 115456 115458 115460 115462 115464 115466 115468 115470 115472 115474 115476 115478 115480 115482 115484 115486 115488 115490 115492 115494 115496 115498 115500 115502 115504 115506 115508 115510 115512 115514 115516 115518 115520 115522 115524 115526 115528 115530 115532 115534 115536 115538 115540 115542 115544 115546 115548 115550 115552 115554 115556 115558 115560 115562 115564 115566 115568 115570 115572 115574 115576 115578 115580 115582 140032 91008 91010 91012 91014 91016 91018 91020 91022 91024 91026 91028 91030 91032 91034 91036 91038 91040 91042 91044 91046 91048 91050 91052 91054 91056 91058 91060 91062 91064 91066 91068 91070 91072 91074 91076 91078 91080 91082 91084 91086 91088 91090 91092 91094 91096 91098 91100 91102 91104 91106 91108 91110 91112 91114 91116 91118 91120 91122 91124 91126 91128 91130 91132 91134 115584 115586 115588 115590 115592 115594 115596 115598 115600 115602 115604 115606 115608 115610 115612 115614 115616 115618 115620 115622 115624 115626 115628 115630 115632 115634 115636 115638 115640 115642 115644 115646 115648 115650 115652 115654 115656 115658 115660 115662 115664 115666 115668 115670 115672 115674 115676 115678 115680 115682 115684 115686 115688 115690 115692 115694 115696 115698 115700 115702 115704 115706 115708 115710 140160 91136 91138 91140 91142 91144 91146 91148 91150 91152 91154 91156 91158 91160 91162 91164 91166 91168 91170 91172 91174 91176 91178 91180 91182 91184 91186 91188 91190 91192 91194 91196 91198 91200 91202 91204 91206 91208 91210 91212 91214 91216 91218 91220 91222 91224 91226 91228 91230 91232 91234 91236 91238 91240 91242 91244 91246 91248 91250 91252 91254 91256 91258 91260 91262 115712 115714 115716 115718 115720 115722 115724 115726 115728 115730 115732 115734 115736 115738 115740 115742 115744 115746 115748 115750 115752 115754 115756 115758 115760 115762 115764 115766 115768 115770 115772 115774 115776 115778 115780 115782 115784 115786 115788 115790 115792 115794 115796 115798 115800 115802 115804 115806 115808 115810 115812 115814 115816 115818 115820 115822 115824 115826 115828 115830 115832 115834 115836 115838 140288 91264 91266 91268 91270 91272 91274 91276 91278 91280 91282 91284 91286 91288 91290 91292 91294 91296 91298 91300 91302 91304 91306 91308 91310 91312 91314 91316 91318 91320 91322 91324 91326 91328 91330 91332 91334 91336 91338 91340 91342 91344 91346 91348 91350 91352 91354 91356 91358 91360 91362 91364 91366 91368 91370 91372 91374 91376 91378 91380 91382 91384 91386 91388 91390 115840 115842 115844 115846 115848 115850 115852 115854 115856 115858 115860 115862 115864 115866 115868 115870 115872 115874 115876 115878 115880 115882 115884 115886 115888 115890 115892 115894 115896 115898 115900 115902 115904 115906 115908 115910 115912 115914 115916 115918 115920 115922 115924 115926 115928 115930 115932 115934 115936 115938 115940 115942 115944 115946 115948 115950 115952 115954 115956 115958 115960 115962 115964 115966 140416 91392 91394 91396 91398 91400 91402 91404 91406 91408 91410 91412 91414 91416 91418 91420 91422 91424 91426 91428 91430 91432 91434 91436 91438 91440 91442 91444 91446 91448 91450 91452 91454 91456 91458 91460 91462 91464 91466 91468 91470 91472 91474 91476 91478 91480 91482 91484 91486 91488 91490 91492 91494 91496 91498 91500 91502 91504 91506 91508 91510 91512 91514 91516 91518 115968 115970 115972 115974 115976 115978 115980 115982 115984 115986 115988 115990 115992 115994 115996 115998 116000 116002 116004 116006 116008 116010 116012 116014 116016 116018 116020 116022 116024 116026 116028 116030 116032 116034 116036 116038 116040 116042 116044 116046 116048 116050 116052 116054 116056 116058 116060 116062 116064 116066 116068 116070 116072 116074 116076 116078 116080 116082 116084 116086 116088 116090 116092 116094 140544 91520 91522 91524 91526 91528 91530 91532 91534 91536 91538 91540 91542 91544 91546 91548 91550 91552 91554 91556 91558 91560 91562 91564 91566 91568 91570 91572 91574 91576 91578 91580 91582 91584 91586 91588 91590 91592 91594 91596 91598 91600 91602 91604 91606 91608 91610 91612 91614 91616 91618 91620 91622 91624 91626 91628 91630 91632 91634 91636 91638 91640 91642 91644 91646 116096 116098 116100 116102 116104 116106 116108 116110 116112 116114 116116 116118 116120 116122 116124 116126 116128 116130 116132 116134 116136 116138 116140 116142 116144 116146 116148 116150 116152 116154 116156 116158 116160 116162 116164 116166 116168 116170 116172 116174 116176 116178 116180 116182 116184 116186 116188 116190 116192 116194 116196 116198 116200 116202 116204 116206 116208 116210 116212 116214 116216 116218 116220 116222 140672 91648 91650 91652 91654 91656 91658 91660 91662 91664 91666 91668 91670 91672 91674 91676 91678 91680 91682 91684 91686 91688 91690 91692 91694 91696 91698 91700 91702 91704 91706 91708 91710 91712 91714 91716 91718 91720 91722 91724 91726 91728 91730 91732 91734 91736 91738 91740 91742 91744 91746 91748 91750 91752 91754 91756 91758 91760 91762 91764 91766 91768 91770 91772 91774 116224 116226 116228 116230 116232 116234 116236 116238 116240 116242 116244 116246 116248 116250 116252 116254 116256 116258 116260 116262 116264 116266 116268 116270 116272 116274 116276 116278 116280 116282 116284 116286 116288 116290 116292 116294 116296 116298 116300 116302 116304 116306 116308 116310 116312 116314 116316 116318 116320 116322 116324 116326 116328 116330 116332 116334 116336 116338 116340 116342 116344 116346 116348 116350 140800 91776 91778 91780 91782 91784 91786 91788 91790 91792 91794 91796 91798 91800 91802 91804 91806 91808 91810 91812 91814 91816 91818 91820 91822 91824 91826 91828 91830 91832 91834 91836 91838 91840 91842 91844 91846 91848 91850 91852 91854 91856 91858 91860 91862 91864 91866 91868 91870 91872 91874 91876 91878 91880 91882 91884 91886 91888 91890 91892 91894 91896 91898 91900 91902 116352 116354 116356 116358 116360 116362 116364 116366 116368 116370 116372 116374 116376 116378 116380 116382 116384 116386 116388 116390 116392 116394 116396 116398 116400 116402 116404 116406 116408 116410 116412 116414 116416 116418 116420 116422 116424 116426 116428 116430 116432 116434 116436 116438 116440 116442 116444 116446 116448 116450 116452 116454 116456 116458 116460 116462 116464 116466 116468 116470 116472 116474 116476 116478 140928 91904 91906 91908 91910 91912 91914 91916 91918 91920 91922 91924 91926 91928 91930 91932 91934 91936 91938 91940 91942 91944 91946 91948 91950 91952 91954 91956 91958 91960 91962 91964 91966 91968 91970 91972 91974 91976 91978 91980 91982 91984 91986 91988 91990 91992 91994 91996 91998 92000 92002 92004 92006 92008 92010 92012 92014 92016 92018 92020 92022 92024 92026 92028 92030 116480 116482 116484 116486 116488 116490 116492 116494 116496 116498 116500 116502 116504 116506 116508 116510 116512 116514 116516 116518 116520 116522 116524 116526 116528 116530 116532 116534 116536 116538 116540 116542 116544 116546 116548 116550 116552 116554 116556 116558 116560 116562 116564 116566 116568 116570 116572 116574 116576 116578 116580 116582 116584 116586 116588 116590 116592 116594 116596 116598 116600 116602 116604 116606 141056 92032 92034 92036 92038 92040 92042 92044 92046 92048 92050 92052 92054 92056 92058 92060 92062 92064 92066 92068 92070 92072 92074 92076 92078 92080 92082 92084 92086 92088 92090 92092 92094 92096 92098 92100 92102 92104 92106 92108 92110 92112 92114 92116 92118 92120 92122 92124 92126 92128 92130 92132 92134 92136 92138 92140 92142 92144 92146 92148 92150 92152 92154 92156 92158 116608 116610 116612 116614 116616 116618 116620 116622 116624 116626 116628 116630 116632 116634 116636 116638 116640 116642 116644 116646 116648 116650 116652 116654 116656 116658 116660 116662 116664 116666 116668 116670 116672 116674 116676 116678 116680 116682 116684 116686 116688 116690 116692 116694 116696 116698 116700 116702 116704 116706 116708 116710 116712 116714 116716 116718 116720 116722 116724 116726 116728 116730 116732 116734 141184 92160 92162 92164 92166 92168 92170 92172 92174 92176 92178 92180 92182 92184 92186 92188 92190 92192 92194 92196 92198 92200 92202 92204 92206 92208 92210 92212 92214 92216 92218 92220 92222 92224 92226 92228 92230 92232 92234 92236 92238 92240 92242 92244 92246 92248 92250 92252 92254 92256 92258 92260 92262 92264 92266 92268 92270 92272 92274 92276 92278 92280 92282 92284 92286 116736 116738 116740 116742 116744 116746 116748 116750 116752 116754 116756 116758 116760 116762 116764 116766 116768 116770 116772 116774 116776 116778 116780 116782 116784 116786 116788 116790 116792 116794 116796 116798 116800 116802 116804 116806 116808 116810 116812 116814 116816 116818 116820 116822 116824 116826 116828 116830 116832 116834 116836 116838 116840 116842 116844 116846 116848 116850 116852 116854 116856 116858 116860 116862 141312 92288 92290 92292 92294 92296 92298 92300 92302 92304 92306 92308 92310 92312 92314 92316 92318 92320 92322 92324 92326 92328 92330 92332 92334 92336 92338 92340 92342 92344 92346 92348 92350 92352 92354 92356 92358 92360 92362 92364 92366 92368 92370 92372 92374 92376 92378 92380 92382 92384 92386 92388 92390 92392 92394 92396 92398 92400 92402 92404 92406 92408 92410 92412 92414 116864 116866 116868 116870 116872 116874 116876 116878 116880 116882 116884 116886 116888 116890 116892 116894 116896 116898 116900 116902 116904 116906 116908 116910 116912 116914 116916 116918 116920 116922 116924 116926 116928 116930 116932 116934 116936 116938 116940 116942 116944 116946 116948 116950 116952 116954 116956 116958 116960 116962 116964 116966 116968 116970 116972 116974 116976 116978 116980 116982 116984 116986 116988 116990 141440 92416 92418 92420 92422 92424 92426 92428 92430 92432 92434 92436 92438 92440 92442 92444 92446 92448 92450 92452 92454 92456 92458 92460 92462 92464 92466 92468 92470 92472 92474 92476 92478 92480 92482 92484 92486 92488 92490 92492 92494 92496 92498 92500 92502 92504 92506 92508 92510 92512 92514 92516 92518 92520 92522 92524 92526 92528 92530 92532 92534 92536 92538 92540 92542 116992 116994 116996 116998 117000 117002 117004 117006 117008 117010 117012 117014 117016 117018 117020 117022 117024 117026 117028 117030 117032 117034 117036 117038 117040 117042 117044 117046 117048 117050 117052 117054 117056 117058 117060 117062 117064 117066 117068 117070 117072 117074 117076 117078 117080 117082 117084 117086 117088 117090 117092 117094 117096 117098 117100 117102 117104 117106 117108 117110 117112 117114 117116 117118 141568 92544 92546 92548 92550 92552 92554 92556 92558 92560 92562 92564 92566 92568 92570 92572 92574 92576 92578 92580 92582 92584 92586 92588 92590 92592 92594 92596 92598 92600 92602 92604 92606 92608 92610 92612 92614 92616 92618 92620 92622 92624 92626 92628 92630 92632 92634 92636 92638 92640 92642 92644 92646 92648 92650 92652 92654 92656 92658 92660 92662 92664 92666 92668 92670 117120 117122 117124 117126 117128 117130 117132 117134 117136 117138 117140 117142 117144 117146 117148 117150 117152 117154 117156 117158 117160 117162 117164 117166 117168 117170 117172 117174 117176 117178 117180 117182 117184 117186 117188 117190 117192 117194 117196 117198 117200 117202 117204 117206 117208 117210 117212 117214 117216 117218 117220 117222 117224 117226 117228 117230 117232 117234 117236 117238 117240 117242 117244 117246 141696 92672 92674 92676 92678 92680 92682 92684 92686 92688 92690 92692 92694 92696 92698 92700 92702 92704 92706 92708 92710 92712 92714 92716 92718 92720 92722 92724 92726 92728 92730 92732 92734 92736 92738 92740 92742 92744 92746 92748 92750 92752 92754 92756 92758 92760 92762 92764 92766 92768 92770 92772 92774 92776 92778 92780 92782 92784 92786 92788 92790 92792 92794 92796 92798 117248 117250 117252 117254 117256 117258 117260 117262 117264 117266 117268 117270 117272 117274 117276 117278 117280 117282 117284 117286 117288 117290 117292 117294 117296 117298 117300 117302 117304 117306 117308 117310 117312 117314 117316 117318 117320 117322 117324 117326 117328 117330 117332 117334 117336 117338 117340 117342 117344 117346 117348 117350 117352 117354 117356 117358 117360 117362 117364 117366 117368 117370 117372 117374 141824 92800 92802 92804 92806 92808 92810 92812 92814 92816 92818 92820 92822 92824 92826 92828 92830 92832 92834 92836 92838 92840 92842 92844 92846 92848 92850 92852 92854 92856 92858 92860 92862 92864 92866 92868 92870 92872 92874 92876 92878 92880 92882 92884 92886 92888 92890 92892 92894 92896 92898 92900 92902 92904 92906 92908 92910 92912 92914 92916 92918 92920 92922 92924 92926 117376 117378 117380 117382 117384 117386 117388 117390 117392 117394 117396 117398 117400 117402 117404 117406 117408 117410 117412 117414 117416 117418 117420 117422 117424 117426 117428 117430 117432 117434 117436 117438 117440 117442 117444 117446 117448 117450 117452 117454 117456 117458 117460 117462 117464 117466 117468 117470 117472 117474 117476 117478 117480 117482 117484 117486 117488 117490 117492 117494 117496 117498 117500 117502 141952 92928 92930 92932 92934 92936 92938 92940 92942 92944 92946 92948 92950 92952 92954 92956 92958 92960 92962 92964 92966 92968 92970 92972 92974 92976 92978 92980 92982 92984 92986 92988 92990 92992 92994 92996 92998 93000 93002 93004 93006 93008 93010 93012 93014 93016 93018 93020 93022 93024 93026 93028 93030 93032 93034 93036 93038 93040 93042 93044 93046 93048 93050 93052 93054 117504 117506 117508 117510 117512 117514 117516 117518 117520 117522 117524 117526 117528 117530 117532 117534 117536 117538 117540 117542 117544 117546 117548 117550 117552 117554 117556 117558 117560 117562 117564 117566 117568 117570 117572 117574 117576 117578 117580 117582 117584 117586 117588 117590 117592 117594 117596 117598 117600 117602 117604 117606 117608 117610 117612 117614 117616 117618 117620 117622 117624 117626 117628 117630 142080 93056 93058 93060 93062 93064 93066 93068 93070 93072 93074 93076 93078 93080 93082 93084 93086 93088 93090 93092 93094 93096 93098 93100 93102 93104 93106 93108 93110 93112 93114 93116 93118 93120 93122 93124 93126 93128 93130 93132 93134 93136 93138 93140 93142 93144 93146 93148 93150 93152 93154 93156 93158 93160 93162 93164 93166 93168 93170 93172 93174 93176 93178 93180 93182 117632 117634 117636 117638 117640 117642 117644 117646 117648 117650 117652 117654 117656 117658 117660 117662 117664 117666 117668 117670 117672 117674 117676 117678 117680 117682 117684 117686 117688 117690 117692 117694 117696 117698 117700 117702 117704 117706 117708 117710 117712 117714 117716 117718 117720 117722 117724 117726 117728 117730 117732 117734 117736 117738 117740 117742 117744 117746 117748 117750 117752 117754 117756 117758 142208 93184 93186 93188 93190 93192 93194 93196 93198 93200 93202 93204 93206 93208 93210 93212 93214 93216 93218 93220 93222 93224 93226 93228 93230 93232 93234 93236 93238 93240 93242 93244 93246 93248 93250 93252 93254 93256 93258 93260 93262 93264 93266 93268 93270 93272 93274 93276 93278 93280 93282 93284 93286 93288 93290 93292 93294 93296 93298 93300 93302 93304 93306 93308 93310 117760 117762 117764 117766 117768 117770 117772 117774 117776 117778 117780 117782 117784 117786 117788 117790 117792 117794 117796 117798 117800 117802 117804 117806 117808 117810 117812 117814 117816 117818 117820 117822 117824 117826 117828 117830 117832 117834 117836 117838 117840 117842 117844 117846 117848 117850 117852 117854 117856 117858 117860 117862 117864 117866 117868 117870 117872 117874 117876 117878 117880 117882 117884 117886 142336 93312 93314 93316 93318 93320 93322 93324 93326 93328 93330 93332 93334 93336 93338 93340 93342 93344 93346 93348 93350 93352 93354 93356 93358 93360 93362 93364 93366 93368 93370 93372 93374 93376 93378 93380 93382 93384 93386 93388 93390 93392 93394 93396 93398 93400 93402 93404 93406 93408 93410 93412 93414 93416 93418 93420 93422 93424 93426 93428 93430 93432 93434 93436 93438 117888 117890 117892 117894 117896 117898 117900 117902 117904 117906 117908 117910 117912 117914 117916 117918 117920 117922 117924 117926 117928 117930 117932 117934 117936 117938 117940 117942 117944 117946 117948 117950 117952 117954 117956 117958 117960 117962 117964 117966 117968 117970 117972 117974 117976 117978 117980 117982 117984 117986 117988 117990 117992 117994 117996 117998 118000 118002 118004 118006 118008 118010 118012 118014 142464 93440 93442 93444 93446 93448 93450 93452 93454 93456 93458 93460 93462 93464 93466 93468 93470 93472 93474 93476 93478 93480 93482 93484 93486 93488 93490 93492 93494 93496 93498 93500 93502 93504 93506 93508 93510 93512 93514 93516 93518 93520 93522 93524 93526 93528 93530 93532 93534 93536 93538 93540 93542 93544 93546 93548 93550 93552 93554 93556 93558 93560 93562 93564 93566 118016 118018 118020 118022 118024 118026 118028 118030 118032 118034 118036 118038 118040 118042 118044 118046 118048 118050 118052 118054 118056 118058 118060 118062 118064 118066 118068 118070 118072 118074 118076 118078 118080 118082 118084 118086 118088 118090 118092 118094 118096 118098 118100 118102 118104 118106 118108 118110 118112 118114 118116 118118 118120 118122 118124 118126 118128 118130 118132 118134 118136 118138 118140 118142 142592 93568 93570 93572 93574 93576 93578 93580 93582 93584 93586 93588 93590 93592 93594 93596 93598 93600 93602 93604 93606 93608 93610 93612 93614 93616 93618 93620 93622 93624 93626 93628 93630 93632 93634 93636 93638 93640 93642 93644 93646 93648 93650 93652 93654 93656 93658 93660 93662 93664 93666 93668 93670 93672 93674 93676 93678 93680 93682 93684 93686 93688 93690 93692 93694 118144 118146 118148 118150 118152 118154 118156 118158 118160 118162 118164 118166 118168 118170 118172 118174 118176 118178 118180 118182 118184 118186 118188 118190 118192 118194 118196 118198 118200 118202 118204 118206 118208 118210 118212 118214 118216 118218 118220 118222 118224 118226 118228 118230 118232 118234 118236 118238 118240 118242 118244 118246 118248 118250 118252 118254 118256 118258 118260 118262 118264 118266 118268 118270 142720 93696 93698 93700 93702 93704 93706 93708 93710 93712 93714 93716 93718 93720 93722 93724 93726 93728 93730 93732 93734 93736 93738 93740 93742 93744 93746 93748 93750 93752 93754 93756 93758 93760 93762 93764 93766 93768 93770 93772 93774 93776 93778 93780 93782 93784 93786 93788 93790 93792 93794 93796 93798 93800 93802 93804 93806 93808 93810 93812 93814 93816 93818 93820 93822 118272 118274 118276 118278 118280 118282 118284 118286 118288 118290 118292 118294 118296 118298 118300 118302 118304 118306 118308 118310 118312 118314 118316 118318 118320 118322 118324 118326 118328 118330 118332 118334 118336 118338 118340 118342 118344 118346 118348 118350 118352 118354 118356 118358 118360 118362 118364 118366 118368 118370 118372 118374 118376 118378 118380 118382 118384 118386 118388 118390 118392 118394 118396 118398 142848 93824 93826 93828 93830 93832 93834 93836 93838 93840 93842 93844 93846 93848 93850 93852 93854 93856 93858 93860 93862 93864 93866 93868 93870 93872 93874 93876 93878 93880 93882 93884 93886 93888 93890 93892 93894 93896 93898 93900 93902 93904 93906 93908 93910 93912 93914 93916 93918 93920 93922 93924 93926 93928 93930 93932 93934 93936 93938 93940 93942 93944 93946 93948 93950 118400 118402 118404 118406 118408 118410 118412 118414 118416 118418 118420 118422 118424 118426 118428 118430 118432 118434 118436 118438 118440 118442 118444 118446 118448 118450 118452 118454 118456 118458 118460 118462 118464 118466 118468 118470 118472 118474 118476 118478 118480 118482 118484 118486 118488 118490 118492 118494 118496 118498 118500 118502 118504 118506 118508 118510 118512 118514 118516 118518 118520 118522 118524 118526 142976 93952 93954 93956 93958 93960 93962 93964 93966 93968 93970 93972 93974 93976 93978 93980 93982 93984 93986 93988 93990 93992 93994 93996 93998 94000 94002 94004 94006 94008 94010 94012 94014 94016 94018 94020 94022 94024 94026 94028 94030 94032 94034 94036 94038 94040 94042 94044 94046 94048 94050 94052 94054 94056 94058 94060 94062 94064 94066 94068 94070 94072 94074 94076 94078 118528 118530 118532 118534 118536 118538 118540 118542 118544 118546 118548 118550 118552 118554 118556 118558 118560 118562 118564 118566 118568 118570 118572 118574 118576 118578 118580 118582 118584 118586 118588 118590 118592 118594 118596 118598 118600 118602 118604 118606 118608 118610 118612 118614 118616 118618 118620 118622 118624 118626 118628 118630 118632 118634 118636 118638 118640 118642 118644 118646 118648 118650 118652 118654 143104 94080 94082 94084 94086 94088 94090 94092 94094 94096 94098 94100 94102 94104 94106 94108 94110 94112 94114 94116 94118 94120 94122 94124 94126 94128 94130 94132 94134 94136 94138 94140 94142 94144 94146 94148 94150 94152 94154 94156 94158 94160 94162 94164 94166 94168 94170 94172 94174 94176 94178 94180 94182 94184 94186 94188 94190 94192 94194 94196 94198 94200 94202 94204 94206 118656 118658 118660 118662 118664 118666 118668 118670 118672 118674 118676 118678 118680 118682 118684 118686 118688 118690 118692 118694 118696 118698 118700 118702 118704 118706 118708 118710 118712 118714 118716 118718 118720 118722 118724 118726 118728 118730 118732 118734 118736 118738 118740 118742 118744 118746 118748 118750 118752 118754 118756 118758 118760 118762 118764 118766 118768 118770 118772 118774 118776 118778 118780 118782 143232 94208 94210 94212 94214 94216 94218 94220 94222 94224 94226 94228 94230 94232 94234 94236 94238 94240 94242 94244 94246 94248 94250 94252 94254 94256 94258 94260 94262 94264 94266 94268 94270 94272 94274 94276 94278 94280 94282 94284 94286 94288 94290 94292 94294 94296 94298 94300 94302 94304 94306 94308 94310 94312 94314 94316 94318 94320 94322 94324 94326 94328 94330 94332 94334 118784 118786 118788 118790 118792 118794 118796 118798 118800 118802 118804 118806 118808 118810 118812 118814 118816 118818 118820 118822 118824 118826 118828 118830 118832 118834 118836 118838 118840 118842 118844 118846 118848 118850 118852 118854 118856 118858 118860 118862 118864 118866 118868 118870 118872 118874 118876 118878 118880 118882 118884 118886 118888 118890 118892 118894 118896 118898 118900 118902 118904 118906 118908 118910 143360 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/resources/testresult_parser.py�����������������������������������������������������0000664�0000000�0000000�00000005751�14364043643�0021661�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import glob import os results_path = "bin/testDriver*.txt" num_passes = 0 num_ignores = 0 num_fails = 0 # accumulative pass/ignore/fail messages pass_txt = "" ignore_txt = "" fail_txt = "" # other things we care about (crashes, etc.) notes_txt = "" # escaped newline for make NL = "\\n" for filename in glob.glob(results_path): if os.stat(filename).st_size == 0: notes_txt = notes_txt + filename + " is a 0 byte file. Likely crashed." + NL else: for line in open(filename, "r"): line = line.strip() if ":PASS" in line or ":IGNORE" in line or ":FAIL" in line: test_file, line_num, test_name, status = line.split(":", 3) test_file = test_file.strip() line_num = line_num.strip() test_name = test_name.strip() status = status.strip() if "PASS" in status: num_passes = num_passes + 1 pass_txt = pass_txt + test_file + ":" + test_name + NL if "IGNORE" in status: num_ignores = num_ignores + 1 ignore_txt = ( ignore_txt + test_file + ":" + test_name + ":" + status + NL ) if "FAIL" in status: num_fails = num_fails + 1 fail_txt = fail_txt + test_file + ":" + test_name + ":" + status + NL # Unity prints a "final status" text at the end. If the last line isn't either # of these then likely the testDriver crashed if line != "FAIL" and line != "OK": notes_txt = notes_txt + filename + " did not finish. Likely crashed." + NL # print the whole report as one big string so that make won't random insert a space # in between every print() print( f"-----------------------{NL}PASSES{NL}-----------------------{NL}" + pass_txt + f"{NL}-----------------------{NL}IGNORES{NL}-----------------------{NL}" + ignore_txt + f"{NL}-----------------------{NL}FAILURES{NL}-----------------------{NL}" + fail_txt + f"{NL}------------------------------------------------------------{NL}" + f"total = {num_passes + num_ignores + num_fails}, num_passes = {num_passes}," + f" num_ignores = {num_ignores}, num_fails = {num_fails}{NL}" + f"{NL}------------------------------------------------------------{NL}" + notes_txt ) �����������������������zDNN-1.0.1/tests/testDriver_convert.c���������������������������������������������������������������0000664�0000000�0000000�00000035753�14364043643�0017547�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This test driver tests the data type conversion code upon which * the Stickify/Unstickify paths are dependent for conversion AND * proper value placement. * * Each test creates a set of random float values (FP32, FP16 or BFLOAT) * and calls a common routine to build its own version of the converted * values, invoke the library's convert_data_format, then compare the two * areas for expected values and placement. It then does the opposite: * invokes teh library's convert_data_format to convert back to the * original format, and compares the input area to the converted/unconverted * area for proper placement. * * Note that the 'no stride' Stickify/unstickify processing will handle sets of *values numbering larger than 64, so values up to 64 are tested here. * * Also note that the stride versions will likely have different validation * because it *doesn't* have the aforementioned '64 entry' limitation. */ #include "convert.h" #include "testsupport.h" #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> /* * tests: * test FP32->DLFloat, using 1,4,7,8,9,15,63,64 (no stride) * test FP16->DLFloat, using 1,7,8,9,63,64 (no stride) * test BFLOAT->DLFloat, using 1,7,8,9,63,64 (no stride) * * test DLFloat->FP16, using 1,7,8,9,63,64 (no stride) * test DLFloat->FP32, using 1,4,7,8,9,15,63,64 (no stride) * test DLFloat->BFloat, using 1,7,8,9,63,64 (no stride) */ /* define some packed structs for holding data */ // midfloat_str used by FP16 testing, easily grabs // middle two bytes of a FP32 and treats it as a // 2 byte float. typedef #ifdef __MVS__ _Packed #endif struct midfloat_str { uint8_t filler1; float_bit16 shortfloat; uint8_t filler2; } #ifndef __MVS__ __attribute__((packed)) #endif midfloat_str; // expected_data_str structure with a union to // allow us to convert individual values then compare as // one data area typedef #ifdef __MVS__ _Packed #endif struct expected_data_str { union maps { float_bit16 shortfloat[64]; float expfloat[64]; // cppcheck-suppress unusedStructMember char exp_data_reserved[1024]; } maps; } #ifndef __MVS__ __attribute__((packed)) #endif expected_data_str; /* vec_char8 selection_vector = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29};*/ /* convert_and_compare Accepts an array of up to 64 values, converts the values to DL16 itself, calls convert_data_format to do its thing, and compares the two areas. Then converts back and compares that to the original. Return values are multiplied by constants to separate different types of errors. */ int convert_and_compare(zdnn_data_types in_type, int numvalues, void *fixeddata) { // Define areas for stickify conversion to return results char converted_DLF_data[1024]; char converted_orig_data[1024]; memset((void *)(converted_DLF_data), 0, 1024); memset((void *)(converted_orig_data), 0, 1024); // Define an expected data area for comparing our version of converted // values (and placement) to The Library's. expected_data_str expected_DLF_data; memset((void *)(&expected_DLF_data), 0, 1024); // Define a lossy data area for comparing the original data (with expected // precision loss) and The Library's converted-back-to-original data. expected_data_str expected_orig_data; memset((void *)(&expected_orig_data), 0, 1024); float_bit16 *fixed_float_bit16 = (float_bit16 *)fixeddata; float *fixedfloat = (float *)fixeddata; // Build the "expected" areas that we will compare to conversion results for (int i = 0; i < numvalues; i = i + 1) { if (in_type == FP32) { expected_DLF_data.maps.shortfloat[i] = cnvt_1_fp32_to_dlf16(fixedfloat[i]); /* Convert a value, store in expected dlfloat entry */ LOG_DEBUG("++ c_1_fp32_to_dlf for expected DLF %d of %d", i, numvalues); LOG_DEBUG("First : %x, Second: %x", fixedfloat[i], expected_DLF_data.maps.shortfloat[i]); expected_orig_data.maps.expfloat[i] = cnvt_1_dlf16_to_fp32( expected_DLF_data.maps.shortfloat[i]); /* Convert a value back to original format, store in expected original format entry */ LOG_DEBUG("++ c_1_dlf16_to_FP32 for expected Orig %d of %d", i, numvalues); LOG_DEBUG("First : %x, Second: %x", fixedfloat[i], expected_orig_data.maps.shortfloat[i]); } if (in_type == FP16) { expected_DLF_data.maps.shortfloat[i] = cnvt_1_fp16_to_dlf16(fixed_float_bit16[i]); /* Convert a value, store in expected dlfloat entry */ expected_orig_data.maps.shortfloat[i] = cnvt_1_dlf16_to_fp16( expected_DLF_data.maps.shortfloat[i]); /* Convert a value back to original format, store in expected original format entry */ } if (in_type == BFLOAT) { expected_DLF_data.maps.shortfloat[i] = cnvt_1_bfloat_to_dlf16(fixed_float_bit16[i]); /* Convert a value, store in expected dlfloat entry */ expected_orig_data.maps.shortfloat[i] = cnvt_1_dlf16_to_bfloat(expected_DLF_data.maps.shortfloat[i]); /* Convert a value back to original format, store in expected original format entry */ } } // call convert_data to convert/stickify the original data LOG_DEBUG("Calling convert_data_format", NO_ARG); int converted_cnt = convert_data_format( fixeddata, in_type, converted_DLF_data, ZDNN_DLFLOAT16, numvalues); if (converted_cnt != numvalues) { LOG_DEBUG("convert_data (to DLF) did not return proper result (%d != %d)", converted_cnt, numvalues); TEST_FAIL_MESSAGE("convert_data (to DLF) count did not match actual"); } // compare expected to convert_data_format output LOG_DEBUG("comparing expected to convert_data output", NO_ARG); LOG_DEBUG("expected data - first word / last word %d / %d", *(int *)((char *)&expected_DLF_data), *(int *)((char *)&expected_DLF_data) + (numvalues * get_data_type_size(ZDNN_DLFLOAT16)) - 4); LOG_DEBUG("expected data address %" PRIXPTR "", (uint64_t)((char *)&expected_DLF_data)); LOG_DEBUG("converted data - first word / last word %d / %d", *(int *)((char *)converted_DLF_data), *(int *)((char *)converted_DLF_data) + (numvalues * get_data_type_size(ZDNN_DLFLOAT16)) - 4); LOG_DEBUG("converted data address %" PRIXPTR "", (uint64_t)((char *)converted_DLF_data)); TEST_ASSERT_MESSAGE(sizeof(expected_DLF_data) == sizeof(converted_DLF_data), "expected data sizes different (test u/t error)"); int compare_data_size = sizeof(expected_DLF_data); /* validate converted area has something in it */ char zeroes[256]; memset(zeroes, 0, sizeof(zeroes)); TEST_ASSERT_MESSAGE( memcmp(converted_DLF_data, zeroes, (numvalues * sizeof(short))) != 0, "converted-to-dlf area left as zeros"); /* Compare expected DLFLOAT to converted DLFLOAT, and validate */ int memcmp_rc = memcmp(&expected_DLF_data, converted_DLF_data, (size_t)compare_data_size); if (memcmp_rc != 0) { BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("memcmp (post convert to DLF) did not return proper result (%d)", memcmp_rc); printf("expected DLFloat data\n"); print_hex((numvalues * sizeof(float)), &expected_DLF_data); printf("Converted DLFloat data\n"); print_hex((numvalues * sizeof(float)), converted_DLF_data); } TEST_FAIL_MESSAGE( "memcmp (post convert to DLF, no stride) did not match expected"); } // call convert_data in stride to convert/stickify the original data LOG_DEBUG("call convert_data_in_stride", NO_ARG); converted_cnt = convert_data_format_in_stride( fixeddata, in_type, converted_DLF_data, ZDNN_DLFLOAT16, numvalues, 1); if (converted_cnt != numvalues) { LOG_DEBUG("Converted (in_stride) count doesn't match actual, %d / %d", converted_cnt, numvalues); TEST_FAIL_MESSAGE( "Convert_data (to DLF) in stride did not return proper result"); } /* Compare expected DLFLOAT to converted DLFLOAT, and validate */ memcmp_rc = memcmp(&expected_DLF_data, converted_DLF_data, (size_t)compare_data_size); if (memcmp_rc != 0) { BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("Expected data doesn't match converted, %d", memcmp_rc); printf("expected DLFloat data\n"); print_hex((numvalues * sizeof(float)), &expected_DLF_data); printf("Converted DLFloat data\n"); print_hex((numvalues * sizeof(float)), converted_DLF_data); } TEST_FAIL_MESSAGE("Converted DLF data (instride) did not match"); } // Now convert back the other way, and compare to original LOG_DEBUG( "comparing data converted back to Orig format by convert_data output", NO_ARG); int orig_data_size = numvalues * get_data_type_size(in_type); LOG_DEBUG("call convert_data", NO_ARG); int converted_cnt2 = convert_data_format(converted_DLF_data, ZDNN_DLFLOAT16, converted_orig_data, in_type, numvalues); if (converted_cnt2 != numvalues) { LOG_DEBUG("converted count (to_orig) did not match actual (%d != %d)", converted_cnt2, numvalues); TEST_FAIL_MESSAGE( "convert_data (to orig, no stride) count did not match actual"); } TEST_ASSERT_MESSAGE( memcmp(converted_orig_data, zeroes, (numvalues * sizeof(short))) != 0, "converted-to-original area left as zeros"); int memcmp_rc2 = memcmp(&expected_orig_data, converted_orig_data, (size_t)orig_data_size); if (memcmp_rc2 != 0) { BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("memcmp (after convert back to original) did not return " "proper result (%d)", memcmp_rc2); printf("expected orig vs converted orig data\n"); print_hex(orig_data_size, &expected_orig_data); print_hex(orig_data_size, converted_orig_data); } TEST_FAIL_MESSAGE("convert_data (back to orig) did not match initial"); } return ZDNN_STATUS_OK; } // generate a float value between SMALLEST_RANDOM_FP to max #define GEN_RAND_FLOAT(x, max) \ while ((x) < SMALLEST_RANDOM_FP) { \ (x) = (float)rand() / (float)(RAND_MAX / max); \ } /*********************/ /* FP32 to DLF tests */ /*********************/ void test_FP32_DLF(int count) { float fixeddata[128] = {0}; // Build a tensor data area of req'd type with random data for (int i = 0; i < count; i++) { GEN_RAND_FLOAT(fixeddata[i], 3); } int test_result = convert_and_compare(FP32, count, fixeddata); TEST_ASSERT_MESSAGE(0 == test_result, "Converted and expected areas did not match"); } void test_FP32_DLF_1() { test_FP32_DLF(1); } void test_FP32_DLF_4() { test_FP32_DLF(4); } void test_FP32_DLF_7() { test_FP32_DLF(7); } void test_FP32_DLF_8() { test_FP32_DLF(8); } void test_FP32_DLF_9() { test_FP32_DLF(9); } void test_FP32_DLF_15() { test_FP32_DLF(15); } void test_FP32_DLF_63() { test_FP32_DLF(63); } void test_FP32_DLF_64() { test_FP32_DLF(64); } void test_16_DLF(zdnn_data_types type, int count) { float_bit16 fixeddata[4096] = {0}; // Build a tensor data area of req'd type with random data for (int i = 0; i < count; i++) { float temp_float = 0; GEN_RAND_FLOAT(temp_float, 3); if (type == FP16) { fixeddata[i] = cnvt_1_fp32_to_fp16(temp_float); } else if (type == BFLOAT) { fixeddata[i] = cnvt_1_fp32_to_bfloat(temp_float); } } int test_result = convert_and_compare(type, count, fixeddata); TEST_ASSERT_MESSAGE(0 == test_result, "Converted and expected areas did not match"); } void test_FP16_DLF_1() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE( "when ZDNN_CONFIG_NO_NNPA is set FP16<->DLFLOAT16 is noop"); #endif test_16_DLF(FP16, 1); } void test_FP16_DLF_7() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE( "when ZDNN_CONFIG_NO_NNPA is set FP16<->DLFLOAT16 is noop"); #endif test_16_DLF(FP16, 7); } void test_FP16_DLF_8() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE( "when ZDNN_CONFIG_NO_NNPA is set FP16<->DLFLOAT16 is noop"); #endif test_16_DLF(FP16, 8); } void test_FP16_DLF_9() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE( "when ZDNN_CONFIG_NO_NNPA is set FP16<->DLFLOAT16 is noop"); #endif test_16_DLF(FP16, 9); } void test_FP16_DLF_63() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE( "when ZDNN_CONFIG_NO_NNPA is set FP16<->DLFLOAT16 is noop"); #endif test_16_DLF(FP16, 63); } void test_FP16_DLF_64() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE( "when ZDNN_CONFIG_NO_NNPA is set FP16<->DLFLOAT16 is noop"); #endif test_16_DLF(FP16, 64); } void test_BFLOAT_DLF_1() { test_16_DLF(BFLOAT, 1); } void test_BFLOAT_DLF_7() { test_16_DLF(BFLOAT, 7); } void test_BFLOAT_DLF_8() { test_16_DLF(BFLOAT, 8); } void test_BFLOAT_DLF_9() { test_16_DLF(BFLOAT, 9); } void test_BFLOAT_DLF_63() { test_16_DLF(BFLOAT, 63); } void test_BFLOAT_DLF_64() { test_16_DLF(BFLOAT, 64); } // cppcheck-suppress unusedFunction void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } // cppcheck-suppress unusedFunction void tearDown(void) {} int main() { UNITY_BEGIN(); srand(time(0)); /* set up to get random values */ RUN_TEST(test_FP32_DLF_1); RUN_TEST(test_FP32_DLF_4); RUN_TEST(test_FP32_DLF_7); RUN_TEST(test_FP32_DLF_8); RUN_TEST(test_FP32_DLF_9); RUN_TEST(test_FP32_DLF_15); RUN_TEST(test_FP32_DLF_63); RUN_TEST(test_FP32_DLF_64); RUN_TEST(test_BFLOAT_DLF_1); RUN_TEST(test_BFLOAT_DLF_7); RUN_TEST(test_BFLOAT_DLF_8); RUN_TEST(test_BFLOAT_DLF_9); RUN_TEST(test_BFLOAT_DLF_63); RUN_TEST(test_BFLOAT_DLF_64); RUN_TEST(test_FP16_DLF_1); RUN_TEST(test_FP16_DLF_7); RUN_TEST(test_FP16_DLF_8); RUN_TEST(test_FP16_DLF_9); RUN_TEST(test_FP16_DLF_63); RUN_TEST(test_FP16_DLF_64); return UNITY_END(); } ���������������������zDNN-1.0.1/tests/testDriver_getoffset.c�������������������������������������������������������������0000664�0000000�0000000�00000031007�14364043643�0020041�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ } void tearDown(void) {} //================================================================================================= // tests for get_stick_offset void test_offset(uint32_t dim4, uint32_t dim3, uint32_t dim2, uint32_t dim1, zdnn_data_layouts layout, const uint64_t correct_offset[]) { zdnn_status status; zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, dim4, dim3, dim2, dim1); status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() returned %d \"%s\"", status, zdnn_get_status_message(status)); zdnn_init_ztensor(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); uint64_t *offsets_calculated = malloc(sizeof(uint64_t) * get_num_elements(&ztensor, ELEMENTS_PRE)); uint64_t c = 0; for (uint32_t e4x = 0; e4x < pre_tfrmd_desc.dim4; e4x++) { for (uint32_t e3x = 0; e3x < pre_tfrmd_desc.dim3; e3x++) { for (uint32_t e2x = 0; e2x < pre_tfrmd_desc.dim2; e2x++) { for (uint32_t e1x = 0; e1x < pre_tfrmd_desc.dim1; e1x++) { offsets_calculated[c] = get_stick_offset(e4x, e3x, e2x, e1x, &pre_tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( offsets_calculated[c] == correct_offset[c], "element (%d, %d, %d, %d) has wrong offset of %" PRIu64 ", (expects %" PRIu64 ")", e4x, e3x, e2x, e1x, offsets_calculated[c], correct_offset[c]); c++; } } } } free(offsets_calculated); } // offsets for a 1,4,4,1,NHWC void test_nhwc_1x4x4x1() { uint32_t dim4 = 1, dim3 = 4, dim2 = 4, dim1 = 1; uint64_t correct_offset[dim3 * dim2 * dim1]; int correct_offset_template[4] = {0, 128, 256, 384}; /* * Each element is the only one on a stick (C == 1), so that each W takes one * stick. There are then only 4 sticks used in a page, each H taking one page. */ for (int h = 0; h < dim3; h++) { for (int w = 0; w < dim2; w++) { correct_offset[h * dim2 + w] = h * AIU_PAGESIZE_IN_BYTES + correct_offset_template[w]; } } test_offset(dim4, dim3, dim2, dim1, ZDNN_NHWC, correct_offset); } void test_nhwc_1x2x2x4() { uint32_t dim4 = 1, dim3 = 2, dim2 = 2, dim1 = 4; /* * 16 elements total, with 4 cells used per stick, and 2 sticks per page. * At the H boundary (==2) switch to a new page */ uint64_t correct_offset[16] = {0, 2, 4, 6, 128, 130, 132, 134, 4096, 4098, 4100, 4102, 4224, 4226, 4228, 4230}; test_offset(dim4, dim3, dim2, dim1, ZDNN_NHWC, correct_offset); } // offsets for 1,32,32,3,NHWC void test_nhwc_1x32x32x3() { uint32_t dim4 = 1, dim3 = 32, dim2 = 32, dim1 = 3; uint64_t correct_offset[dim3 * dim2 * dim1]; uint32_t correct_offset_template[3] = {0, 2, 4}; uint32_t vertical_pages_per_h = (dim2 + AIU_STICKS_PER_PAGE - 1) / AIU_STICKS_PER_PAGE; uint16_t index = 0; for (int hx = 0; hx < dim3; hx++) { for (int wx = 0; wx < dim2; wx++) { for (int cx = 0; cx < dim1; cx++) { correct_offset[index++] = correct_offset_template[cx] + hx * vertical_pages_per_h * AIU_PAGESIZE_IN_BYTES + wx * AIU_BYTES_PER_STICK; } } } test_offset(dim4, dim3, dim2, dim1, ZDNN_NHWC, correct_offset); } void test_nhwc_1x4x33x64() { uint32_t dim4 = 1, dim3 = 4, dim2 = 33, dim1 = 64; uint64_t correct_offset[dim3 * dim2 * dim1]; uint32_t *template_stick = malloc(sizeof(uint32_t) * 64); for (uint32_t i = 0; i < 64; i++) template_stick[i] = i * AIU_2BYTE_CELL_SIZE; int index = 0; for (uint32_t e4x = 0; e4x < dim4; e4x++) { for (uint32_t e3x = 0; e3x < dim3; e3x++) { uint32_t page_num = e3x * 2; for (uint32_t e2x = 0; e2x < dim2; e2x++) { uint64_t stickOffset = e2x * AIU_BYTES_PER_STICK; for (int e1x = 0; e1x < dim1; e1x++) { correct_offset[index] = page_num * AIU_PAGESIZE_IN_BYTES + stickOffset + template_stick[e1x]; index++; } } } } test_offset(dim4, dim3, dim2, dim1, ZDNN_NHWC, correct_offset); free(template_stick); } void test_nhwc_1x4x32x65() { uint32_t dim4 = 1, dim3 = 4, dim2 = 32, dim1 = 65; uint64_t correct_offset[dim3 * dim2 * dim1]; uint32_t *template_stick = malloc(sizeof(uint32_t) * AIU_2BYTE_CELLS_PER_STICK); for (uint32_t i = 0; i < AIU_2BYTE_CELLS_PER_STICK; i++) template_stick[i] = i * AIU_2BYTE_CELL_SIZE; int index = 0; for (uint32_t e4x = 0; e4x < dim4; e4x++) { for (uint32_t e3x = 0; e3x < dim3; e3x++) { for (uint32_t e2x = 0; e2x < dim2; e2x++) { for (uint32_t e1x = 0; e1x < dim1; e1x++) { // h + floor(c/AIU_2BYTE_CELLS_PER_STICK) * H; uint32_t page_num = e3x + (e1x / AIU_2BYTE_CELLS_PER_STICK) * dim3; correct_offset[index] = page_num * AIU_PAGESIZE_IN_BYTES + e2x * AIU_BYTES_PER_STICK + template_stick[e1x % AIU_2BYTE_CELLS_PER_STICK]; index++; } } } } test_offset(dim4, dim3, dim2, dim1, ZDNN_NHWC, correct_offset); free(template_stick); } void test_nhwc_1x4x33x65() { uint32_t dim4 = 1, dim3 = 4, dim2 = 33, dim1 = 65; uint64_t correct_offset[dim3 * dim2 * dim1]; uint32_t *template_stick = malloc(sizeof(uint32_t) * AIU_2BYTE_CELLS_PER_STICK); for (uint32_t i = 0; i < AIU_2BYTE_CELLS_PER_STICK; i++) template_stick[i] = i * AIU_2BYTE_CELL_SIZE; int index = 0; for (int e4x = 0; e4x < dim4; e4x++) { for (int e3x = 0; e3x < dim3; e3x++) { for (int e2x = 0; e2x < dim2; e2x++) { for (int e1x = 0; e1x < dim1; e1x++) { uint32_t page_num = e3x * 2 + (e1x / AIU_2BYTE_CELLS_PER_STICK) * dim3 * 2; correct_offset[index] = page_num * AIU_PAGESIZE_IN_BYTES + e2x * AIU_BYTES_PER_STICK + template_stick[e1x % AIU_2BYTE_CELLS_PER_STICK]; index++; } } } } test_offset(dim4, dim3, dim2, dim1, ZDNN_NHWC, correct_offset); free(template_stick); } #define NHWC_TEST_WITH_FILE(n, h, w, c) \ void test_nhwc_##n##x##h##x##w##x##c() { \ uint32_t dim4 = n, dim3 = h, dim2 = w, dim1 = c; \ uint64_t correct_offset[n * h * w * c]; \ TEST_ASSERT_MESSAGE(get_offsets_from_file(OFFSET_FILE(nhwc, n, h, w, c), \ correct_offset) > 0, \ "get_offsets_from_file() failed"); \ test_offset(dim4, dim3, dim2, dim1, ZDNN_NHWC, correct_offset); \ } NHWC_TEST_WITH_FILE(1, 2, 3, 4) NHWC_TEST_WITH_FILE(1, 1, 31, 64) NHWC_TEST_WITH_FILE(1, 1, 32, 64) NHWC_TEST_WITH_FILE(1, 1, 33, 64) NHWC_TEST_WITH_FILE(1, 1, 32, 63) NHWC_TEST_WITH_FILE(1, 1, 32, 65) NHWC_TEST_WITH_FILE(1, 1, 4, 127) NHWC_TEST_WITH_FILE(1, 1, 4, 128) NHWC_TEST_WITH_FILE(1, 1, 4, 129) NHWC_TEST_WITH_FILE(1, 1, 63, 4) NHWC_TEST_WITH_FILE(1, 1, 64, 4) NHWC_TEST_WITH_FILE(1, 1, 65, 4) NHWC_TEST_WITH_FILE(2, 3, 33, 129) #define NCHW_TEST_WITH_FILE(n, c, h, w) \ void test_nchw_##n##x##c##x##h##x##w() { \ uint32_t dim4 = 1, dim3 = c, dim2 = h, dim1 = w; \ uint64_t correct_offset[n * c * h * w]; \ TEST_ASSERT_MESSAGE(get_offsets_from_file(OFFSET_FILE(nchw, n, c, h, w), \ correct_offset) > 0, \ "get_offsets_from_file() failed"); \ test_offset(dim4, dim3, dim2, dim1, ZDNN_NCHW, correct_offset); \ } NCHW_TEST_WITH_FILE(1, 1, 4, 4) NCHW_TEST_WITH_FILE(1, 4, 2, 3) NCHW_TEST_WITH_FILE(1, 3, 32, 32) NCHW_TEST_WITH_FILE(2, 129, 3, 33) NCHW_TEST_WITH_FILE(1, 64, 1, 31) NCHW_TEST_WITH_FILE(1, 64, 1, 32) NCHW_TEST_WITH_FILE(1, 64, 1, 33) NCHW_TEST_WITH_FILE(1, 63, 1, 32) NCHW_TEST_WITH_FILE(1, 65, 1, 32) NCHW_TEST_WITH_FILE(1, 127, 1, 4) NCHW_TEST_WITH_FILE(1, 128, 1, 4) NCHW_TEST_WITH_FILE(1, 129, 1, 4) NCHW_TEST_WITH_FILE(1, 4, 1, 63) NCHW_TEST_WITH_FILE(1, 4, 1, 64) NCHW_TEST_WITH_FILE(1, 4, 1, 65) #define HWCK_TEST_WITH_FILE(h, w, c, k) \ void test_hwck_##h##x##w##x##c##x##k() { \ uint32_t dim4 = h, dim3 = w, dim2 = c, dim1 = k; \ uint64_t correct_offset[h * w * c * k]; \ TEST_ASSERT_MESSAGE(get_offsets_from_file(OFFSET_FILE(hwck, h, w, c, k), \ correct_offset) > 0, \ "get_offsets_from_file() failed"); \ test_offset(dim4, dim3, dim2, dim1, ZDNN_HWCK, correct_offset); \ } HWCK_TEST_WITH_FILE(1, 4, 4, 1) HWCK_TEST_WITH_FILE(1, 2, 3, 4) HWCK_TEST_WITH_FILE(2, 3, 33, 129) HWCK_TEST_WITH_FILE(1, 32, 32, 3) HWCK_TEST_WITH_FILE(1, 1, 32, 63) HWCK_TEST_WITH_FILE(1, 1, 31, 64) HWCK_TEST_WITH_FILE(1, 1, 32, 64) HWCK_TEST_WITH_FILE(1, 1, 33, 64) HWCK_TEST_WITH_FILE(1, 1, 32, 65) HWCK_TEST_WITH_FILE(1, 1, 4, 127) HWCK_TEST_WITH_FILE(1, 1, 4, 128) HWCK_TEST_WITH_FILE(1, 1, 4, 129) HWCK_TEST_WITH_FILE(1, 1, 63, 4) HWCK_TEST_WITH_FILE(1, 1, 64, 4) HWCK_TEST_WITH_FILE(1, 1, 65, 4) int main(void) { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(test_nhwc_1x4x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x2x2x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x32x32x3); RUN_TEST_ALL_DATATYPES(test_nhwc_1x4x33x64); RUN_TEST_ALL_DATATYPES(test_nhwc_1x4x32x65); RUN_TEST_ALL_DATATYPES(test_nhwc_1x4x33x65); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x33x129); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x31x64); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x32x64); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x33x64); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x32x63); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x32x65); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x127); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x128); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x129); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x63x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x64x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x65x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x1x4x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x2x3); RUN_TEST_ALL_DATATYPES(test_nchw_1x3x32x32); RUN_TEST_ALL_DATATYPES(test_nchw_2x129x3x33); RUN_TEST_ALL_DATATYPES(test_nchw_1x63x1x32); RUN_TEST_ALL_DATATYPES(test_nchw_1x64x1x31); RUN_TEST_ALL_DATATYPES(test_nchw_1x64x1x32); RUN_TEST_ALL_DATATYPES(test_nchw_1x64x1x33); RUN_TEST_ALL_DATATYPES(test_nchw_1x65x1x32); RUN_TEST_ALL_DATATYPES(test_nchw_1x127x1x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x128x1x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x129x1x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x1x63); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x1x64); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x1x65); RUN_TEST_ALL_DATATYPES(test_hwck_1x4x4x1); RUN_TEST_ALL_DATATYPES(test_hwck_1x2x3x4); RUN_TEST_ALL_DATATYPES(test_hwck_1x32x32x3); RUN_TEST_ALL_DATATYPES(test_hwck_2x3x33x129); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x32x63); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x31x64); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x32x64); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x33x64); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x32x65); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x4x127); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x4x128); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x4x129); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x63x4); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x64x4); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x65x4); return UNITY_END(); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_init_ztensor.c����������������������������������������������������������0000664�0000000�0000000�00000107611�14364043643�0020607�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} // Helper method for tests that check the boundaries of the maximum dim1 index. // Concatenated ztensors introduce padding that must be determined to test this. // See zdnn_generate_transformed_desc_concatenated() to see padding equation. uint32_t max_concat_dim1(uint32_t num_concats) { uint32_t temp = zdnn_get_nnpa_max_dim_idx_size() / num_concats; uint32_t max_concat_dim1 = temp - (temp % AIU_2BYTE_CELLS_PER_STICK); LOG_TRACE("returning %d\n", max_concat_dim1); return max_concat_dim1; } // test if we can zdnn_init_ztensor_with_malloc() correctly with the supplied // pre-transformed and transformed descriptors void test_main(zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc, zdnn_concat_info info, uint64_t exp_size, zdnn_status exp_status_allochelper) { zdnn_ztensor ztensor; zdnn_status status; status = zdnn_init_ztensor_with_malloc(pre_tfrmd_desc, tfrmd_desc, &ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status_allochelper, "zdnn_init_ztensor_with_malloc() status is %08x (%s) " "but expects %08x (%s) (concat info = %08x)", status, zdnn_get_status_message(status), exp_status_allochelper, zdnn_get_status_message(exp_status_allochelper), info); // check and free buffer but only if expected // zdnn_init_ztensor_with_malloc() to work if (exp_status_allochelper == ZDNN_OK) { TEST_ASSERT_MESSAGE_FORMATTED( ztensor.buffer_size == exp_size, "zdnn_init_ztensor_with_malloc() returns incorrect size: %" PRIu64 " (expects %" PRIu64 ") (concat info = %08x)", ztensor.buffer_size, exp_size, info); zdnn_free_ztensor_buffer(&ztensor); } } void test_normal(zdnn_tensor_desc *pre_tfrmd_desc, uint64_t exp_size) { zdnn_tensor_desc tfrmd_desc; zdnn_status status; status = zdnn_generate_transformed_desc(pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() status is %08x (%s) " "but expects %08x (%s))", status, zdnn_get_status_message(status), ZDNN_OK, zdnn_get_status_message(ZDNN_OK)); test_main(pre_tfrmd_desc, &tfrmd_desc, NO_CONCAT, exp_size, ZDNN_OK); } /// Drive the creation of a FICO/ZRH ztensor with the provided pre-transformed /// layout, data type and dims, and transformed layout (FICO/ZRH). Then drive /// allocation and compare to an expected value. /// /// \param[in] pre_tfrmd_layout pre-transformed layout /// \param[in] info concatenation info /// \param[in] exp_size expected allocation size /// \param[in] exp_status_gen_concat expected status of _desc_concatenated() /// \param[in] exp_status_allochelper expected status of _allochelper() /// \param[in] ... dimensions, outermost -> innermost /// order (ie shape order) /// /// \return None - Fails test assertion if actual values don't match specified /// exp values /// void test_concat(zdnn_data_layouts pre_tfrmd_layout, zdnn_concat_info info, uint64_t exp_size, zdnn_status exp_status_gen_concat, zdnn_status exp_status_allochelper, ...) { zdnn_status status; zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; uint32_t num_things; switch (pre_tfrmd_layout) { case ZDNN_2DS: case ZDNN_3DS: num_things = get_data_layout_dims(pre_tfrmd_layout); break; default: // for driving an "invalid layout" testcase num_things = 4; break; } va_list v_list; va_start(v_list, exp_status_allochelper); uint32_t dim_nums[num_things]; for (uint32_t i = 0; i < num_things; i++) { dim_nums[i] = va_arg(v_list, uint32_t); } va_end(v_list); switch (pre_tfrmd_layout) { case ZDNN_2DS: zdnn_init_pre_transformed_desc(pre_tfrmd_layout, test_datatype, &pre_tfrmd_desc, dim_nums[0], dim_nums[1]); break; case ZDNN_3DS: zdnn_init_pre_transformed_desc(pre_tfrmd_layout, test_datatype, &pre_tfrmd_desc, dim_nums[0], dim_nums[1], dim_nums[2]); break; default: zdnn_init_pre_transformed_desc(pre_tfrmd_layout, test_datatype, &pre_tfrmd_desc, dim_nums[0], dim_nums[1], dim_nums[2], dim_nums[3]); break; } status = zdnn_generate_transformed_desc_concatenated(&pre_tfrmd_desc, info, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status_gen_concat, "zdnn_generate_transformed_desc_concatenated() status is %08x (%s) " "but expects %08x (%s))", status, zdnn_get_status_message(status), exp_status_gen_concat, zdnn_get_status_message(exp_status_gen_concat)); // do the rest if expected zdnn_generate_transformed_desc_concatenated() to // work if (exp_status_gen_concat == ZDNN_OK) { test_main(&pre_tfrmd_desc, &tfrmd_desc, info, exp_size, exp_status_allochelper); } } void test_NHWC(unsigned int n, unsigned int h, unsigned int w, unsigned int c, uint64_t exp_size) { zdnn_tensor_desc pre_tfrmd_desc; zdnn_init_pre_transformed_desc(ZDNN_NHWC, test_datatype, &pre_tfrmd_desc, n, h, w, c); test_normal(&pre_tfrmd_desc, exp_size); } void test_2D(unsigned int dim2, unsigned int dim1, uint64_t exp_size) { zdnn_tensor_desc pre_tfrmd_desc; zdnn_init_pre_transformed_desc(ZDNN_2D, test_datatype, &pre_tfrmd_desc, dim2, dim1); test_normal(&pre_tfrmd_desc, exp_size); } /// Drive the creation of a tensor descriptor with the layout /// ZDNN_2DS and passed in dimensions. This will then call /// the test_main function to drive allocation and compare to /// an expected value. /// /// \param[in] e1 dimension 1 /// \param[in] e2 dimension 2 /// \param[in] exp_size expected allocation size /// /// \return None /// void test_2DS(uint32_t dim2, uint32_t dim1, uint64_t exp_size) { zdnn_tensor_desc pre_tfrmd_desc; zdnn_init_pre_transformed_desc(ZDNN_2DS, test_datatype, &pre_tfrmd_desc, dim2, dim1); test_normal(&pre_tfrmd_desc, exp_size); } /// Drive the creation of a tensor descriptor with the layout /// ZDNN_3DS and passed in dimensions. This will then call /// the test_main function to drive allocation and compare to /// an expected value. /// /// \param[in] e1 dimension 1 /// \param[in] e2 dimension 2 /// \param[in] e3 dimension 3 /// \param[in] exp_size expected allocation size /// /// \return None /// void test_3DS(uint32_t dim3, uint32_t dim2, uint32_t dim1, uint64_t exp_size) { zdnn_tensor_desc pre_tfrmd_desc; zdnn_init_pre_transformed_desc(ZDNN_3DS, test_datatype, &pre_tfrmd_desc, dim3, dim2, dim1); test_normal(&pre_tfrmd_desc, exp_size); } void test_NHWC_1x3x3x5() { test_NHWC(1, 3, 3, 5, 12288); } void test_NHWC_5x32x32x3() { test_NHWC(5, 32, 32, 3, 655360); } void test_NHWC_1x64x64x64() { test_NHWC(1, 64, 64, 64, 524288); } void test_NHWC_1x8x8x1() { test_NHWC(1, 8, 8, 1, 32768); } void test_NHWC_1x256x256x1() { test_NHWC(1, 256, 256, 1, 8388608); } void test_NHWC_1x1x256x1() { test_NHWC(1, 1, 256, 1, 32768); } void test_2D_8x8() { test_2D(8, 8, 4096); } void test_2DS_1x8() { test_2DS(1, 8, 4096); } void test_2DS_8x1() { test_2DS(8, 1, 32768); } void test_2DS_8x8() { test_2DS(8, 8, 32768); } void test_2DS_32x8() { test_2DS(32, 8, 131072); } void test_2DS_64x8() { test_2DS(64, 8, 262144); } void test_2DS_64x64() { test_2DS(64, 64, 262144); } void test_2DS_256x32() { test_2DS(256, 32, 1048576); } void test_2DS_256x256() { test_2DS(256, 256, 4194304); } void test_3DS_1x8x1() { test_3DS(1, 8, 1, 4096); } void test_3DS_8x8x1() { test_3DS(8, 8, 1, 32768); } void test_3DS_8x8x8() { test_3DS(8, 8, 8, 32768); } void test_3DS_16x32x8() { test_3DS(16, 32, 8, 65536); } void test_3DS_16x64x8() { test_3DS(16, 64, 8, 131072); } void test_3DS_16x256x32() { test_3DS(16, 256, 32, 524288); } void test_3DS_16x64x64() { test_3DS(16, 64, 64, 131072); } void test_3DS_16x256x256() { test_3DS(16, 256, 256, 2097152); } //------------------------------------------------------------ // any combination of PREV_ UNI/BIDIR + BIASES/HIDDEN_BIASES should yield the // same results void test_lstm_biases_1x8() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 16384, ZDNN_OK, ZDNN_OK, 1, 8); } } } void test_lstm_biases_2x32() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 32768, ZDNN_OK, ZDNN_OK, 2, 32); } } } void test_lstm_biases_1x64() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 16384, ZDNN_OK, ZDNN_OK, 1, 64); } } } void test_lstm_biases_2x70() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 65536, ZDNN_OK, ZDNN_OK, 2, 70); } } } void test_lstm_biases_1x128() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 32768, ZDNN_OK, ZDNN_OK, 1, 128); } } } void test_lstm_biases_2x150() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 98304, ZDNN_OK, ZDNN_OK, 2, 150); } } } //------------------------------------------------------------ // PREV_ UNI/BIDIR + HIDDEN_WEIGHTS and UNI + WEIGHTS should yield the same // results void test_lstm_no_vconcat_weights_1x2x8() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | no_vconcat_infos[i], 16384, ZDNN_OK, ZDNN_OK, 1, 2, 8); } } void test_lstm_no_vconcat_weights_2x5x32() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | no_vconcat_infos[i], 32768, ZDNN_OK, ZDNN_OK, 2, 5, 32); } } void test_lstm_no_vconcat_weights_1x3x64() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | no_vconcat_infos[i], 16384, ZDNN_OK, ZDNN_OK, 1, 3, 64); } } void test_lstm_no_vconcat_weights_2x10x70() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | no_vconcat_infos[i], 65536, ZDNN_OK, ZDNN_OK, 2, 10, 70); } } void test_lstm_no_vconcat_weights_1x34x128() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | no_vconcat_infos[i], 65536, ZDNN_OK, ZDNN_OK, 1, 34, 128); } } void test_lstm_no_vconcat_weights_2x50x150() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | no_vconcat_infos[i], 196608, ZDNN_OK, ZDNN_OK, 2, 50, 150); } } //------------------------------------------------------------ // lstm_prev_bidir_weights expected size: // dim3 * (2 * PADDED(dim2/2) / AIU_STICKS_PER_PAGE) * // ceil(dim1/AIU_2BYTE_CELLS_PER_STICK) * // * AIU_PAGESIZE_IN_BYTES * 4 void test_lstm_prev_bidir_weights_1x2x8() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 65536, ZDNN_OK, ZDNN_OK, 1, 2, 8); } void test_lstm_prev_bidir_weights_2x2x8() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 131072, ZDNN_OK, ZDNN_OK, 2, 2, 8); } void test_lstm_prev_bidir_weights_1x34x8() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 65536, ZDNN_OK, ZDNN_OK, 1, 34, 8); } void test_lstm_prev_bidir_weights_2x34x8() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 131072, ZDNN_OK, ZDNN_OK, 2, 34, 8); } void test_lstm_prev_bidir_weights_1x64x10() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 65536, ZDNN_OK, ZDNN_OK, 1, 64, 10); } void test_lstm_prev_bidir_weights_2x64x10() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 131072, ZDNN_OK, ZDNN_OK, 2, 64, 10); } void test_lstm_prev_bidir_weights_1x70x20() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 65536, ZDNN_OK, ZDNN_OK, 1, 70, 20); } void test_lstm_prev_bidir_weights_2x70x20() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 131072, ZDNN_OK, ZDNN_OK, 2, 70, 20); } void test_lstm_prev_bidir_weights_1x10x32() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 65536, ZDNN_OK, ZDNN_OK, 1, 10, 32); } void test_lstm_prev_bidir_weights_2x10x32() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 131072, ZDNN_OK, ZDNN_OK, 2, 10, 32); } void test_lstm_prev_bidir_weights_1x6x64() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 65536, ZDNN_OK, ZDNN_OK, 1, 6, 64); } void test_lstm_prev_bidir_weights_2x6x64() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 131072, ZDNN_OK, ZDNN_OK, 2, 6, 64); } void test_lstm_prev_bidir_weights_1x10x70() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 131072, ZDNN_OK, ZDNN_OK, 1, 10, 70); } void test_lstm_prev_bidir_weights_2x10x70() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 262144, ZDNN_OK, ZDNN_OK, 2, 10, 70); } void test_lstm_prev_bidir_weights_1x34x128() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 131072, ZDNN_OK, ZDNN_OK, 1, 34, 128); } void test_lstm_prev_bidir_weights_2x34x128() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 262144, ZDNN_OK, ZDNN_OK, 2, 34, 128); } void test_lstm_prev_bidir_weights_1x50x150() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 196608, ZDNN_OK, ZDNN_OK, 1, 50, 150); } void test_lstm_prev_bidir_weights_2x50x150() { test_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 393216, ZDNN_OK, ZDNN_OK, 2, 50, 150); } //------------------------------------------------------------ void test_CONCAT_LSTM_fail_unsupported_layout() { // bad layout: ZDNN_4D as pre-transformed yields ZDNN_INVALID_LAYOUT test_concat(ZDNN_4D, RNN_TYPE_LSTM | PREV_LAYER_UNI | USAGE_WEIGHTS, 0, ZDNN_INVALID_LAYOUT, 0, 1, 2, 3, 4); } void test_CONCAT_LSTM_max_dim1() { // Confirm we pass when at the maximum number of dim1 elements // LSTM concatenates 4 gates. uint32_t max_dim1 = max_concat_dim1(4); test_concat(ZDNN_2DS, RNN_TYPE_LSTM | PREV_LAYER_UNI | USAGE_BIASES, 2097152, ZDNN_OK, ZDNN_OK, 1, max_dim1); } void test_CONCAT_LSTM_fail_dim1_too_big() { // zdnn_generate_transformed_desc_concatenated() yields no error but // zdnn_allochelper() yields ZDNN_DATA_ERROR during it's checks. // LSTM concatenates 4 gates. uint32_t max_dim1 = max_concat_dim1(4); test_concat(ZDNN_2DS, RNN_TYPE_LSTM | PREV_LAYER_UNI | USAGE_BIASES, 0, ZDNN_OK, ZDNN_INVALID_SHAPE, 1, max_dim1 + 1); } void test_CONCAT_LSTM_max_dim1_API_doc() { // This value is hardcoded in our API documentation. If the hardware makes // a change that alters the max value, this UT will fail. uint64_t max_dim1 = max_concat_dim1(4); uint64_t doc_max_dim1 = 8192; TEST_ASSERT_MESSAGE_FORMATTED( max_dim1 == doc_max_dim1, "hardware returned a maximum dim1 of %" PRIu64 " but our LSTM API documents the hidden_stat_size limit %" PRIu64 ". Update documentation and this test to match new value.", max_dim1, doc_max_dim1); } //------------------------------------------------------------ // test_gru_* tests are based off test_lstm_*, with smaller expected sizes ( = // 3/4 of test_lstm__*'s ) void test_gru_biases_1x8() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 12288, ZDNN_OK, ZDNN_OK, 1, 8); } } } void test_gru_biases_2x32() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 24576, ZDNN_OK, ZDNN_OK, 2, 32); } } } void test_gru_biases_1x64() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 12288, ZDNN_OK, ZDNN_OK, 1, 64); } } } void test_gru_biases_2x70() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 49152, ZDNN_OK, ZDNN_OK, 2, 70); } } } void test_gru_biases_1x128() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 24576, ZDNN_OK, ZDNN_OK, 1, 128); } } } void test_gru_biases_2x150() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat(ZDNN_2DS, RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 73728, ZDNN_OK, ZDNN_OK, 2, 150); } } } //------------------------------------------------------------ // PREV_ UNI/BIDIR + HIDDEN_WEIGHTS and UNI + WEIGHTS should yield the same // results void test_gru_no_vconcat_weights_1x2x8() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_GRU | no_vconcat_infos[i], 12288, ZDNN_OK, ZDNN_OK, 1, 2, 8); } } void test_gru_no_vconcat_weights_2x5x32() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_GRU | no_vconcat_infos[i], 24576, ZDNN_OK, ZDNN_OK, 2, 5, 32); } } void test_gru_no_vconcat_weights_1x3x64() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_GRU | no_vconcat_infos[i], 12288, ZDNN_OK, ZDNN_OK, 1, 3, 64); } } void test_gru_no_vconcat_weights_2x10x70() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_GRU | no_vconcat_infos[i], 49152, ZDNN_OK, ZDNN_OK, 2, 10, 70); } } void test_gru_no_vconcat_weights_1x34x128() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_GRU | no_vconcat_infos[i], 49152, ZDNN_OK, ZDNN_OK, 1, 34, 128); } } void test_gru_no_vconcat_weights_2x50x150() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_concat(ZDNN_3DS, RNN_TYPE_GRU | no_vconcat_infos[i], 147456, ZDNN_OK, ZDNN_OK, 2, 50, 150); } } //------------------------------------------------------------ // gru_prev_bidir_weights expected size: // dim3 * (2 * PADDED(dim2/2) / AIU_STICKS_PER_PAGE) * // ceil(dim1/AIU_2BYTE_CELLS_PER_STICK) * // * AIU_PAGESIZE_IN_BYTES * 3 void test_gru_prev_bidir_weights_1x2x8() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 49152, ZDNN_OK, ZDNN_OK, 1, 2, 8); } void test_gru_prev_bidir_weights_2x2x8() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 98304, ZDNN_OK, ZDNN_OK, 2, 2, 8); } void test_gru_prev_bidir_weights_1x34x8() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 49152, ZDNN_OK, ZDNN_OK, 1, 34, 8); } void test_gru_prev_bidir_weights_2x34x8() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 98304, ZDNN_OK, ZDNN_OK, 2, 34, 8); } void test_gru_prev_bidir_weights_1x64x10() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 49152, ZDNN_OK, ZDNN_OK, 1, 64, 10); } void test_gru_prev_bidir_weights_2x64x10() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 98304, ZDNN_OK, ZDNN_OK, 2, 64, 10); } void test_gru_prev_bidir_weights_1x70x20() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 49152, ZDNN_OK, ZDNN_OK, 1, 70, 20); } void test_gru_prev_bidir_weights_2x70x20() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 98304, ZDNN_OK, ZDNN_OK, 2, 70, 20); } void test_gru_prev_bidir_weights_1x10x32() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 49152, ZDNN_OK, ZDNN_OK, 1, 10, 32); } void test_gru_prev_bidir_weights_2x10x32() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 98304, ZDNN_OK, ZDNN_OK, 2, 10, 32); } void test_gru_prev_bidir_weights_1x6x64() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 49152, ZDNN_OK, ZDNN_OK, 1, 6, 64); } void test_gru_prev_bidir_weights_2x6x64() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 98304, ZDNN_OK, ZDNN_OK, 2, 6, 64); } void test_gru_prev_bidir_weights_1x10x70() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 98304, ZDNN_OK, ZDNN_OK, 1, 10, 70); } void test_gru_prev_bidir_weights_2x10x70() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 196608, ZDNN_OK, ZDNN_OK, 2, 10, 70); } void test_gru_prev_bidir_weights_1x34x128() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 98304, ZDNN_OK, ZDNN_OK, 1, 34, 128); } void test_gru_prev_bidir_weights_2x34x128() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 196608, ZDNN_OK, ZDNN_OK, 2, 34, 128); } void test_gru_prev_bidir_weights_1x50x150() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 147456, ZDNN_OK, ZDNN_OK, 1, 50, 150); } void test_gru_prev_bidir_weights_2x50x150() { test_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 294912, ZDNN_OK, ZDNN_OK, 2, 50, 150); } //------------------------------------------------------------ void test_CONCAT_GRU_fail_unsupported_layout() { // bad layout: ZDNN_4D as pre-transformed yields ZDNN_INVALID_LAYOUT test_concat(ZDNN_4D, RNN_TYPE_GRU | PREV_LAYER_UNI | USAGE_WEIGHTS, 0, ZDNN_INVALID_LAYOUT, 1, 2, 3, 4); } void test_CONCAT_GRU_max_dim1() { // Confirm we pass when at the maximum number of dim1 elements // GRU concatenates 3 gates. uint64_t max_dim1 = max_concat_dim1(3); test_concat(ZDNN_2DS, RNN_TYPE_GRU | PREV_LAYER_UNI | USAGE_BIASES, 2088960, ZDNN_OK, ZDNN_OK, 1, max_dim1); } void test_CONCAT_GRU_fail_dim1_too_big() { // zdnn_generate_transformed_desc_concatenated() yields no error but // zdnn_allochelper() yields ZDNN_DATA_ERROR during it's checks. // GRU concatenates 3 gates. uint64_t max_dim1 = max_concat_dim1(3); test_concat(ZDNN_2DS, RNN_TYPE_GRU | PREV_LAYER_UNI | USAGE_BIASES, 0, ZDNN_OK, ZDNN_INVALID_SHAPE, 1, max_dim1 + 1); } void test_CONCAT_GRU_max_dim1_API_doc() { // This value is hardcoded in our API documentation. If the hardware makes // a change that alters this, this UT will fail. uint64_t max_dim1 = max_concat_dim1(3); uint64_t doc_max_dim1 = 10880; TEST_ASSERT_MESSAGE_FORMATTED( max_dim1 == doc_max_dim1, "hardware returned a maximum dim1 of %" PRIu64 " but our GRU API documents the hidden_stat_size limit %" PRIu64 ". Update documentation and this test to match new value.", max_dim1, doc_max_dim1); } //------------------------------------------------------------ void test_rnn_output(uint32_t dim4, uint32_t dim3, uint32_t dim2, uint32_t dim1, uint64_t exp_size) { zdnn_tensor_desc pre_tfrmd_desc; zdnn_init_pre_transformed_desc(ZDNN_4DS, test_datatype, &pre_tfrmd_desc, dim4, dim3, dim2, dim1); test_normal(&pre_tfrmd_desc, exp_size); } void test_uni_output_1x1x2x8() { test_rnn_output(1, 1, 2, 8, 4096); } void test_uni_output_2x1x5x32() { test_rnn_output(2, 1, 5, 32, 8192); } void test_uni_output_1x1x3x64() { test_rnn_output(1, 1, 3, 64, 4096); } void test_uni_output_2x1x10x70() { test_rnn_output(2, 1, 10, 70, 16384); } void test_uni_output_1x1x34x128() { test_rnn_output(1, 1, 34, 128, 16384); } void test_uni_output_2x1x50x150() { test_rnn_output(2, 1, 50, 150, 49152); } void test_bidir_output_1x2x2x8() { test_rnn_output(1, 2, 2, 8, 8192); } void test_bidir_output_2x2x5x32() { test_rnn_output(2, 2, 5, 32, 16384); } void test_bidir_output_1x2x3x64() { test_rnn_output(1, 2, 3, 64, 8192); } void test_bidir_output_2x2x10x70() { test_rnn_output(2, 2, 10, 70, 32768); } void test_bidir_output_1x2x34x128() { test_rnn_output(1, 2, 34, 128, 32768); } void test_bidir_output_2x2x50x150() { test_rnn_output(2, 2, 50, 150, 98304); } //------------------------------------------------------------ void test_bidir_output_max_dim1() { // Confirm we pass when at the maximum number of dim1 elements zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; uint64_t max_dim1 = max_concat_dim1(2); zdnn_init_pre_transformed_desc(ZDNN_4DS, test_datatype, &pre_tfrmd_desc, 1, 2, 2, max_dim1); zdnn_status status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() status is %08x (%s) " "but expects %08x (%s))", status, zdnn_get_status_message(status), ZDNN_OK, zdnn_get_status_message(ZDNN_OK)); test_main(&pre_tfrmd_desc, &tfrmd_desc, NO_CONCAT, 2097152, ZDNN_OK); } void test_bidir_output_fail_dim1_too_big() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; uint64_t max_dim1 = max_concat_dim1(2); zdnn_init_pre_transformed_desc(ZDNN_4DS, test_datatype, &pre_tfrmd_desc, 1, 2, 3, max_dim1 + 1); // zdnn_generate_transformed_desc_concatenated() yields no error but // zdnn_allochelper() yields ZDNN_DATA_ERROR during it's checks. zdnn_status status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() status is %08x (%s) " "but expects %08x (%s))", status, zdnn_get_status_message(status), ZDNN_OK, zdnn_get_status_message(ZDNN_OK)); test_main(&pre_tfrmd_desc, &tfrmd_desc, NO_CONCAT, 9999, ZDNN_INVALID_SHAPE); } void test_zdnn_init_ztensor_function() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; // Set ztensor to all 1s prior to function call. memset(&ztensor, 1, sizeof(ztensor)); zdnn_init_ztensor(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); TEST_ASSERT_MESSAGE( ztensor.pre_transformed_desc == &pre_tfrmd_desc, "Expected ztensor to point to passed in pre-transformed descriptor."); TEST_ASSERT_MESSAGE( ztensor.transformed_desc == &tfrmd_desc, "Expected ztensor to point to passed in transformed descriptor."); TEST_ASSERT_MESSAGE( false == ztensor.is_transformed, "Expected ztensor to have is_transformed initialized as false."); // We expect reserved area to be all zeros, create variable for memcmp char expected_reserved[sizeof(ztensor.reserved)] = {0}; TEST_ASSERT_MESSAGE( memcmp(expected_reserved, ztensor.reserved, sizeof(expected_reserved)) == 0, "Expected ztensor reserved area not initialized to zeroes."); } void test_zdnn_init_ztensor_via_malloc_function() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; // Create a very basic descriptors to satisfy malloc portion of init function zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP32, &pre_tfrmd_desc, 1, 1, 1, 1); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); // Set ztensor to all 1s prior to function call. memset(&ztensor, 1, sizeof(ztensor)); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); TEST_ASSERT_MESSAGE( ztensor.pre_transformed_desc == &pre_tfrmd_desc, "Expected ztensor to point to passed in pre-transformed descriptor."); TEST_ASSERT_MESSAGE( ztensor.transformed_desc == &tfrmd_desc, "Expected ztensor to point to passed in transformed descriptor."); TEST_ASSERT_MESSAGE( false == ztensor.is_transformed, "Expected ztensor to have is_transformed initialized as false."); // We expect reserved area to be all zeros, create variable for memcmp char expected_reserved[sizeof(ztensor.reserved)] = {0}; TEST_ASSERT_MESSAGE( memcmp(expected_reserved, ztensor.reserved, sizeof(expected_reserved)) == 0, "Expected ztensor reserved area not initialized to zeroes."); zdnn_free_ztensor_buffer(&ztensor); } int main(void) { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(test_NHWC_1x3x3x5); RUN_TEST_ALL_DATATYPES(test_NHWC_5x32x32x3); RUN_TEST_ALL_DATATYPES(test_NHWC_1x64x64x64); RUN_TEST_ALL_DATATYPES(test_NHWC_1x8x8x1); RUN_TEST_ALL_DATATYPES(test_NHWC_1x256x256x1); RUN_TEST_ALL_DATATYPES(test_NHWC_1x1x256x1); RUN_TEST_ALL_DATATYPES(test_2D_8x8); RUN_TEST_ALL_DATATYPES(test_2DS_1x8); RUN_TEST_ALL_DATATYPES(test_2DS_8x1); RUN_TEST_ALL_DATATYPES(test_2DS_8x8); RUN_TEST_ALL_DATATYPES(test_2DS_32x8); RUN_TEST_ALL_DATATYPES(test_2DS_64x8); RUN_TEST_ALL_DATATYPES(test_2DS_256x32); RUN_TEST_ALL_DATATYPES(test_2DS_64x64); RUN_TEST_ALL_DATATYPES(test_2DS_256x256); RUN_TEST_ALL_DATATYPES(test_3DS_1x8x1); RUN_TEST_ALL_DATATYPES(test_3DS_8x8x1); RUN_TEST_ALL_DATATYPES(test_3DS_8x8x8); RUN_TEST_ALL_DATATYPES(test_3DS_16x32x8); RUN_TEST_ALL_DATATYPES(test_3DS_16x64x8); RUN_TEST_ALL_DATATYPES(test_3DS_16x256x32); RUN_TEST_ALL_DATATYPES(test_3DS_16x64x64); RUN_TEST_ALL_DATATYPES(test_3DS_16x256x256); RUN_TEST_ALL_DATATYPES(test_lstm_biases_1x8); RUN_TEST_ALL_DATATYPES(test_lstm_biases_2x32); RUN_TEST_ALL_DATATYPES(test_lstm_biases_1x64); RUN_TEST_ALL_DATATYPES(test_lstm_biases_2x70); RUN_TEST_ALL_DATATYPES(test_lstm_biases_1x128); RUN_TEST_ALL_DATATYPES(test_lstm_biases_2x150); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_1x2x8); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_2x5x32); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x2x8); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x2x8); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x34x8); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x34x8); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x64x10); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x64x10); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x70x20); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x70x20); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x10x32); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x10x32); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_1x3x64); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_2x10x70); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_1x34x128); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_2x50x150); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x6x64); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x6x64); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x10x70); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x10x70); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x34x128); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x34x128); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x50x150); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x50x150); RUN_TEST_ALL_DATATYPES(test_CONCAT_LSTM_max_dim1); RUN_TEST_ALL_DATATYPES(test_CONCAT_LSTM_fail_unsupported_layout); RUN_TEST_ALL_DATATYPES(test_CONCAT_LSTM_fail_dim1_too_big); RUN_TEST_ALL_DATATYPES(test_CONCAT_LSTM_max_dim1_API_doc); RUN_TEST_ALL_DATATYPES(test_gru_biases_1x8); RUN_TEST_ALL_DATATYPES(test_gru_biases_2x32); RUN_TEST_ALL_DATATYPES(test_gru_biases_1x64); RUN_TEST_ALL_DATATYPES(test_gru_biases_2x70); RUN_TEST_ALL_DATATYPES(test_gru_biases_1x128); RUN_TEST_ALL_DATATYPES(test_gru_biases_2x150); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_1x2x8); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_2x5x32); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x2x8); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x2x8); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x34x8); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x34x8); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x64x10); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x64x10); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x70x20); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x70x20); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x10x32); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x10x32); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_1x3x64); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_2x10x70); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_1x34x128); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_2x50x150); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x6x64); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x6x64); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x10x70); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x10x70); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x34x128); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x34x128); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x50x150); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x50x150); RUN_TEST_ALL_DATATYPES(test_CONCAT_GRU_max_dim1); RUN_TEST_ALL_DATATYPES(test_CONCAT_GRU_fail_unsupported_layout); RUN_TEST_ALL_DATATYPES(test_CONCAT_GRU_fail_dim1_too_big); RUN_TEST_ALL_DATATYPES(test_CONCAT_GRU_max_dim1_API_doc); RUN_TEST_ALL_DATATYPES(test_uni_output_1x1x2x8); RUN_TEST_ALL_DATATYPES(test_uni_output_2x1x5x32); RUN_TEST_ALL_DATATYPES(test_bidir_output_1x2x2x8); RUN_TEST_ALL_DATATYPES(test_bidir_output_2x2x5x32); RUN_TEST_ALL_DATATYPES(test_uni_output_1x1x3x64); RUN_TEST_ALL_DATATYPES(test_uni_output_2x1x10x70); RUN_TEST_ALL_DATATYPES(test_uni_output_1x1x34x128); RUN_TEST_ALL_DATATYPES(test_uni_output_2x1x50x150); RUN_TEST_ALL_DATATYPES(test_bidir_output_1x2x3x64); RUN_TEST_ALL_DATATYPES(test_bidir_output_2x2x10x70); RUN_TEST_ALL_DATATYPES(test_bidir_output_1x2x34x128); RUN_TEST_ALL_DATATYPES(test_bidir_output_2x2x50x150); RUN_TEST_ALL_DATATYPES(test_bidir_output_max_dim1); RUN_TEST_ALL_DATATYPES(test_bidir_output_fail_dim1_too_big); RUN_TEST(test_zdnn_init_ztensor_function); RUN_TEST(test_zdnn_init_ztensor_via_malloc_function); return UNITY_END(); } �����������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_logger.c����������������������������������������������������������������0000664�0000000�0000000�00000015312�14364043643�0017333�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "testsupport.h" char msg_trace[] = "TRACE"; char msg_debug[] = "DEBUG"; char msg_info[] = "INFO"; char msg_warn[] = "WARN"; char msg_error[] = "ERROR"; char msg_fatal[] = "FATAL"; void setUp(void) { /* This is run before EACH TEST */ } void tearDown(void) {} void try_log(uint32_t loglvl) { // override whatever ZDNN_LOGLEVEL/ZDNN_LOGMODULE are set in env log_level = loglvl; log_module[0] = '\0'; char buf_stdout[BUFSIZ] = {0}; char buf_stderr[BUFSIZ] = {0}; stdout_to_pipe(); stderr_to_pipe(); LOG_TRACE(msg_trace, NO_ARG); LOG_DEBUG(msg_debug, NO_ARG); LOG_INFO(msg_info, NO_ARG); LOG_WARN(msg_warn, NO_ARG); LOG_ERROR(msg_error, NO_ARG); LOG_FATAL(msg_fatal, NO_ARG); restore_stdout(buf_stdout, BUFSIZ); restore_stderr(buf_stderr, BUFSIZ); #define EXPECTS_ONLY_STDOUT(msg) \ if (strstr(buf_stdout, msg) == NULL) { \ TEST_FAIL_MESSAGE("can't find " #msg " message in STDOUT"); \ } \ if (strstr(buf_stderr, msg) != NULL) { \ TEST_FAIL_MESSAGE("found " #msg " message unexpectedly STDERR"); \ } #define EXPECTS_ONLY_STDERR(msg) \ if (strstr(buf_stderr, msg) == NULL) { \ TEST_FAIL_MESSAGE("can't find " #msg " message in STDERR"); \ } \ if (strstr(buf_stdout, msg) != NULL) { \ TEST_FAIL_MESSAGE("found " #msg " message unexpectedly STDOUT"); \ } #define EXPECTS_NEITHER(msg) \ if (strstr(buf_stdout, msg) != NULL) { \ TEST_FAIL_MESSAGE("found " #msg " message unexpectedly STDOUT"); \ } \ if (strstr(buf_stderr, msg) != NULL) { \ TEST_FAIL_MESSAGE("found " #msg " message unexpectedly STDERR"); \ } switch (loglvl) { case (LOGLEVEL_TRACE): EXPECTS_ONLY_STDOUT(msg_trace); EXPECTS_ONLY_STDOUT(msg_debug); EXPECTS_ONLY_STDOUT(msg_info); EXPECTS_ONLY_STDOUT(msg_warn); EXPECTS_ONLY_STDERR(msg_error); EXPECTS_ONLY_STDERR(msg_fatal); break; case (LOGLEVEL_DEBUG): EXPECTS_NEITHER(msg_trace); EXPECTS_ONLY_STDOUT(msg_debug); EXPECTS_ONLY_STDOUT(msg_info); EXPECTS_ONLY_STDOUT(msg_warn); EXPECTS_ONLY_STDERR(msg_error); EXPECTS_ONLY_STDERR(msg_fatal); break; case (LOGLEVEL_INFO): EXPECTS_NEITHER(msg_trace); EXPECTS_NEITHER(msg_debug); EXPECTS_ONLY_STDOUT(msg_info); EXPECTS_ONLY_STDOUT(msg_warn); EXPECTS_ONLY_STDERR(msg_error); EXPECTS_ONLY_STDERR(msg_fatal); break; case (LOGLEVEL_WARN): EXPECTS_NEITHER(msg_trace); EXPECTS_NEITHER(msg_debug); EXPECTS_NEITHER(msg_info); EXPECTS_ONLY_STDOUT(msg_warn); EXPECTS_ONLY_STDERR(msg_error); EXPECTS_ONLY_STDERR(msg_fatal); break; case (LOGLEVEL_ERROR): EXPECTS_NEITHER(msg_trace); EXPECTS_NEITHER(msg_debug); EXPECTS_NEITHER(msg_info); EXPECTS_NEITHER(msg_warn); EXPECTS_ONLY_STDERR(msg_error); EXPECTS_ONLY_STDERR(msg_fatal); break; case (LOGLEVEL_FATAL): EXPECTS_NEITHER(msg_trace); EXPECTS_NEITHER(msg_debug); EXPECTS_NEITHER(msg_info); EXPECTS_NEITHER(msg_warn); EXPECTS_NEITHER(msg_error); EXPECTS_ONLY_STDERR(msg_fatal); break; case (LOGLEVEL_OFF): EXPECTS_NEITHER(msg_trace); EXPECTS_NEITHER(msg_debug); EXPECTS_NEITHER(msg_info); EXPECTS_NEITHER(msg_warn); EXPECTS_NEITHER(msg_error); EXPECTS_NEITHER(msg_fatal); break; default: TEST_FAIL_MESSAGE_FORMATTED("Invalid log level %u", loglvl); } } void test_off(void) { try_log(LOGLEVEL_OFF); } void test_fatal(void) { try_log(LOGLEVEL_FATAL); } void test_err0r(void) { try_log(LOGLEVEL_ERROR); } // "error" confuses jenkins void test_warn(void) { try_log(LOGLEVEL_WARN); } void test_info(void) { try_log(LOGLEVEL_INFO); } void test_debug(void) { try_log(LOGLEVEL_DEBUG); } void test_trace(void) { try_log(LOGLEVEL_TRACE); } // log_module with only "testDriver_logger.c" in it void test_in_logmodule() { log_level = LOGLEVEL_INFO; strncpy(log_module, __FILE__, LOGMODULE_SIZE); char buf_stdout[BUFSIZ] = {0}; stdout_to_pipe(); LOG_INFO(msg_info, NO_ARG); restore_stdout(buf_stdout, BUFSIZ); if (strstr(buf_stdout, msg_info) == NULL) { TEST_FAIL_MESSAGE("can't find message message in STDOUT"); } fflush(stdout); } // log_module with "testDriver_logger.c" somewhere in the string void test_in_logmodule2() { log_level = LOGLEVEL_INFO; strncpy(log_module, "fafafa.c " __FILE__ " lalala.c", LOGMODULE_SIZE); char buf_stdout[BUFSIZ] = {0}; stdout_to_pipe(); LOG_INFO(msg_info, NO_ARG); restore_stdout(buf_stdout, BUFSIZ); if (strstr(buf_stdout, msg_info) == NULL) { TEST_FAIL_MESSAGE("can't find message message in STDOUT"); } fflush(stdout); } // log_module with "testDriver_logger.c" completely not in void test_not_in_logmodule() { log_level = LOGLEVEL_INFO; strncpy(log_module, "hahahahaha.c", LOGMODULE_SIZE); char buf_stdout[BUFSIZ] = {0}; stdout_to_pipe(); LOG_INFO(msg_info, NO_ARG); restore_stdout(buf_stdout, BUFSIZ); if (strstr(buf_stdout, msg_info) != NULL) { TEST_FAIL_MESSAGE("found message unexpectedly STDOUT"); } fflush(stdout); } int main(void) { UNITY_BEGIN(); // logger in full form only when ZDNN_CONFIG_DEBUG is on #ifdef ZDNN_CONFIG_DEBUG RUN_TEST(test_trace); RUN_TEST(test_debug); RUN_TEST(test_info); RUN_TEST(test_warn); RUN_TEST(test_err0r); RUN_TEST(test_fatal); RUN_TEST(test_off); RUN_TEST(test_in_logmodule); RUN_TEST(test_in_logmodule2); RUN_TEST(test_not_in_logmodule); #endif return UNITY_END(); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_malloc4k.c��������������������������������������������������������������0000664�0000000�0000000�00000005261�14364043643�0017564�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ } void tearDown(void) {} // test 0-byte allocation void malloc4k_zero() { void *ptr = malloc_aligned_4k(0); TEST_ASSERT_MESSAGE( ptr == NULL, "malloc_aligned_4k() returned non-zero for 0-byte allocation"); } // test absolute hardware max + 1 byte allocation // SIZE_MAX is 18446744073709551615UL (2^64) void malloc4k_size_max_plus_one() { void *ptr = malloc_aligned_4k(SIZE_MAX + 1); TEST_ASSERT_MESSAGE( ptr == NULL, "malloc_aligned_4k() returned non-zero SIZE_MAX+1 bytes allocation"); } // test different happy-path allocation sizes and make sure the return address // is on 4k boundary void malloc4k_check_boundary() { #define PLUS_AND_MINUS 2 // 1K, 4K, 32K, 64K, 256K, 1M, 1G, 2G // 5 allocations (-2, -1, +0, +1, +2) of each unsigned int allocations[] = {1, 4, 32, 64, 256, 1024, 1024 * 1024, 2 * 1024 * 1024}; for (int i = 0; i < sizeof(allocations) / sizeof(allocations[0]); i++) { for (size_t j = allocations[i] * 1024 - PLUS_AND_MINUS; j <= allocations[i] * 1024 + PLUS_AND_MINUS; j++) { void *ptr = malloc_aligned_4k(j); LOG_DEBUG( "malloc_aligned_4k() returned location = %016lx\n, size = %zu\n", (uintptr_t)ptr, j); TEST_ASSERT_MESSAGE_FORMATTED( ptr, "detected NULL return from malloc_aligned_4k(), size = %zu, " "location = %016lx\n", j, (uintptr_t)ptr); TEST_ASSERT_MESSAGE_FORMATTED( !((uintptr_t)ptr % AIU_PAGESIZE_IN_BYTES), "detected non-4k aligned return from malloc_aligned_4k(), size = " "%zu, " "location = %016lx\n", j, (uintptr_t)ptr); free_aligned_4k(ptr); } } TEST_PASS(); } int main(void) { UNITY_BEGIN(); RUN_TEST(malloc4k_zero); RUN_TEST(malloc4k_size_max_plus_one); RUN_TEST(malloc4k_check_boundary); return UNITY_END(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_nnpa_parm_block.c�������������������������������������������������������0000664�0000000�0000000�00000037700�14364043643�0021206�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <math.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> // Query block offsets #define INSTALLED_FUNCTIONS_VECTOR_OFFSET 0 #define INSTALLED_PARAMETER_BLOCK_FORMATS_OFFSET 32 #define INSTALLED_DATA_TYPES_OFFSET 48 #define QAF_RESERVED_1_OFFSET 50 #define INSTALLED_DATA_LAYOUT_FORMATS_OFFSET 52 #define QAF_RESERVED_2_OFFSET 56 #define MAXIMUM_DIMENSION_INDEX_SIZE_OFFSET 60 #define MAXIMUM_TENSOR_SIZE_OFFSET 64 #define INSTALLED_DT1_CONVERSIONS_VECTOR_OFFSET 72 #define QAF_RESERVED_3_OFFSET 74 // Standard NNPA block offsets #define PARM_BLOCK_VERSION_NUMBER_OFFSET 0 #define MODEL_VERSION_NUMBER_OFFSET 2 #define NNPA_RESERVED_FOR_IBM 3 #define NNPA_RESERVED_1_OFFSET 6 #define NNPA_RESERVED_2_OFFSET 8 #define FUNC_SPECIFIC_SAVE_AREA_ADDR_OFFSET 56 #define OUTPUT_TENSOR_DESC_1_OFFSET 64 #define OUTPUT_TENSOR_DESC_2_OFFSET 96 #define NNPA_RESERVED_3_OFFSET 128 #define INPUT_TENSOR_DESC_1_OFFSET 192 #define INPUT_TENSOR_DESC_2_OFFSET 224 #define INPUT_TENSOR_DESC_3_OFFSET 256 #define NNPA_RESERVED_4_OFFSET 288 #define FUNCTION_SPECIFIC_PARM_1 384 #define FUNCTION_SPECIFIC_PARM_2 388 #define FUNCTION_SPECIFIC_PARM_3 392 #define FUNCTION_SPECIFIC_PARM_4 396 #define FUNCTION_SPECIFIC_PARM_5 400 #define NNPA_RESERVED_5_OFFSET 404 #define CSB_OFFSET 512 void setUp(void) {} void tearDown(void) {} /* * Verify that the tensor descriptor was updated with the correct * information from the ztensor. invalid_type set when testing for invalid * data_type. */ void verify_populate_descriptor(nnpa_tensor_descriptor *descriptor, zdnn_ztensor *ztensor) { LOG_DEBUG("Verifying descriptor", NO_ARG); TEST_ASSERT_EQUAL_UINT8_MESSAGE(ztensor->transformed_desc->format, descriptor->data_layout_format, "Incorrect data layout format."); TEST_ASSERT_EQUAL_UINT32_MESSAGE(ztensor->transformed_desc->dim4, descriptor->dim4_index_size, "Incorrect dim4 index size"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(ztensor->transformed_desc->dim3, descriptor->dim3_index_size, "Incorrect dim3 index size"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(ztensor->transformed_desc->dim2, descriptor->dim2_index_size, "Incorrect dim2 index size"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(ztensor->transformed_desc->dim1, descriptor->dim1_index_size, "Incorrect dim1 index size"); TEST_ASSERT_EQUAL_UINT64_MESSAGE(ztensor->buffer, descriptor->tensor_data_addr, "Incorrect tensor pointer"); } /* * Common routine for driving all x-inputs y-outputs testcases * variadic parameters are input dims followed by output dims, which the * dims are in {outermost, ..., innermost} order */ void populate_x_inputs_y_outputs(uint8_t num_inputs, uint8_t num_outputs, zdnn_data_types type, ...) { // Allocate and initialize our nnpa_parm_blocks nnpa_parameter_block parm_block; nnpa_parameter_block parm_block_all; zdnn_ztensor input_ztensor[num_inputs], output_ztensor[num_outputs]; int dummy; // something for ztensor.buffer to point to va_list ap; va_start(ap, type); // variadic: input dim arrays then output dim arrays for (int i = 0; i < num_inputs; i++) { uint32_t *dims = va_arg(ap, uint32_t *); input_ztensor[i].transformed_desc = malloc(sizeof(zdnn_tensor_desc)); // dims[0] is the outermost dimension init_transformed_desc(ZDNN_NHWC, type, ZDNN_FORMAT_4DFEATURE, input_ztensor[i].transformed_desc, dims[0], dims[1], dims[2], dims[3]); input_ztensor[i].buffer = &dummy; } for (int i = 0; i < num_outputs; i++) { uint32_t *dims = va_arg(ap, uint32_t *); output_ztensor[i].transformed_desc = malloc(sizeof(zdnn_tensor_desc)); init_transformed_desc(ZDNN_NHWC, type, ZDNN_FORMAT_4DFEATURE, output_ztensor[i].transformed_desc, dims[0], dims[1], dims[2], dims[3]); output_ztensor[i].buffer = &dummy; } va_end(ap); populate_nnpa_parm_block( &parm_block_all, &input_ztensor[0], (num_inputs > 1) ? &input_ztensor[1] : NULL, (num_inputs > 2) ? &input_ztensor[2] : NULL, &output_ztensor[0], (num_outputs > 1) ? &output_ztensor[1] : NULL, 0, 0, 0, 0, 0, 0); // treat parm_block->input_tensor1/2/3 as if an array so we can loop them nnpa_tensor_descriptor *block_input_ptr = &(parm_block.input_tensor1); nnpa_tensor_descriptor *block_all_input_ptr = &(parm_block_all.input_tensor1); for (int i = 0; i < num_inputs; i++) { populate_descriptor(block_input_ptr + i, &input_ztensor[i]); verify_populate_descriptor(block_all_input_ptr + i, &input_ztensor[i]); verify_populate_descriptor(block_input_ptr + i, &input_ztensor[i]); } nnpa_tensor_descriptor *block_output_ptr = &(parm_block.output_tensor1); nnpa_tensor_descriptor *block_all_output_ptr = &(parm_block_all.output_tensor1); for (int i = 0; i < num_outputs; i++) { populate_descriptor(block_output_ptr + i, &output_ztensor[i]); verify_populate_descriptor(block_all_output_ptr + i, &output_ztensor[i]); verify_populate_descriptor(block_output_ptr + i, &output_ztensor[i]); } for (int i = 0; i < num_inputs; i++) { free(input_ztensor[i].transformed_desc); } for (int i = 0; i < num_outputs; i++) { free(output_ztensor[i].transformed_desc); } } /* * Test to ensure using either populate_descriptor or populate_all_descriptor * updates the nnpa parm block appropriately for 1 input tensor */ void populate_single_input() { uint32_t shape[ZDNN_MAX_DIMS] = {1, 1, 1, 3}; populate_x_inputs_y_outputs(1, 1, ZDNN_DLFLOAT16, shape, shape); } /* * Test to ensure using either populate_descriptor or populate_all_descriptor * updates the nnpa parm block appropriately for 1 input tensor and 2 output * tensors */ void populate_single_input_double_output() { uint32_t shape[ZDNN_MAX_DIMS] = {1, 1, 1, 3}; populate_x_inputs_y_outputs(1, 2, ZDNN_DLFLOAT16, shape, shape, shape); } /* * Test to ensure using either populate_descriptor or populate_all_descriptor * updates the nnpa parm block appropriately for 2 input tensors */ void populate_double_input() { unsigned int input_dims[ZDNN_MAX_DIMS] = {4, 2, 1, 3}; unsigned int output_dims[ZDNN_MAX_DIMS] = {2, 1, 5, 2}; populate_x_inputs_y_outputs(2, 1, ZDNN_DLFLOAT16, input_dims, input_dims, output_dims); } /* * Test to ensure using either populate_descriptor or populate_all_descriptor * updates the nnpa parm block appropriately for 3 input tensors */ void populate_triple_input() { unsigned int input_dims[ZDNN_MAX_DIMS] = {5, 3, 1, 1}; unsigned int output_dims[ZDNN_MAX_DIMS] = {8, 1, 2, 4}; populate_x_inputs_y_outputs(3, 1, ZDNN_DLFLOAT16, input_dims, input_dims, input_dims, output_dims); } /** * Function to verify the offsets of each element in a nnpa_parameter_block * struct. * * Parameter block offsets: * Bytes: Name: 0-1 PBVN 2 MVN 3-5 RIBM 6-7 Reserved (1-bit Continuation Flag at end) 8-55 Reserved 56-63 Function-specific-save-area-address 64-95 Output Tensor Descriptor 1 96-127 Output Tensor Descriptor 2 128-191 Reserved 192-223 Input Tensor Descriptor 1 224-255 Input Tensor Descriptor 2 256-287 Input Tensor Descriptor 3 288-383 Reserved 384-387 Function-specific-parameter-1 388-391 Function-specific-parameter-2 392-295 Function-specific-parameter-3 396-399 Function-specific-parameter-4 400-403 Function-specific-parameter-5 404-511 Reserved 512-4088 CSB */ void verify_parm_block_offsets() { TEST_ASSERT_EQUAL_MESSAGE( PARM_BLOCK_VERSION_NUMBER_OFFSET, offsetof(nnpa_parameter_block, parm_block_version_number), "parm_block_version in nnpa_parameter_block has incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( MODEL_VERSION_NUMBER_OFFSET, offsetof(nnpa_parameter_block, model_version_number), "model_version in nnpa_parameter_block has incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( NNPA_RESERVED_1_OFFSET, offsetof(nnpa_parameter_block, reserved1), "reserved1 in nnpa_parameter_block has incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( NNPA_RESERVED_2_OFFSET, offsetof(nnpa_parameter_block, reserved2), "reserved2 in nnpa_parameter_block has incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( FUNC_SPECIFIC_SAVE_AREA_ADDR_OFFSET, offsetof(nnpa_parameter_block, function_specific_save_area_address), "function_specific_save_area_address in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(OUTPUT_TENSOR_DESC_1_OFFSET, offsetof(nnpa_parameter_block, output_tensor1), "output_tensor1 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(OUTPUT_TENSOR_DESC_2_OFFSET, offsetof(nnpa_parameter_block, output_tensor2), "output_tensor2 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(NNPA_RESERVED_3_OFFSET, offsetof(nnpa_parameter_block, reserved3), "reserved3 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(INPUT_TENSOR_DESC_1_OFFSET, offsetof(nnpa_parameter_block, input_tensor1), "input_tensor1 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(INPUT_TENSOR_DESC_2_OFFSET, offsetof(nnpa_parameter_block, input_tensor2), "input_tensor2 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(INPUT_TENSOR_DESC_3_OFFSET, offsetof(nnpa_parameter_block, input_tensor3), "input_tensor3 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(NNPA_RESERVED_4_OFFSET, offsetof(nnpa_parameter_block, reserved4), "reserved4 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( FUNCTION_SPECIFIC_PARM_1, offsetof(nnpa_parameter_block, function_specific_parm1), "function_specific_parm1 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( FUNCTION_SPECIFIC_PARM_2, offsetof(nnpa_parameter_block, function_specific_parm2), "function_specific_parm2 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( FUNCTION_SPECIFIC_PARM_3, offsetof(nnpa_parameter_block, function_specific_parm3), "function_specific_parm3 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( FUNCTION_SPECIFIC_PARM_4, offsetof(nnpa_parameter_block, function_specific_parm4), "function_specific_parm4 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( FUNCTION_SPECIFIC_PARM_5, offsetof(nnpa_parameter_block, function_specific_parm5), "function_specific_parm5 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(NNPA_RESERVED_5_OFFSET, offsetof(nnpa_parameter_block, reserved5), "reserved5 in nnpa_parameter_block has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( CSB_OFFSET, offsetof(nnpa_parameter_block, continuation_state_buffer), "continuation_state_buffer in nnpa_parameter_block has " "incorrect offset"); } /** * Function to verify the offsets of each element in a * aiu_parameter_block_nnpa_qaf struct. * * Parameter block offsets: * Bytes: Name: 0-31 installed_functions_vector; 32-47 installed_parameter_block_formats; 48-49 installed_data_types; 50-51 reserved1[2] 52-55 installed_data_layout_formats; 56-59 reserved2[4]; 60-63 maximum_dimension_index_size; 64-71 maximum_tensor_size; 72-73 installed_dt1_conversions_vector 74-95 reserved3[16]; */ void verify_qaf_parm_block_offsets() { TEST_ASSERT_EQUAL_MESSAGE( INSTALLED_FUNCTIONS_VECTOR_OFFSET, offsetof(nnpa_qaf_parameter_block, installed_functions_vector), "installed_functions_vector in aiu_parameter_block_nnpa_qaf has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( INSTALLED_PARAMETER_BLOCK_FORMATS_OFFSET, offsetof(nnpa_qaf_parameter_block, installed_parameter_block_formats), "reserved1 in aiu_parameter_block_nnpa_qaf has incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( INSTALLED_DATA_TYPES_OFFSET, offsetof(nnpa_qaf_parameter_block, installed_data_types), "installed_data_type in aiu_parameter_block_nnpa_qaf has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( QAF_RESERVED_1_OFFSET, offsetof(nnpa_qaf_parameter_block, reserved1), "installed_parameter_block_formats in aiu_parameter_block_nnpa_qaf has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( INSTALLED_DATA_LAYOUT_FORMATS_OFFSET, offsetof(nnpa_qaf_parameter_block, installed_data_layout_formats), "installed_data_layout_formats in aiu_parameter_block_nnpa_qaf has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(QAF_RESERVED_2_OFFSET, offsetof(nnpa_qaf_parameter_block, reserved2), "reserved2 in aiu_parameter_block_nnpa_qaf has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( MAXIMUM_DIMENSION_INDEX_SIZE_OFFSET, offsetof(nnpa_qaf_parameter_block, maximum_dimension_index_size), "maximum_dimension_index_size in aiu_parameter_block_nnpa_qaf has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( MAXIMUM_TENSOR_SIZE_OFFSET, offsetof(nnpa_qaf_parameter_block, maximum_tensor_size), "maximum_tensor_size in aiu_parameter_block_nnpa_qaf has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE( INSTALLED_DT1_CONVERSIONS_VECTOR_OFFSET, offsetof(nnpa_qaf_parameter_block, installed_dt1_conversions_vector), "installed_dt1_conversions_vector in aiu_parameter_block_nnpa_qaf has " "incorrect offset"); TEST_ASSERT_EQUAL_MESSAGE(QAF_RESERVED_3_OFFSET, offsetof(nnpa_qaf_parameter_block, reserved3), "reserved3 in aiu_parameter_block_nnpa_qaf has " "incorrect offset"); } int main() { UNITY_BEGIN(); RUN_TEST(populate_single_input); RUN_TEST(populate_single_input_double_output); RUN_TEST(populate_double_input); RUN_TEST(populate_triple_input); RUN_TEST(verify_parm_block_offsets); RUN_TEST(verify_qaf_parm_block_offsets); return UNITY_END(); } ����������������������������������������������������������������zDNN-1.0.1/tests/testDriver_precheck.c��������������������������������������������������������������0000664�0000000�0000000�00000024343�14364043643�0017644�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <stdio.h> #include <stdlib.h> #include <string.h> zdnn_ztensor ztensor_input1, ztensor_input2, ztensor_input3, ztensor_output1, ztensor_output2; zdnn_tensor_desc pre_tfrmd_desc, input1_tfrmd_desc, input2_tfrmd_desc, input3_tfrmd_desc, output1_tfrmd_desc, output2_tfrmd_desc; void create_garbage_tensors(); void setUp(void) { /* This is run before EACH TEST */ create_garbage_tensors(); } void tearDown(void) {} /********************************************************************* * The goal is to verify if the verifier routine is invoked when * precheck_enabled = true, not if the verifier routine returns the * correct status code (which is testDriver_tensor_verify*.c's job). * * On environment equipped with AIU, all testcases will cause program * termination due to DXG rather than issuing a non-ZDNN_OK status. * *******************************************************************/ /// Create garbage input/output tensors that are guaranteed to fail any AIU op void create_garbage_tensors() { precheck_enabled = true; uint32_t dim4 = 1, dim3 = 1, dim2 = 1, dim1 = 1; zdnn_data_layouts layout = ZDNN_NHWC; zdnn_data_types type = FP16; zdnn_init_pre_transformed_desc(layout, type, &pre_tfrmd_desc, dim4, dim3, dim2, dim1); // all inputs and outputs same shape zdnn_generate_transformed_desc(&pre_tfrmd_desc, &input1_tfrmd_desc); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &input2_tfrmd_desc); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &input3_tfrmd_desc); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &output1_tfrmd_desc); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &output2_tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &input1_tfrmd_desc, &ztensor_input1); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &input2_tfrmd_desc, &ztensor_input2); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &input3_tfrmd_desc, &ztensor_input3); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &output1_tfrmd_desc, &ztensor_output1); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &output2_tfrmd_desc, &ztensor_output2); // all input tensors are features, all output tensors are kernels. ztensor_output1.transformed_desc->format = ZDNN_FORMAT_4DKERNEL; ztensor_output2.transformed_desc->format = ZDNN_FORMAT_4DKERNEL; } void bad_element_wise() { zdnn_status status = zdnn_add(&ztensor_input1, &ztensor_input2, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED(status != ZDNN_OK, "Expected failure status but got %d \"%s\"", status, zdnn_get_status_message(status)); } void bad_batchnorm() { zdnn_status status = zdnn_batchnorm(&ztensor_input1, &ztensor_input2, &ztensor_input3, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED(status != ZDNN_OK, "Expected failure status but got %d \"%s\"", status, zdnn_get_status_message(status)); } void bad_lstm() { // ZDNN_INVALID_SHAPE because all dims are 1s zdnn_status exp_status = ZDNN_INVALID_SHAPE; zdnn_status status = zdnn_lstm(&ztensor_input1, &ztensor_input2, &ztensor_input3, &ztensor_input1, &ztensor_input2, &ztensor_input3, &ztensor_input1, FWD, NULL, &ztensor_output1, &ztensor_output2); TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status, "Got status %d \"%s\" but expected %d \"%s\"", status, zdnn_get_status_message(status), exp_status, (zdnn_get_status_message(exp_status))); } void bad_matmul_op_with_bias_addition() { zdnn_status status = zdnn_matmul_op(&ztensor_input1, &ztensor_input2, &ztensor_input3, MATMUL_OP_ADDITION, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED(status != ZDNN_OK, "Expected failure status but got %d \"%s\"", status, zdnn_get_status_message(status)); } void bad_matmul_bcast_op_with_bias_addition() { zdnn_status status = zdnn_matmul_bcast_op(&ztensor_input1, &ztensor_input2, &ztensor_input3, MATMUL_BCAST_OP_ADDITION, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED(status != ZDNN_OK, "Expected failure status but got %d \"%s\"", status, zdnn_get_status_message(status)); } void bad_pool() { zdnn_status status = zdnn_avgpool2d(&ztensor_input1, 1, 1, 1, 1, 1, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED(status != ZDNN_OK, "Expected failure status but got %d \"%s\"", status, zdnn_get_status_message(status)); } void negative_relu_clipping() { VERIFY_HW_ENV; // zdnn_relu drives HW conversion before precheck ztensor_output1.transformed_desc->format = ZDNN_FORMAT_4DFEATURE; zdnn_status exp_status = ZDNN_INVALID_CLIPPING_VALUE; float clip_value = -1; zdnn_status status = zdnn_relu(&ztensor_input1, (void *)&clip_value, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status, "Got status %d \"%s\" but expected %d \"%s\"", status, zdnn_get_status_message(status), exp_status, (zdnn_get_status_message(exp_status))); } void nan_relu_clipping() { VERIFY_HW_ENV; // zdnn_relu drives HW conversion before precheck ztensor_output1.transformed_desc->format = ZDNN_FORMAT_4DFEATURE; zdnn_status exp_status = ZDNN_INVALID_CLIPPING_VALUE; uint32_t clip_value = 0x7FFFFFFF; zdnn_status status = zdnn_relu(&ztensor_input1, (void *)&clip_value, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status, "Got status %d \"%s\" but expected %d \"%s\"", status, zdnn_get_status_message(status), exp_status, (zdnn_get_status_message(exp_status))); } void negative_nan_relu_clipping() { VERIFY_HW_ENV; // zdnn_relu drives HW conversion before precheck ztensor_output1.transformed_desc->format = ZDNN_FORMAT_4DFEATURE; zdnn_status exp_status = ZDNN_INVALID_CLIPPING_VALUE; uint32_t clip_value = 0xFFFFFFFF; zdnn_status status = zdnn_relu(&ztensor_input1, (void *)&clip_value, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status, "Got status %d \"%s\" but expected %d \"%s\"", status, zdnn_get_status_message(status), exp_status, (zdnn_get_status_message(exp_status))); } // Make all tensor and other values correct. void setup_conv2d_tensors() { ztensor_output1.transformed_desc->format = ZDNN_FORMAT_4DFEATURE; ztensor_input1.transformed_desc->dim4 = 1; ztensor_input1.transformed_desc->dim3 = 4; ztensor_input1.transformed_desc->dim2 = 3; ztensor_input1.transformed_desc->dim1 = 5; ztensor_input2.transformed_desc->dim4 = 2; ztensor_input2.transformed_desc->dim3 = 2; ztensor_input2.transformed_desc->dim2 = 5; ztensor_input2.transformed_desc->dim1 = 2; ztensor_input3.transformed_desc->dim4 = 1; ztensor_input3.transformed_desc->dim3 = 1; ztensor_input3.transformed_desc->dim2 = 1; ztensor_input3.transformed_desc->dim1 = 2; ztensor_output1.transformed_desc->dim4 = 1; ztensor_output1.transformed_desc->dim3 = 3; ztensor_output1.transformed_desc->dim2 = 2; ztensor_output1.transformed_desc->dim1 = 2; } void negative_conv2d_clipping() { VERIFY_HW_ENV; // zdnn_conv2d drives HW conversion before precheck setup_conv2d_tensors(); zdnn_status exp_status = ZDNN_INVALID_CLIPPING_VALUE; float clip_value = -1; zdnn_status status = zdnn_conv2d( &ztensor_input1, &ztensor_input2, &ztensor_input3, VALID_PADDING, 1, 1, CONV2D_ACT_RELU, (void *)&clip_value, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status, "Got status %d \"%s\" but expected %d \"%s\"", status, zdnn_get_status_message(status), exp_status, (zdnn_get_status_message(exp_status))); } void nan_conv2d_clipping() { VERIFY_HW_ENV; // zdnn_conv2d drives HW conversion before precheck setup_conv2d_tensors(); zdnn_status exp_status = ZDNN_INVALID_CLIPPING_VALUE; uint32_t clip_value = 0x7FFFFFFF; zdnn_status status = zdnn_conv2d( &ztensor_input1, &ztensor_input2, &ztensor_input3, VALID_PADDING, 1, 1, CONV2D_ACT_RELU, (void *)&clip_value, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status, "Got status %d \"%s\" but expected %d \"%s\"", status, zdnn_get_status_message(status), exp_status, (zdnn_get_status_message(exp_status))); } void negative_nan_conv2d_clipping() { VERIFY_HW_ENV; // zdnn_conv2d drives HW conversion before precheck setup_conv2d_tensors(); zdnn_status exp_status = ZDNN_INVALID_CLIPPING_VALUE; uint32_t clip_value = 0xFFFFFFFF; zdnn_status status = zdnn_conv2d( &ztensor_input1, &ztensor_input2, &ztensor_input3, VALID_PADDING, 1, 1, CONV2D_ACT_RELU, (void *)&clip_value, &ztensor_output1); TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status, "Got status %d \"%s\" but expected %d \"%s\"", status, zdnn_get_status_message(status), exp_status, (zdnn_get_status_message(exp_status))); } int main() { UNITY_BEGIN(); RUN_TEST(bad_element_wise); RUN_TEST(bad_batchnorm); RUN_TEST(bad_lstm); RUN_TEST(bad_matmul_op_with_bias_addition); RUN_TEST(bad_matmul_bcast_op_with_bias_addition); RUN_TEST(bad_pool); RUN_TEST(negative_relu_clipping); RUN_TEST(nan_relu_clipping); RUN_TEST(negative_nan_relu_clipping); RUN_TEST(negative_conv2d_clipping); RUN_TEST(nan_conv2d_clipping); RUN_TEST(negative_nan_conv2d_clipping); return UNITY_END(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_query.c�����������������������������������������������������������������0000664�0000000�0000000�00000012250�14364043643�0017217�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <stdio.h> #define NNPA_OP_FAKE 255 #define NNPA_PARMBLKFORMAT_FAKE 127 #define QUERY_DATATYPE_FAKE (1 << 0) #define QUERY_LAYOUTFMT_FAKE (1 << 0) #define QUERY_BFPFMT_FAKE (1 << 0) void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} void test_function_available() { TEST_ASSERT_MESSAGE( zdnn_is_nnpa_function_installed(3, NNPA_ADD, NNPA_BATCHNORMALIZATION, NNPA_SOFTMAX) == true, "One or more of the requested functions is not detected as available"); } void test_function_not_available() { TEST_ASSERT_MESSAGE(zdnn_is_nnpa_function_installed(3, NNPA_ADD, NNPA_BATCHNORMALIZATION, NNPA_OP_FAKE) == false, "NNPA_OP_FAKE is not detected as unavailable"); } void test_parm_blk_fmt_installed() { TEST_ASSERT_MESSAGE( zdnn_is_nnpa_parmblk_fmt_installed(1, NNPA_PARMBLKFORMAT_0) == true, "NNPA_PARMBLKFORMAT_TENSORDESC is not detected as available"); } void test_parm_blk_fmt_not_installed() { TEST_ASSERT_MESSAGE( zdnn_is_nnpa_parmblk_fmt_installed(2, NNPA_PARMBLKFORMAT_FAKE, NNPA_PARMBLKFORMAT_0) == false, "NNPA_PARMBLKFORMAT_FAKE is not detected as unavailable"); } void test_datatype_installed() { TEST_ASSERT_MESSAGE( zdnn_is_nnpa_datatype_installed(QUERY_DATATYPE_INTERNAL1) == true, "NNPA_QAF_DATATYPE_INTERNAL1 is not detected as available"); } void test_datatype_not_installed() { TEST_ASSERT_MESSAGE(zdnn_is_nnpa_datatype_installed(QUERY_DATATYPE_INTERNAL1 | QUERY_DATATYPE_FAKE) == false, "QUERY_DATATYPE_FAKE is not detected as unavailable"); } void test_datalayout_installed() { TEST_ASSERT_MESSAGE( zdnn_is_nnpa_layout_fmt_installed(QUERY_LAYOUTFMT_4DFEATURE | QUERY_LAYOUTFMT_4DKERNEL) == true, "NNPA_QAF_DATALAYOUT_4DFEATURETENSOR is not detected as available"); } void test_datalayout_not_installed() { TEST_ASSERT_MESSAGE(zdnn_is_nnpa_layout_fmt_installed( QUERY_LAYOUTFMT_4DFEATURE | QUERY_LAYOUTFMT_4DKERNEL | QUERY_LAYOUTFMT_FAKE) == false, "QUERY_LAYOUTFMT_FAKE is not detected as unavailable"); } void test_datatype_conversion_installed() { TEST_ASSERT_MESSAGE( zdnn_is_nnpa_conversion_installed( NNPA_DATATYPE_1, QUERY_BFPFMT_TINY | QUERY_BFPFMT_SHORT) == true, "QUERY_BFPFMT_TINY | QUERY_BFPFMT_SHORT is not detected as available"); } void test_datatype_conversion_not_installed() { TEST_ASSERT_MESSAGE( zdnn_is_nnpa_conversion_installed(NNPA_DATATYPE_1, QUERY_BFPFMT_TINY | QUERY_BFPFMT_SHORT | QUERY_BFPFMT_FAKE) == false, "QUERY_BFPFMT_FAKE is not detected as unavailable"); } #define MAXIMUM_DIMENSION_INDEX_SIZE ((uint32_t)1 << 15) // 32768 #define MAXIMUM_TENSOR_SIZE ((uint64_t)1 << 32) // 4294967296 void test_get_max_dim_idx_size() { TEST_ASSERT_MESSAGE_FORMATTED( zdnn_get_nnpa_max_dim_idx_size() == MAXIMUM_DIMENSION_INDEX_SIZE, "zdnn_get_nnpa_max_dim_idx_size() %u did not return %d", zdnn_get_nnpa_max_dim_idx_size(), 1); } void test_get_max_tensor_size() { TEST_ASSERT_MESSAGE_FORMATTED( zdnn_get_nnpa_max_tensor_size() == MAXIMUM_TENSOR_SIZE, "zdnn_get_nnpa_max_tensor_size() %" PRIu64 " did not return %" PRIu64, zdnn_get_nnpa_max_tensor_size(), MAXIMUM_TENSOR_SIZE); } // eyeball inspection void test_print_version() { printf("version = %04x\n", zdnn_get_library_version()); printf("version string = %s\n", zdnn_get_library_version_str()); } // ------------------------------------------------------------------------------------------------ int main(void) { UNITY_BEGIN(); RUN_TEST(test_function_available); RUN_TEST(test_function_not_available); RUN_TEST(test_parm_blk_fmt_installed); RUN_TEST(test_parm_blk_fmt_not_installed); RUN_TEST(test_datatype_installed); RUN_TEST(test_datatype_not_installed); RUN_TEST(test_datalayout_installed); RUN_TEST(test_datalayout_not_installed); RUN_TEST(test_datatype_conversion_installed); RUN_TEST(test_datatype_conversion_not_installed); RUN_TEST(test_get_max_dim_idx_size); RUN_TEST(test_get_max_tensor_size); RUN_TEST(test_print_version); return UNITY_END(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_reshape_ztensor.c�������������������������������������������������������0000664�0000000�0000000�00000024462�14364043643�0021275�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} /* * Non-error scenario general strategy: * * Create 2 tensors: * tensor A: shape (x, y, z, a) * tensor B: shape (i, j, k, b) * which (x * y * z * a) == (i * j * k * b) * * Create raw data of (x * y * z * a) elements * * Stickify raw data to tensor A's buffer * zdnn_reshape_ztensor() from tensor A to tensor B * * Compare tensor B's buffer to the raw data, element by element, using * get_stick_offset() with respect to tensor B's shape * * Compare by values due to precision loss: * A goes from FP16/FP32/BFLOAT -> DLFLOAT16, meaning * B goes from FP16/FP32/BFLOAT -> DLFLOAT16 -> FP32 -> DLFLOAT16 */ void test(zdnn_data_layouts src_layout, uint32_t src_dim4, uint32_t src_dim3, uint32_t src_dim2, uint32_t src_dim1, zdnn_data_layouts dest_layout, uint32_t dest_dim4, uint32_t dest_dim3, uint32_t dest_dim2, uint32_t dest_dim1, zdnn_status exp_status) { zdnn_status status; zdnn_tensor_desc src_pre_tfrmd_desc, dest_pre_tfrmd_desc, src_tfrmd_desc, dest_tfrmd_desc; zdnn_ztensor src_ztensor, dest_ztensor; zdnn_init_pre_transformed_desc(src_layout, test_datatype, &src_pre_tfrmd_desc, src_dim4, src_dim3, src_dim2, src_dim1); zdnn_init_pre_transformed_desc(dest_layout, test_datatype, &dest_pre_tfrmd_desc, dest_dim4, dest_dim3, dest_dim2, dest_dim1); zdnn_generate_transformed_desc(&src_pre_tfrmd_desc, &src_tfrmd_desc); zdnn_generate_transformed_desc(&dest_pre_tfrmd_desc, &dest_tfrmd_desc); status = zdnn_init_ztensor_with_malloc(&src_pre_tfrmd_desc, &src_tfrmd_desc, &src_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc() (src) failed, status = %08x", status); void *raw_data = create_and_fill_random_fp_data(&src_ztensor); status = zdnn_init_ztensor_with_malloc(&dest_pre_tfrmd_desc, &dest_tfrmd_desc, &dest_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc() (dest) failed, status = %08x", status); status = zdnn_transform_ztensor(&src_ztensor, raw_data); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_transform_ztensor() failed, status = %08x", status); status = zdnn_reshape_ztensor(&src_ztensor, &dest_ztensor); if (exp_status == ZDNN_OK) { TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_reshape_ztensor() failed, status = %08x", status); uint64_t raw_offset = 0; uint64_t cnt = 0; for (uint32_t i = 0; i < dest_dim4; i++) { for (uint32_t j = 0; j < dest_dim3; j++) { for (uint32_t k = 0; k < dest_dim2; k++) { for (uint32_t b = 0; b < dest_dim1; b++) { uint64_t dest_offset = get_stick_offset(i, j, k, b, &dest_tfrmd_desc); uint16_t raw_dlf16_val = 0; // this is the "expected" value uint16_t dest_dlf16_val = *(uint16_t *)((uintptr_t)dest_ztensor.buffer + dest_offset); // these 2 are for printf-ing only float raw_float_val = 0; float dest_float_val = cnvt_1_dlf16_to_fp32(dest_dlf16_val); if (test_datatype == BFLOAT) { raw_float_val = cnvt_1_bfloat_to_fp32( *(uint16_t *)((uintptr_t)raw_data + raw_offset)); raw_dlf16_val = cnvt_1_bfloat_to_dlf16( *(uint16_t *)((uintptr_t)raw_data + raw_offset)); } else if (test_datatype == FP16) { raw_float_val = cnvt_1_fp16_to_fp32( *(uint16_t *)((uintptr_t)raw_data + raw_offset)); raw_dlf16_val = cnvt_1_fp16_to_dlf16( *(uint16_t *)((uintptr_t)raw_data + raw_offset)); } else if (test_datatype == FP32) { raw_float_val = *(float *)((uintptr_t)raw_data + raw_offset); raw_dlf16_val = cnvt_1_fp32_to_dlf16(raw_float_val); } TEST_ASSERT_MESSAGE_FORMATTED( almost_equal_dlf16(dest_dlf16_val, raw_dlf16_val), "Incorrect value at element %" PRIu64 ": Expected: %.6f, Found (offset %" PRIu64 "): %.6f", cnt, raw_float_val, dest_offset, dest_float_val); raw_offset += get_data_type_size(test_datatype); cnt++; } } } } } else { TEST_ASSERT_MESSAGE_FORMATTED(exp_status == status, "expected status = %08x, got status = %08x", exp_status, status); } free(raw_data); } // N/H/W/C all the same (memcpy whole buffer) void test_4x5x6x7_4x5x6x7() { test(ZDNN_NHWC, 4, 5, 6, 7, ZDNN_NHWC, 4, 5, 6, 7, ZDNN_OK); } // same C, different N/H/W (sticks memcpy) void test_1x2x3x4_6x1x1x4() { test(ZDNN_NHWC, 1, 2, 3, 4, ZDNN_NHWC, 6, 1, 1, 4, ZDNN_OK); } // same C, different N/H/W, more elements (sticks memcpy) void test_2x3x4x68_4x1x6x68() { test(ZDNN_NHWC, 2, 3, 4, 68, ZDNN_NHWC, 4, 1, 6, 68, ZDNN_OK); } // same C, different N/H/W, even more elements (sticks memcpy) void test_4x3x40x70_8x20x3x70() { test(ZDNN_NHWC, 2, 3, 4, 68, ZDNN_NHWC, 4, 1, 6, 68, ZDNN_OK); } // N/H/W/C all different void test_4x4x4x4_1x1x16x16() { test(ZDNN_NHWC, 4, 4, 4, 4, ZDNN_NHWC, 1, 1, 16, 16, ZDNN_OK); } void test_fail_total_elements_mismatch() { test(ZDNN_NHWC, 4, 4, 4, 4, ZDNN_NHWC, 1, 1, 16, 15, ZDNN_INVALID_SHAPE); } void test_fail_not_nhwc_nor_hwck() { zdnn_status status, exp_status = ZDNN_INVALID_LAYOUT; zdnn_tensor_desc src_pre_tfrmd_desc, dest_pre_tfrmd_desc, src_tfrmd_desc, dest_tfrmd_desc; zdnn_ztensor src_ztensor, dest_ztensor; zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &src_pre_tfrmd_desc, 4, 4, 4, 4); zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &dest_pre_tfrmd_desc, 4, 4, 4, 4); zdnn_generate_transformed_desc(&src_pre_tfrmd_desc, &src_tfrmd_desc); zdnn_generate_transformed_desc(&dest_pre_tfrmd_desc, &dest_tfrmd_desc); zdnn_init_ztensor(&src_pre_tfrmd_desc, &src_tfrmd_desc, &src_ztensor); zdnn_init_ztensor(&dest_pre_tfrmd_desc, &dest_tfrmd_desc, &dest_ztensor); src_ztensor.is_transformed = true; // sabotage the layouts src_tfrmd_desc.layout = ZDNN_NCHW; dest_tfrmd_desc.layout = ZDNN_NCHW; status = zdnn_reshape_ztensor(&src_ztensor, &dest_ztensor); TEST_ASSERT_MESSAGE_FORMATTED(exp_status == status, "expected status = %08x, got status = %08x", exp_status, status); } void test_fail_not_same_layout() { test_datatype = FP16; test(ZDNN_NHWC, 4, 5, 6, 7, ZDNN_HWCK, 4, 5, 6, 7, ZDNN_INVALID_LAYOUT); } void test_fail_src_not_transformed() { zdnn_status status, exp_status = ZDNN_INVALID_STATE; test_datatype = FP16; zdnn_tensor_desc src_pre_tfrmd_desc, dest_pre_tfrmd_desc, src_tfrmd_desc, dest_tfrmd_desc; zdnn_ztensor src_ztensor, dest_ztensor; zdnn_init_pre_transformed_desc(ZDNN_NHWC, test_datatype, &src_pre_tfrmd_desc, 4, 4, 4, 4); zdnn_init_pre_transformed_desc(ZDNN_NHWC, test_datatype, &dest_pre_tfrmd_desc, 4, 4, 4, 4); zdnn_generate_transformed_desc(&src_pre_tfrmd_desc, &src_tfrmd_desc); zdnn_generate_transformed_desc(&dest_pre_tfrmd_desc, &dest_tfrmd_desc); zdnn_init_ztensor(&src_pre_tfrmd_desc, &src_tfrmd_desc, &src_ztensor); zdnn_init_ztensor(&dest_pre_tfrmd_desc, &dest_tfrmd_desc, &dest_ztensor); // src_ztensor is NOT transformed at this point status = zdnn_reshape_ztensor(&src_ztensor, &dest_ztensor); TEST_ASSERT_MESSAGE_FORMATTED(exp_status == status, "expected status = %08x, got status = %08x", exp_status, status); } void test_fail_dest_already_transformed() { zdnn_status status, exp_status = ZDNN_INVALID_STATE; test_datatype = FP16; zdnn_tensor_desc src_pre_tfrmd_desc, dest_pre_tfrmd_desc, src_tfrmd_desc, dest_tfrmd_desc; zdnn_ztensor src_ztensor, dest_ztensor; zdnn_init_pre_transformed_desc(ZDNN_NHWC, test_datatype, &src_pre_tfrmd_desc, 4, 4, 4, 4); zdnn_init_pre_transformed_desc(ZDNN_NHWC, test_datatype, &dest_pre_tfrmd_desc, 4, 4, 4, 4); zdnn_generate_transformed_desc(&src_pre_tfrmd_desc, &src_tfrmd_desc); zdnn_generate_transformed_desc(&dest_pre_tfrmd_desc, &dest_tfrmd_desc); zdnn_init_ztensor(&src_pre_tfrmd_desc, &src_tfrmd_desc, &src_ztensor); zdnn_init_ztensor(&dest_pre_tfrmd_desc, &dest_tfrmd_desc, &dest_ztensor); src_ztensor.is_transformed = true; // sabotage dest_ztensor dest_ztensor.is_transformed = true; status = zdnn_reshape_ztensor(&src_ztensor, &dest_ztensor); TEST_ASSERT_MESSAGE_FORMATTED(exp_status == status, "expected status = %08x, got status = %08x", exp_status, status); } int main(void) { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(test_4x5x6x7_4x5x6x7); RUN_TEST_ALL_DATATYPES(test_1x2x3x4_6x1x1x4); RUN_TEST_ALL_DATATYPES(test_2x3x4x68_4x1x6x68); RUN_TEST_ALL_DATATYPES(test_4x3x40x70_8x20x3x70); RUN_TEST_ALL_DATATYPES(test_4x4x4x4_1x1x16x16); RUN_TEST_ALL_DATATYPES(test_fail_total_elements_mismatch); RUN_TEST(test_fail_not_nhwc_nor_hwck); RUN_TEST(test_fail_not_same_layout); RUN_TEST(test_fail_src_not_transformed); RUN_TEST(test_fail_dest_already_transformed); return UNITY_END(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_status_diag.c�����������������������������������������������������������0000664�0000000�0000000�00000005452�14364043643�0020367�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <stddef.h> #include <stdio.h> #include <string.h> #include <unistd.h> /********************************************************************* * This testcase only works for LoZ, as there's no way to easily * verify ctrace()'s output under z/OS. The intent of this testcase * is to verify if the status_diag code gets invoked when we want it * to, not as much as if it's producing the correct output. * *******************************************************************/ #ifndef __MVS__ void setUp(void) { /* This is run before EACH TEST */ } void tearDown(void) {} void try_diag(uint32_t status_to_diag, uint32_t status_to_set, bool expect_backtrace) { status_diag = status_to_diag; char buf_stdout[BUFSIZ] = {0}; stdout_to_pipe(); set_zdnn_status(status_to_set, __func__, __FILE__, __LINE__, "this is a test"); restore_stdout(buf_stdout, BUFSIZ); /* the backtrace should have something like: obj/../../aiu/libzdnn.so.1(set_zdnn_status+0x1d4)[0x3ffb750a19c] ./obj/testDriver_status_diag.out() [0x1001a2c] ./obj/testDriver_status_diag.out() [0x1001ade] ./obj/testDriver_status_diag.out() [0x1005012] ./obj/testDriver_status_diag.out() [0x1001baa] so search for "libzdnn" in the captured STDOUT output */ if (expect_backtrace) { TEST_ASSERT_MESSAGE(strstr(buf_stdout, "libzdnn") != NULL, "Can't find backtrace in buf_stdout"); } else { TEST_ASSERT_MESSAGE(strstr(buf_stdout, "libzdnn") == NULL, "Backtrace unexpectedly appears"); } } void test_real_error() { try_diag(ZDNN_INVALID_SHAPE, ZDNN_INVALID_SHAPE, true); } void test_zdnn_ok() { try_diag(ZDNN_OK, ZDNN_OK, true); } void test_not_match1() { try_diag(ZDNN_INVALID_SHAPE, ZDNN_OK, false); } void test_not_match2() { try_diag(ZDNN_INVALID_SHAPE, ZDNN_INVALID_FORMAT, false); } int main() { UNITY_BEGIN(); RUN_TEST(test_not_match1); RUN_TEST(test_not_match2); RUN_TEST(test_real_error); RUN_TEST(test_zdnn_ok); return UNITY_END(); } #else void setUp(void) {} void tearDown(void) {} int main() { UNITY_BEGIN(); return UNITY_END(); } #endif // __MVS__ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_stickify.c��������������������������������������������������������������0000664�0000000�0000000�00000154731�14364043643�0017712�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} //================================================================================================= // tests for stickify void test_stickify(uint32_t dim4, uint32_t dim3, uint32_t dim2, uint32_t dim1, zdnn_data_layouts layout, offset_mode offset_mode, const char *path) { /* Use 1x4x4x1 as example: 1) Create the input tensor descriptor 2) Create the raw (i.e., dense) input tensor data with random FP16/FP32/BFLOAT values 1 >= x > SMALLEST_RANDOM_FP. For 1x4x4x1 we have 16 elements. 3) Stickify the data to ztensor. Now ztensor.buffer has 16 DLFLOAT16 elements with all the necessary paddings. 4) get the array of address offsets where the values are expected to be in the stickified buffer. 5) Perform the check: fp16_to_dlf16(input_data[n]) == output_data[n] (i.e., stick_area[offsets[n]])? */ zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; void *data; switch (layout) { case (ZDNN_1D): zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, dim1); break; case (ZDNN_2D): case (ZDNN_2DS): zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, dim2, dim1); break; case (ZDNN_3D): case (ZDNN_3DS): zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, dim3, dim2, dim1); break; default: zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, dim4, dim3, dim2, dim1); } status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() failed (status = %08x)", status); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc() failed (status = %08x)", status); data = create_and_fill_random_fp_data(&ztensor); status = zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_transform_ztensor() failed, status = %08x " "(%s)", status, zdnn_get_status_message(status)); BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("%s(): dumpdata_origtensor\n", __func__); dumpdata_origtensor(&pre_tfrmd_desc, data, AS_HEX); dumpdata_origtensor(&pre_tfrmd_desc, data, AS_FLOAT); printf("%s(): dumpdata_ztensor\n", __func__); dumpdata_ztensor(&ztensor, AS_HEX, false); dumpdata_ztensor(&ztensor, AS_FLOAT, false); } uint64_t num_elements = get_num_elements(&ztensor, ELEMENTS_PRE); size_t *offsets = alloc_offsets(&ztensor, offset_mode, path); for (uint64_t i = 0; i < num_elements; i++) { // value in stick area, stickified uint16_t output_stickified_value = *(uint16_t *)((uintptr_t)ztensor.buffer + offsets[i]); // input value converted to DLFLOAT16, this is the "expected" value uint16_t stickified_input_value = 0; switch (test_datatype) { case BFLOAT: stickified_input_value = cnvt_1_bfloat_to_dlf16(((uint16_t *)data)[i]); break; case FP16: stickified_input_value = cnvt_1_fp16_to_dlf16(((uint16_t *)data)[i]); break; case FP32: stickified_input_value = cnvt_1_fp32_to_dlf16(((float *)data)[i]); break; default: TEST_FAIL_MESSAGE("Unsupported data type"); return; } TEST_ASSERT_MESSAGE_FORMATTED( almost_equal_dlf16(output_stickified_value, stickified_input_value), "Incorrect value at element %" PRIu64 ": Stickified: " "%.6f, Expected: %.6f", i, cnvt_1_dlf16_to_fp32(output_stickified_value), cnvt_1_dlf16_to_fp32(stickified_input_value)); } // Free allocated storage free(offsets); free(data); zdnn_free_ztensor_buffer(&ztensor); } /************************************************************** * NHWC **************************************************************/ #define NHWC_TEST_BASIC(n, h, w, c) \ void test_nhwc_##n##x##h##x##w##x##c() { \ test_stickify(n, h, w, c, ZDNN_NHWC, QUICK_OFFSETS, NULL); \ } /* * Tensor with 16 entries, NHWC * 1,4,4,1 NHWC will use one cell per stick, 4 sticks per page and a total of 4 * pages * * [0, 128, 256, 384, (H = 0) * 4096, 4224, 4352, 4480, (H = 1) * 8192, 8320, 8448, 8576, (H = 2) * 12288, 12416, 12544, 12672] (H = 3) */ NHWC_TEST_BASIC(1, 4, 4, 1); NHWC_TEST_BASIC(1, 4, 4, 2); NHWC_TEST_BASIC(1, 32, 32, 1); NHWC_TEST_BASIC(1, 32, 32, 2); /* * 3K entries in tensor, send to NHWC sticks * Each stick uses 3 cells, and all 32 sticks of the page are used. * 32 pages are used to store the values. */ NHWC_TEST_BASIC(1, 32, 32, 3); NHWC_TEST_BASIC(1, 1, 2, 1); NHWC_TEST_BASIC(1, 1, 2, 2); NHWC_TEST_BASIC(1, 1, 2, 4); NHWC_TEST_BASIC(1, 1, 2, 7); NHWC_TEST_BASIC(1, 1, 4, 1); NHWC_TEST_BASIC(1, 1, 4, 2); NHWC_TEST_BASIC(1, 1, 4, 4); NHWC_TEST_BASIC(1, 1, 4, 7); NHWC_TEST_BASIC(1, 1, 7, 1); NHWC_TEST_BASIC(1, 1, 7, 2); NHWC_TEST_BASIC(1, 1, 7, 4); NHWC_TEST_BASIC(1, 1, 7, 7); NHWC_TEST_BASIC(1, 1, 8, 1); NHWC_TEST_BASIC(1, 1, 8, 2); NHWC_TEST_BASIC(1, 1, 8, 4); NHWC_TEST_BASIC(1, 1, 8, 7); NHWC_TEST_BASIC(1, 1, 13, 1); NHWC_TEST_BASIC(1, 1, 13, 2); NHWC_TEST_BASIC(1, 1, 13, 4); NHWC_TEST_BASIC(1, 1, 13, 7); NHWC_TEST_BASIC(1, 1, 100, 1); NHWC_TEST_BASIC(1, 1, 100, 2); NHWC_TEST_BASIC(1, 1, 100, 4); NHWC_TEST_BASIC(1, 1, 100, 7); NHWC_TEST_BASIC(2, 3, 2, 1); NHWC_TEST_BASIC(2, 3, 2, 2); NHWC_TEST_BASIC(2, 3, 2, 4); NHWC_TEST_BASIC(2, 3, 2, 7); NHWC_TEST_BASIC(2, 3, 4, 1); NHWC_TEST_BASIC(2, 3, 4, 2); NHWC_TEST_BASIC(2, 3, 4, 4); NHWC_TEST_BASIC(2, 3, 4, 7); NHWC_TEST_BASIC(2, 3, 7, 1); NHWC_TEST_BASIC(2, 3, 7, 2); NHWC_TEST_BASIC(2, 3, 7, 4); NHWC_TEST_BASIC(2, 3, 7, 7); NHWC_TEST_BASIC(2, 3, 8, 1); NHWC_TEST_BASIC(2, 3, 8, 2); NHWC_TEST_BASIC(2, 3, 8, 4); NHWC_TEST_BASIC(2, 3, 8, 7); NHWC_TEST_BASIC(2, 3, 13, 1); NHWC_TEST_BASIC(2, 3, 13, 2); NHWC_TEST_BASIC(2, 3, 13, 4); NHWC_TEST_BASIC(2, 3, 13, 7); NHWC_TEST_BASIC(2, 3, 100, 1); NHWC_TEST_BASIC(2, 3, 100, 2); NHWC_TEST_BASIC(2, 3, 100, 4); NHWC_TEST_BASIC(2, 3, 100, 7); NHWC_TEST_BASIC(3, 2, 2, 1); NHWC_TEST_BASIC(3, 2, 2, 2); NHWC_TEST_BASIC(3, 2, 2, 4); NHWC_TEST_BASIC(3, 2, 2, 7); NHWC_TEST_BASIC(3, 2, 4, 1); NHWC_TEST_BASIC(3, 2, 4, 2); NHWC_TEST_BASIC(3, 2, 4, 4); NHWC_TEST_BASIC(3, 2, 4, 7); NHWC_TEST_BASIC(3, 2, 7, 1); NHWC_TEST_BASIC(3, 2, 7, 2); NHWC_TEST_BASIC(3, 2, 7, 4); NHWC_TEST_BASIC(3, 2, 7, 7); NHWC_TEST_BASIC(3, 2, 8, 1); NHWC_TEST_BASIC(3, 2, 8, 2); NHWC_TEST_BASIC(3, 2, 8, 4); NHWC_TEST_BASIC(3, 2, 8, 7); NHWC_TEST_BASIC(3, 2, 13, 1); NHWC_TEST_BASIC(3, 2, 13, 2); NHWC_TEST_BASIC(3, 2, 13, 4); NHWC_TEST_BASIC(3, 2, 13, 7); NHWC_TEST_BASIC(3, 2, 100, 1); NHWC_TEST_BASIC(3, 2, 100, 2); NHWC_TEST_BASIC(3, 2, 100, 4); NHWC_TEST_BASIC(3, 2, 100, 7); /* * This routine is a generic test routine, allowing various 'e1' values * to be input. It tests stickification conversion (X -> DLFLOAT). * It assumes the e4-e2 values are 1 in order to * allow simpler assignment of the "offset" variable for * examining values stored in the stick. e1 can range from 1 to 128, * i.e. one or two pages of 64 values per stick. */ void test_nhwc_1x1x1xe1(uint32_t e1) { test_stickify(1, 1, 1, e1, ZDNN_NHWC, QUICK_OFFSETS, NULL); } void test_nhwc_1x1x1x4() { test_nhwc_1x1x1xe1(4); } void test_nhwc_1x1x1x5() { test_nhwc_1x1x1xe1(5); } void test_nhwc_1x1x1x8() { test_nhwc_1x1x1xe1(8); } void test_nhwc_1x1x1x9() { test_nhwc_1x1x1xe1(9); } void test_nhwc_1x1x1x63() { test_nhwc_1x1x1xe1(63); } void test_nhwc_1x1x1x64() { test_nhwc_1x1x1xe1(64); } void test_nhwc_1x1x1x65() { test_nhwc_1x1x1xe1(65); } void test_nhwc_1x1x1x127() { test_nhwc_1x1x1xe1(127); } void test_nhwc_1x1x1x128() { test_nhwc_1x1x1xe1(128); } #define NHWC_TEST_WITH_FILE(n, h, w, c) \ void test_nhwc_##n##x##h##x##w##x##c() { \ test_stickify(n, h, w, c, ZDNN_NHWC, FILE_OFFSETS, \ OFFSET_FILE(nhwc, n, h, w, c)); \ } NHWC_TEST_WITH_FILE(1, 2, 3, 4) NHWC_TEST_WITH_FILE(1, 1, 31, 64) NHWC_TEST_WITH_FILE(1, 1, 32, 64) NHWC_TEST_WITH_FILE(1, 1, 33, 64) NHWC_TEST_WITH_FILE(1, 1, 32, 63) NHWC_TEST_WITH_FILE(1, 1, 32, 65) NHWC_TEST_WITH_FILE(1, 1, 4, 127) NHWC_TEST_WITH_FILE(1, 1, 4, 128) NHWC_TEST_WITH_FILE(1, 1, 4, 129) NHWC_TEST_WITH_FILE(1, 1, 63, 4) NHWC_TEST_WITH_FILE(1, 1, 64, 4) NHWC_TEST_WITH_FILE(1, 1, 65, 4) NHWC_TEST_WITH_FILE(2, 3, 33, 129) /* * Tensor with 16 entries, 3DS * 4,4,1 3DS will use one cell per stick, 4 sticks per page and a total of 4 * pages. */ void test_3ds_4x4x1() { // first entry doesn't matter test_stickify(9999, 4, 4, 1, ZDNN_3DS, QUICK_OFFSETS, NULL); } /* * 3K entries in tensor, send to 3DS sticks * Each stick uses 3 cells, and all 32 sticks of the page are used. * 32 pages are used to store the values. * */ void test_3ds_32x32x3() { // first entry doesn't matter test_stickify(9999, 32, 32, 3, ZDNN_3DS, QUICK_OFFSETS, NULL); } /* * Tensor with 8 entries, 2DS * 4,2 2DS will use two cells per stick, (implied 1 stick per page) and a total * of 4 pages. */ void test_2ds_4x2() { // first two entries don't matter in 2DS test_stickify(9999, 9999, 4, 2, ZDNN_2DS, QUICK_OFFSETS, NULL); } /* * Tensor with 4k entries, 2DS * We expect this to require 4 pages total. Each dim2 will require 2 pages. * The first page will have all 64 cells of all 32 sticks filled holding 2048 * values. A second page will have 1 stick with 1 cell filled to hold val 2049. */ void test_2ds_2x2049() { // first two entries don't matter in 2DS test_stickify(9999, 9999, 2, 2049, ZDNN_2DS, QUICK_OFFSETS, NULL); } void test_concat_stickify(zdnn_concat_info info, uint32_t dim3, uint32_t dim2, uint32_t dim1) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; void *data[] = {NULL, NULL, NULL, NULL}; uint8_t num_concats = 0; if (CONCAT_RNN_TYPE(info) == RNN_TYPE_LSTM) { num_concats = 4; } else if (CONCAT_RNN_TYPE(info) == RNN_TYPE_GRU) { num_concats = 3; } else { TEST_FAIL_MESSAGE_FORMATTED("bad concat info: %08x\n", info); } // Fill in pre_transformed_desc. If dim3 is set, we're concatenating a 3DS // tensor otherwise assume 2DS. if (dim3) { // Initialize tensor descriptor zdnn_init_pre_transformed_desc(ZDNN_3DS, test_datatype, &pre_tfrmd_desc, dim3, dim2, dim1); } else { zdnn_init_pre_transformed_desc(ZDNN_2DS, test_datatype, &pre_tfrmd_desc, dim2, dim1); } // Fill in transformed_desc. status = zdnn_generate_transformed_desc_concatenated(&pre_tfrmd_desc, info, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc_concatenated() failed, status = %08x " "(%s) (concat info = %08x)", status, zdnn_get_status_message(status), info); // Create ztensor and allocate space for it's buffer status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); TEST_ASSERT_MESSAGE_FORMATTED(status == ZDNN_OK, "zdnn_init_ztensor_with_malloc() failed, " "status = %08x (%s) (concat info = %08x)", status, zdnn_get_status_message(status), info); // Fill in random data for each gate's original values for (uint8_t i = 0; i < num_concats; i++) { data[i] = create_and_fill_random_fp_data(&ztensor); } // Transform the original data values into the stickified ztensor switch (num_concats) { case 4: status = zdnn_transform_ztensor(&ztensor, data[0], data[1], data[2], data[3]); break; case 3: status = zdnn_transform_ztensor(&ztensor, data[0], data[1], data[2]); break; default: TEST_FAIL_MESSAGE_FORMATTED("num_concats of %d is not supported (concat " "info = %08x)", num_concats, info); break; } TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_transform_ztensor() failed, status = %08x " "(%s) (concat info = %08x)", status, zdnn_get_status_message(status), info); // Print the original data and stickified buffer BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { // Each gate will have it's own input data so dump each one. Each will // have the same dimensions/pre-tfrmd_desc for (uint8_t i = 0; i < num_concats; i++) { printf("%s(): dumpdata_origtensor for gate %d\n", __func__, i); dumpdata_origtensor(ztensor.pre_transformed_desc, data[i], AS_HEX); dumpdata_origtensor(ztensor.pre_transformed_desc, data[i], AS_FLOAT); } // The gates are concatenated into one ztensor so there's only one to dump printf("%s(): dumpdata_ztensor (concatenated)\n", __func__); dumpdata_ztensor(&ztensor, AS_HEX, false); dumpdata_ztensor(&ztensor, AS_FLOAT, false); } uint64_t elements_per_concat = get_num_elements(&ztensor, ELEMENTS_PRE_SINGLE_GATE); uint64_t slices_per_concat = ztensor.transformed_desc->dim4; uint64_t elements_per_concat_slice = elements_per_concat / slices_per_concat; LOG_DEBUG("elements_per_concat = %ld, slices_per_concat = %ld, " "elements_per_concat_slice = %ld", elements_per_concat, slices_per_concat, elements_per_concat_slice); size_t *offsets = alloc_offsets(&ztensor, QUICK_OFFSETS, NULL); uint16_t input_stickified_value = 0; uint16_t output_stickified_value; uint32_t offset_index = 0; // Loop through each offset in order and confirm the stickified value there // matches the correct original input value. The loop handles the difference // in output vs input element order caused by support of ztensor slicing. for (uint32_t slice = 0; slice < ztensor.transformed_desc->dim4; slice++) { size_t slice_offset = slice * elements_per_concat_slice * get_data_type_size(test_datatype); for (uint32_t concat = 0; concat < num_concats; concat++) { void *concat_slice_data = (void *)((uintptr_t)data[concat] + slice_offset); for (uint32_t elm_i = 0; elm_i < elements_per_concat_slice; elm_i++) { output_stickified_value = *(uint16_t *)((uintptr_t)ztensor.buffer + offsets[offset_index]); switch (test_datatype) { // Convert input to stickified values for comparison to output. case BFLOAT: input_stickified_value = cnvt_1_bfloat_to_dlf16(((uint16_t *)concat_slice_data)[elm_i]); LOG_TRACE( "offsets[%d] (native %s) = %04x vs %04x for input from " "slice %d of concat %d at element index %d (%s converted to %s)", offset_index, get_data_type_str(ZDNN_DLFLOAT16), output_stickified_value, input_stickified_value, slice, concat, elm_i, get_data_type_str(test_datatype), get_data_type_str(ZDNN_DLFLOAT16)); break; case FP16: input_stickified_value = cnvt_1_fp16_to_dlf16(((uint16_t *)concat_slice_data)[elm_i]); LOG_TRACE( "offsets[%d] (native %s) = %04x vs %04x for input from " "slice %d of concat %d at element index %d (%s converted to %s)", offset_index, get_data_type_str(ZDNN_DLFLOAT16), output_stickified_value, input_stickified_value, slice, concat, elm_i, get_data_type_str(test_datatype), get_data_type_str(ZDNN_DLFLOAT16)); break; case FP32: input_stickified_value = cnvt_1_fp32_to_dlf16(((float *)concat_slice_data)[elm_i]); LOG_TRACE( "offsets[%d] (%s converted to %s) = %4f vs %4f for input from " "slice %d of concat %d at element index %d (native %s)", offset_index, get_data_type_str(ZDNN_DLFLOAT16), get_data_type_str(test_datatype), cnvt_1_dlf16_to_fp32(output_stickified_value), ((float *)concat_slice_data)[elm_i], slice, concat, elm_i, get_data_type_str(test_datatype)); break; default: TEST_FAIL_MESSAGE_FORMATTED("Unsupported data type %d (%s)", test_datatype, get_data_type_str(test_datatype)); break; } TEST_ASSERT_MESSAGE_FORMATTED( output_stickified_value == input_stickified_value, "offsets[%u] = %04x (native %s) but expected %04x (%s " "converted to %s)", offset_index, output_stickified_value, get_data_type_str(ZDNN_DLFLOAT16), input_stickified_value, get_data_type_str(test_datatype), get_data_type_str(ZDNN_DLFLOAT16)); offset_index++; } } } // Free allocated storage free(offsets); for (uint8_t i = 0; i < num_concats; i++) { free(data[i]); } zdnn_free_ztensor_buffer(&ztensor); } /* * Create a FICO bias ztensor with 16 entries: * 4 gates each having 1 direction each having 4 elements */ void test_lstm_biases_1x4() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat_stickify(RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 0, 1, 4); } } } /* * Create a FICO bias ztensor with 32 entries: * 4 gates each having 2 directions each having 4 elements */ void test_lstm_biases_2x4() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat_stickify(RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 0, 2, 4); } } } /* * Create a FICO bias ztensor with 520 entries: * 4 gates each having 2 directions each having 65 elements */ void test_lstm_biases_2x65() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat_stickify(RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 0, 2, 65); } } } /* * Create a FICO bias ztensor with 16392 entries: * 4 gates each having 2 directions each having 2049 elements * 2049 = 64 max cells per stick * 32 max sticks per page + 1. This means each * direction will require two 4K pages to stickify. */ void test_lstm_biases_2x2049() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat_stickify(RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], 0, 2, 2049); } } } /* * Create a FICO weights ztensor (PREV_LAYER_UNI) with 48 entries: * 4 gates each having 1 direction each having 3 rows with 4 elements */ void test_lstm_no_vconcat_weights_1x3x4() { test_concat_stickify(RNN_TYPE_LSTM | PREV_LAYER_UNI | USAGE_WEIGHTS, 1, 3, 4); } /* * Create a FICO weights ztensor (PREV_LAYER_UNI) with 96 entries: * 4 gates each having 2 directions each having 3 rows with 4 elements */ void test_lstm_no_vconcat_weights_2x3x4() { test_concat_stickify(RNN_TYPE_LSTM | PREV_LAYER_UNI | USAGE_WEIGHTS, 2, 3, 4); } /* * Create a FICO weights ztensor (PREV_LAYER_UNI) with 17160 entries: * 4 gates each having 2 directions each having 33 rows with 65 elements * Each direction will require two 4k pages to stickify as each cell has a max * of 64 elements and each page has a max of 32 sticks. */ void test_lstm_no_vconcat_weights_2x33x65() { test_concat_stickify(RNN_TYPE_LSTM | PREV_LAYER_UNI | USAGE_WEIGHTS, 2, 33, 65); } /* * Create a FICO weights ztensor (PREV_LAYER_BIDIR) with 96 entries: * 4 gates each having 1 direction each having 6 rows with 4 elements */ void test_lstm_prev_bidir_weights_1x6x4() { test_concat_stickify(RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 1, 6, 4); } /* * Create a FICO weights ztensor (PREV_LAYER_BIDIR) with 192 entries: * 4 gates each having 2 directions each having 6 rows with 4 elements */ void test_lstm_prev_bidir_weights_2x6x4() { test_concat_stickify(RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 2, 6, 4); } /* * Create a FICO weights ztensor with (PREV_LAYER_BIDIR) 34320 entries: * 4 gates each having 2 directions each having 66 rows with 65 elements * Each direction will require eight 4k pages to stickify as each cell has a max * of 64 elements and each page has a max of 32 sticks. */ void test_lstm_prev_bidir_weights_2x66x65() { test_concat_stickify(RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 2, 66, 65); } /* * Create a GRU bias ztensor with 12 entries: * 3 gates each having 1 direction each having 4 elements */ void test_gru_biases_1x4() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat_stickify(RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 0, 1, 4); } } } /* * Create a GRU bias ztensor with 24 entries: * 3 gates each having 2 directions each having 4 elements */ void test_gru_biases_2x4() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat_stickify(RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 0, 2, 4); } } } /* * Create a GRU bias ztensor with 390 entries: * 3 gates each having 2 directions each having 65 elements */ void test_gru_biases_2x65() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat_stickify(RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 0, 2, 65); } } } /* * Create a GRU bias ztensor with 12294 entries: * 3 gates each having 2 directions each having 2049 elements * 2049 = 64 max cells per stick * 32 max sticks per page + 1. This means each * direction will require two 4K pages to stickify. */ void test_gru_biases_2x2049() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_concat_stickify(RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], 0, 2, 2049); } } } /* * Create a ZRH weights ztensor (PREV_LAYER_UNI) with 36 entries: * 3 gates each having 1 direction each having 3 rows with 4 elements */ void test_gru_no_vconcat_weights_1x3x4() { test_concat_stickify(RNN_TYPE_GRU | PREV_LAYER_UNI | USAGE_WEIGHTS, 1, 3, 4); } /* * Create a ZRH weights ztensor (PREV_LAYER_UNI) with 72 entries: * 3 gates each having 2 directions each having 3 rows with 4 elements */ void test_gru_no_vconcat_weights_2x3x4() { test_concat_stickify(RNN_TYPE_GRU | PREV_LAYER_UNI | USAGE_WEIGHTS, 2, 3, 4); } /* * Create a ZRH weights ztensor (PREV_LAYER_UNI) with 12870 entries: * 3 gates each having 2 directions each having 33 rows with 65 elements * Each direction will require two 4k pages to stickify as each cell has a max * of 64 elements and each page has a max of 32 sticks. */ void test_gru_no_vconcat_weights_2x33x65() { test_concat_stickify(RNN_TYPE_GRU | PREV_LAYER_UNI | USAGE_WEIGHTS, 2, 33, 65); } /* * Create a ZRH weights ztensor (PREV_LAYER_BIDIR) with 72 entries: * 3 gates each having 1 direction each having 6 rows with 4 elements */ void test_gru_prev_bidir_weights_1x6x4() { test_concat_stickify(RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 1, 6, 4); } /* * Create a ZRH weights ztensor (PREV_LAYER_BIDIR) with 144 entries: * 3 gates each having 2 directions each having 6 rows with 4 elements */ void test_gru_prev_bidir_weights_2x6x4() { test_concat_stickify(RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 2, 6, 4); } /* * Create a ZRH weights ztensor with (PREV_LAYER_BIDIR) 25740 entries: * 3 gates each having 2 directions each having 66 rows with 65 elements * Each direction will require six 4k pages to stickify as each cell has a max * of 64 elements and each page has a max of 32 sticks. */ void test_gru_prev_bidir_weights_2x66x65() { test_concat_stickify(RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, 2, 66, 65); } void test_concat_weights_dim2(zdnn_concat_info info, uint32_t dim3, uint32_t dim2, uint32_t dim1, zdnn_status exp_status) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; void *data[] = {NULL, NULL, NULL, NULL}; uint8_t num_concats = 0; if (CONCAT_RNN_TYPE(info) == RNN_TYPE_LSTM) { num_concats = 4; } else if (CONCAT_RNN_TYPE(info) == RNN_TYPE_GRU) { num_concats = 3; } else { TEST_FAIL_MESSAGE_FORMATTED("bad concat info: %08x\n", info); } // if dim2 is odd number coming in, +1 so we create a valid dim2 and create // a valid ztensor with that. else use it as is zdnn_init_pre_transformed_desc(ZDNN_3DS, test_datatype, &pre_tfrmd_desc, dim3, ((dim2 & 1) ? dim2 + 1 : dim2), dim1); status = zdnn_generate_transformed_desc_concatenated(&pre_tfrmd_desc, info, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc_concatenated() failed, status = %08x " "(%s) (concat info = %08x)", status, zdnn_get_status_message(status), info); // Create ztensor and allocate space for it's buffer status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); TEST_ASSERT_MESSAGE_FORMATTED(status == ZDNN_OK, "zdnn_init_ztensor_with_malloc() failed, " "status = %08x (%s) (concat info = %08x)", status, zdnn_get_status_message(status), info); // Fill in random data for each gate's original values for (uint8_t i = 0; i < num_concats; i++) { data[i] = create_and_fill_random_fp_data(&ztensor); } // put back the incoming dim2 into pre-transformed desc as caller intended ztensor.pre_transformed_desc->dim2 = dim2; // Transform the original data values into the stickified ztensor switch (num_concats) { case 4: status = zdnn_transform_ztensor(&ztensor, data[0], data[1], data[2], data[3]); break; case 3: status = zdnn_transform_ztensor(&ztensor, data[0], data[1], data[2]); break; default: TEST_FAIL_MESSAGE_FORMATTED( "num_concats of %d is not supported (concat info = %08x)", num_concats, info); break; } TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status, "zdnn_transform_origtensor() unexpected status (status = %08x, " "expects = %08x)", status, exp_status); for (uint8_t i = 0; i < num_concats; i++) { free(data[i]); } zdnn_free_ztensor_buffer(&ztensor); } void test_lstm_no_vconcat_weights_odd_dim2_pass() { test_concat_weights_dim2(RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_UNI, 3, 9, 10, ZDNN_OK); } void test_lstm_prev_bidir_weights_odd_dim2_fail() { test_concat_weights_dim2(RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_BIDIR, 3, 9, 10, ZDNN_INVALID_SHAPE); } void test_gru_no_vconcat_weights_odd_dim2_pass() { test_concat_weights_dim2(RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_UNI, 3, 9, 10, ZDNN_OK); } void test_gru_prev_bidir_weights_odd_dim2_fail() { test_concat_weights_dim2(RNN_TYPE_GRU | USAGE_WEIGHTS | PREV_LAYER_BIDIR, 3, 9, 10, ZDNN_INVALID_SHAPE); } /************************************************************** * NCHW **************************************************************/ #define NCHW_TEST_WITH_FILE(n, c, h, w) \ void test_nchw_##n##x##c##x##h##x##w() { \ test_stickify(n, c, h, w, ZDNN_NCHW, FILE_OFFSETS, \ OFFSET_FILE(nchw, n, c, h, w)); \ } NCHW_TEST_WITH_FILE(1, 1, 4, 4) NCHW_TEST_WITH_FILE(1, 4, 2, 3) NCHW_TEST_WITH_FILE(1, 3, 32, 32) NCHW_TEST_WITH_FILE(2, 129, 3, 33) NCHW_TEST_WITH_FILE(1, 64, 1, 31) NCHW_TEST_WITH_FILE(1, 64, 1, 32) NCHW_TEST_WITH_FILE(1, 64, 1, 33) NCHW_TEST_WITH_FILE(1, 63, 1, 32) NCHW_TEST_WITH_FILE(1, 65, 1, 32) NCHW_TEST_WITH_FILE(1, 127, 1, 4) NCHW_TEST_WITH_FILE(1, 128, 1, 4) NCHW_TEST_WITH_FILE(1, 129, 1, 4) NCHW_TEST_WITH_FILE(1, 4, 1, 63) NCHW_TEST_WITH_FILE(1, 4, 1, 64) NCHW_TEST_WITH_FILE(1, 4, 1, 65) // a simple (dumb) routine to convert a NHWC datastream to NCHW void nhwc_2_nchw(void *nhwc_ptr, uint32_t n, uint32_t h, uint32_t w, uint32_t c, int element_size, void *nchw_ptr) { uint32_t nx, hx, wx, cx; for (nx = 0; nx < n; nx++) { for (hx = 0; hx < h; hx++) { for (wx = 0; wx < w; wx++) { for (cx = 0; cx < c; cx++) { uint64_t nhwc_idx = nx * (h * w * c) + hx * (w * c) + wx * (c) + cx; uint64_t nchw_idx = nx * (c * h * w) + cx * (h * w) + hx * (w) + wx; if (element_size == 2) { ((uint16_t *)nchw_ptr)[nchw_idx] = ((uint16_t *)nhwc_ptr)[nhwc_idx]; } else if (element_size == 4) { ((uint32_t *)nchw_ptr)[nchw_idx] = ((uint32_t *)nhwc_ptr)[nhwc_idx]; } } } } } } /* create a NHWC input tensor data stream, then create a NCHW-copy of it via * matrix-rotate, then stickify both. Compare the stickified data areas via * memcmp and they should match 100% */ void nhwc_nchw_comp(uint32_t n, uint32_t h, uint32_t w, uint32_t c) { zdnn_tensor_desc pre_tfrmd_desc_nhwc, pre_tfrmd_desc_nchw; zdnn_tensor_desc tfrmd_desc_nhwc, tfrmd_desc_nchw; zdnn_ztensor ztensor_nhwc, ztensor_nchw; zdnn_status status; void *data_nhwc, *data_nchw; zdnn_init_pre_transformed_desc(ZDNN_NHWC, test_datatype, &pre_tfrmd_desc_nhwc, n, h, w, c); zdnn_init_pre_transformed_desc(ZDNN_NCHW, test_datatype, &pre_tfrmd_desc_nchw, n, c, h, w); zdnn_generate_transformed_desc(&pre_tfrmd_desc_nhwc, &tfrmd_desc_nhwc); zdnn_generate_transformed_desc(&pre_tfrmd_desc_nchw, &tfrmd_desc_nchw); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc_nhwc, &tfrmd_desc_nhwc, &ztensor_nhwc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc NHWC failed (status = %08x)", status); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc_nchw, &tfrmd_desc_nchw, &ztensor_nchw); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc NCHW failed (status = %08x)", status); // create NHWC data stream, then matrix-rotate it to NCHW to another data // stream data_nhwc = create_and_fill_random_fp_data(&ztensor_nhwc); data_nchw = malloc(pre_tfrmd_desc_nhwc.dim4 * pre_tfrmd_desc_nhwc.dim3 * pre_tfrmd_desc_nhwc.dim2 * pre_tfrmd_desc_nhwc.dim1 * get_data_type_size(pre_tfrmd_desc_nhwc.type)); nhwc_2_nchw(data_nhwc, n, h, w, c, get_data_type_size(pre_tfrmd_desc_nhwc.type), data_nchw); BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("NHWC DATA " "=================================================================" "\n"); dumpdata_origtensor(&pre_tfrmd_desc_nhwc, data_nhwc, AS_FLOAT); printf("NCHW DATA " "=================================================================" "\n"); dumpdata_origtensor(&pre_tfrmd_desc_nchw, data_nchw, AS_FLOAT); } memset(ztensor_nhwc.buffer, 0, ztensor_nhwc.buffer_size); memset(ztensor_nchw.buffer, 0, ztensor_nchw.buffer_size); status = zdnn_transform_ztensor(&ztensor_nhwc, data_nhwc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_transform_ztensor NHWC failed (status = %08x)", status); status = zdnn_transform_ztensor(&ztensor_nchw, data_nchw); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_transform_ztensor NCHW failed (status = %08x)", status); BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("NHWC STICK " "=================================================================" "\n"); dumpdata_ztensor(&ztensor_nhwc, AS_FLOAT, false); printf("NCHW STICK " "=================================================================" "\n"); dumpdata_ztensor(&ztensor_nchw, AS_FLOAT, false); } TEST_ASSERT_MESSAGE(memcmp(ztensor_nchw.buffer, ztensor_nhwc.buffer, ztensor_nhwc.buffer_size) == 0, "Stickified NHWC and NCHW don't match"); free(data_nchw); } void test_nhwc_nchw_comp_1x4x4x1() { nhwc_nchw_comp(1, 4, 4, 1); } void test_nhwc_nchw_comp_1x32x32x3() { nhwc_nchw_comp(1, 32, 32, 3); } void test_nhwc_nchw_comp_2x3x33x129() { nhwc_nchw_comp(2, 3, 33, 129); } // Reuse zdnn_ztensor without resetting is_transformed, expects // ZDNN_BAD_PARAMETER void test_ztensor_reuse_with_reset() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; unsigned char *data, *data2; zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &pre_tfrmd_desc, 1, 4, 4, 1); status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() failed (status = %08x)", status); TEST_ASSERT_MESSAGE(ZDNN_OK == zdnn_init_ztensor_with_malloc( &pre_tfrmd_desc, &tfrmd_desc, &ztensor), "Unsuccessful zdnn_init_ztensor_with_malloc"); data = create_and_fill_random_fp_data(&ztensor); data2 = create_and_fill_random_fp_data(&ztensor); TEST_ASSERT_MESSAGE(ZDNN_OK == zdnn_transform_ztensor(&ztensor, data), "Unsuccessful first zdnn_transform_ztensor"); zdnn_reset_ztensor(&ztensor); TEST_ASSERT_MESSAGE(ZDNN_OK == zdnn_transform_ztensor(&ztensor, data2), "Unsuccessful second zdnn_transform_ztensor"); // Free allocated storage free(data); free(data2); zdnn_free_ztensor_buffer(&ztensor); } // Reuse zdnn_ztensor without resetting is_transformed, expects // ZDNN_BAD_PARAMETER void test_ztensor_reuse_without_reset() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; unsigned char *data, *data2; zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &pre_tfrmd_desc, 1, 4, 4, 1); status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() failed (status = %08x)", status); TEST_ASSERT_MESSAGE(ZDNN_OK == zdnn_init_ztensor_with_malloc( &pre_tfrmd_desc, &tfrmd_desc, &ztensor), "Unsuccessful zdnn_init_ztensor_with_malloc"); data = create_and_fill_random_fp_data(&ztensor); data2 = create_and_fill_random_fp_data(&ztensor); TEST_ASSERT_MESSAGE(ZDNN_OK == zdnn_transform_ztensor(&ztensor, data), "Unsuccessful first zdnn_transform_ztensor"); TEST_ASSERT_MESSAGE( ZDNN_INVALID_STATE == zdnn_transform_ztensor(&ztensor, data2), "Second zdnn_transform_ztensor does not yield ZDNN_INVALID_STATE"); // Free allocated storage free(data); free(data2); zdnn_free_ztensor_buffer(&ztensor); } void test_format_after_stickify_4dfeature_success() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; unsigned char *data; // sabotage ztensor with crap values memset(&ztensor, 0xFF, sizeof(ztensor)); // doing all these steps absolutely barebone, as the normal testcases should // have covered verifying the status zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &pre_tfrmd_desc, 1, 4, 4, 1); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); data = create_and_fill_random_fp_data(&ztensor); zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE(ztensor.is_transformed == true, "Expected is_transformed to be set to true, it is not."); // Free allocated storage free(data); zdnn_free_ztensor_buffer(&ztensor); } void test_format_after_stickify_4dfeature_fail() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; unsigned char *data; // sabotage ztensor with crap values memset(&ztensor, 0xFF, sizeof(ztensor)); // doing all these steps absolutely barebone, as the normal testcases should // have covered verifying the status zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &pre_tfrmd_desc, 1, 4, 4, 1); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); data = create_and_fill_random_fp_data(&ztensor); // sabotage ztensor.pre_transformed_desc so it would fail ztensor.pre_transformed_desc->type = ZDNN_DLFLOAT16; zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE(ztensor.is_transformed == false, "Expected is_transformed to be set to false, it is not."); // Free allocated storage free(data); zdnn_free_ztensor_buffer(&ztensor); } void test_ztensor_null_buffer() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; unsigned char *data; zdnn_status status; zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &pre_tfrmd_desc, 1, 4, 4, 1); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); data = create_and_fill_random_fp_data(&ztensor); ztensor.buffer = NULL; status = zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_INVALID_BUFFER, "zdnn_transform_ztensor() failed (status = %08x, expects = %08x)", status, ZDNN_DATA_ERROR); // Free allocated storage free(data); zdnn_free_ztensor_buffer(&ztensor); } void test_ztensor_not_enough_buffersize() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; unsigned char *data; zdnn_status status; zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &pre_tfrmd_desc, 4, 1, 1, 1); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); data = create_and_fill_random_fp_data(&ztensor); // (4, 1, 1, 1) needs 4 * 4096 bytes ztensor.buffer_size = 4096; status = zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_INVALID_BUFFER, "zdnn_transform_ztensor() failed (status = %08x, expects = %08x)", status, ZDNN_DATA_ERROR); // Free allocated storage free(data); zdnn_free_ztensor_buffer(&ztensor); } // This routine tests the conversion from FP16 to DLF // Input: a "bad" value in FP16, which will "trip" the // floating point exception trigger on VCNF void test_ztensor_bad_value_FP16(uint16_t bad_value) { #define INF_FP16_POS 0X7C00 #define INF_FP16_NEG 0xFC00 #define NAN_FP16_POS 0x7FFF #define NAN_FP16_NEG 0xFFFF #define STICK_ENTRIES_FP16 7 uint32_t stick_entries_to_try[STICK_ENTRIES_FP16] = {0, 1, 7, 8, 9, 62, 63}; zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; unsigned char *data; uint16_t *array; // Alternate view on data zdnn_status status; zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &pre_tfrmd_desc, 1, 1, 1, 64); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); data = create_and_fill_random_fp_data(&ztensor); array = (uint16_t *)data; /* use data as an INT array */ for (int i = 0; i < STICK_ENTRIES_FP16; i++) { array[stick_entries_to_try[i]] = bad_value; ztensor.is_transformed = false; /* set false for next attempt, required for underflow case */ status = zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_CONVERT_FAILURE, "zdnn_transform_ztensor() succeeded (status = %08x, expects = " "%08x, i = %d, value = %04x)", status, ZDNN_CONVERT_FAILURE, i, bad_value); TEST_ASSERT_MESSAGE_FORMATTED( ztensor.is_transformed == false, "zdnn_transform_ztensor() set is_transformed (status = %08x, " "expects = %08x, i = %d, value = %08x)", status, ZDNN_CONVERT_FAILURE, i, bad_value); array[stick_entries_to_try[i]] = 0; // set entry to 0 for next iteration } // Free allocated storage free(data); zdnn_free_ztensor_buffer(&ztensor); } void test_ztensor_fp16_bad_values() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE("needs NNPA to trigger overflow/invalid-op/etc"); #endif test_ztensor_bad_value_FP16( INF_FP16_POS); // is not a number, will cause overflow test_ztensor_bad_value_FP16( INF_FP16_NEG); // is not a number, will cause overflow test_ztensor_bad_value_FP16( NAN_FP16_POS); // is not a number, will cause invalid op test_ztensor_bad_value_FP16( NAN_FP16_NEG); // is not a number, will cause Invalid Op // Underflow not possible converting FP16 to DLF (VCNF) } // This routine tests the conversion from FP32 to DLFloat16 // Input: a "bad" value in FP32, which will "trip" the // floating point exception trigger on VCRNF // NOTE: Only Not-A-Number values will trip the exception. void test_ztensor_bad_value_FP32(uint32_t bad_value) { #define TOO_SMALL_FP32_POS 0x00000FF0 #define TOO_SMALL_FP32_NEG 0x80000FF0 #define TOO_LARGE_INF_FP32_POS 0x7F800000 #define TOO_LARGE_INF_FP32_NEG 0xFF800000 #define NAN_FP32_POS 0x7FFFFFFF #define NAN_FP32_NEG 0xFFFFFFFF #define STICK_ENTRIES_FP32 9 uint32_t stick_entries_to_try[STICK_ENTRIES_FP32] = {0, 1, 3, 4, 7, 8, 9, 15, 63}; zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; unsigned char *data; uint32_t *array; zdnn_status status; zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP32, &pre_tfrmd_desc, 1, 1, 1, 64); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); data = create_and_fill_random_fp_data(&ztensor); array = (uint32_t *)data; /* use data as an INT array */ for (int i = 0; i < STICK_ENTRIES_FP32; i++) { array[stick_entries_to_try[i]] = bad_value; ztensor.is_transformed = false; /* set false for next attempt, required for underflow case */ status = zdnn_transform_ztensor(&ztensor, data); if (bad_value != TOO_SMALL_FP32_NEG && bad_value != TOO_SMALL_FP32_POS) { // if not underflow case TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_CONVERT_FAILURE, "zdnn_transform_ztensor() with overflow succeeded (status = " "%08x, expects = " "%08x, i = %d, value = %08x)", status, ZDNN_CONVERT_FAILURE, i, bad_value); TEST_ASSERT_MESSAGE_FORMATTED( ztensor.is_transformed == false, "zdnn_transform_ztensor() set is_transformed (status = %08x, " "expects = %08x, i = %d, value = %08x)", status, ZDNN_CONVERT_FAILURE, i, bad_value); } else { // Must be underflow case TEST_ASSERT_MESSAGE_FORMATTED( status != ZDNN_CONVERT_FAILURE, "zdnn_transform_ztensor() with underflow did not succeed (status " "= %08x, expects = " "%08x, i = %04x, value = %08x)", status, ZDNN_CONVERT_FAILURE, i, bad_value); TEST_ASSERT_MESSAGE_FORMATTED( ztensor.is_transformed == true, "zdnn_transform_ztensor() set is_transformed (status = %08x, " "expects = %08x, i = %d, value = %08x))", status, ZDNN_CONVERT_FAILURE, i, bad_value); } array[stick_entries_to_try[i]] = 0; // set entry to 0 for next iteration } // Free allocated storage free(data); zdnn_free_ztensor_buffer(&ztensor); } void test_ztensor_fp32_bad_values() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE("needs NNPA to trigger overflow/invalid-op/etc"); #endif test_ztensor_bad_value_FP32( TOO_SMALL_FP32_POS); // non-zero converts to 0, cause underflow test_ztensor_bad_value_FP32( TOO_SMALL_FP32_NEG); // non-zero converts to 0, cause underflow test_ztensor_bad_value_FP32( TOO_LARGE_INF_FP32_POS); // is not a number, will cause overflow test_ztensor_bad_value_FP32( TOO_LARGE_INF_FP32_NEG); // is not a number, will cause overflow test_ztensor_bad_value_FP32( NAN_FP32_POS); // is not a number, will cause invalid op test_ztensor_bad_value_FP32( NAN_FP32_NEG); // is not a number, will cause invalid op } /************************************************************** * HWCK **************************************************************/ #define HWCK_TEST_WITH_FILE(h, w, c, k) \ void test_hwck_##h##x##w##x##c##x##k() { \ test_stickify(h, w, c, k, ZDNN_HWCK, FILE_OFFSETS, \ OFFSET_FILE(hwck, h, w, c, k)); \ } HWCK_TEST_WITH_FILE(1, 4, 4, 1) HWCK_TEST_WITH_FILE(1, 2, 3, 4) HWCK_TEST_WITH_FILE(2, 3, 33, 129) HWCK_TEST_WITH_FILE(1, 32, 32, 3) HWCK_TEST_WITH_FILE(1, 1, 32, 63) HWCK_TEST_WITH_FILE(1, 1, 31, 64) HWCK_TEST_WITH_FILE(1, 1, 32, 64) HWCK_TEST_WITH_FILE(1, 1, 33, 64) HWCK_TEST_WITH_FILE(1, 1, 32, 65) HWCK_TEST_WITH_FILE(1, 1, 4, 127) HWCK_TEST_WITH_FILE(1, 1, 4, 128) HWCK_TEST_WITH_FILE(1, 1, 4, 129) HWCK_TEST_WITH_FILE(1, 1, 63, 4) HWCK_TEST_WITH_FILE(1, 1, 64, 4) HWCK_TEST_WITH_FILE(1, 1, 65, 4) int main(void) { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(test_nhwc_1x4x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x4x4x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x32x32x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x32x32x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x32x32x3); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x2x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x2x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x2x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x2x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x7x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x7x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x7x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x7x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x8x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x8x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x8x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x8x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x13x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x13x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x13x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x13x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x100x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x100x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x100x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x100x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x2x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x2x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x2x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x2x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x4x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x4x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x4x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x7x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x7x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x7x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x7x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x8x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x8x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x8x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x8x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x13x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x13x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x13x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x13x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x100x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x100x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x100x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x100x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x2x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x2x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x2x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x2x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x4x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x4x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x4x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x7x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x7x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x7x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x7x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x8x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x8x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x8x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x8x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x13x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x13x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x13x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x13x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x100x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x100x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x100x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x100x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x5); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x8); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x9); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x63); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x64); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x65); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x127); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x128); // NHWC tests that use offset_files RUN_TEST_ALL_DATATYPES(test_nhwc_1x2x3x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x31x64); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x32x64); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x33x64); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x32x63); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x32x65); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x127); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x128); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x129); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x63x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x64x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x65x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x33x129); RUN_TEST_ALL_DATATYPES(test_3ds_4x4x1); RUN_TEST_ALL_DATATYPES(test_3ds_32x32x3); RUN_TEST_ALL_DATATYPES(test_2ds_4x2); RUN_TEST_ALL_DATATYPES(test_2ds_2x2049); RUN_TEST_ALL_DATATYPES(test_lstm_biases_1x4); RUN_TEST_ALL_DATATYPES(test_lstm_biases_2x4); RUN_TEST_ALL_DATATYPES(test_lstm_biases_2x65); RUN_TEST_ALL_DATATYPES(test_lstm_biases_2x2049); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_1x3x4); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_2x3x4); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_2x33x65); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_1x6x4); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x6x4); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_2x66x65); RUN_TEST_ALL_DATATYPES(test_gru_biases_1x4); RUN_TEST_ALL_DATATYPES(test_gru_biases_2x4); RUN_TEST_ALL_DATATYPES(test_gru_biases_2x65); RUN_TEST_ALL_DATATYPES(test_gru_biases_2x2049); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_1x3x4); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_2x3x4); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_2x33x65); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_1x6x4); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x6x4); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_2x66x65); RUN_TEST_ALL_DATATYPES(test_lstm_no_vconcat_weights_odd_dim2_pass); RUN_TEST_ALL_DATATYPES(test_lstm_prev_bidir_weights_odd_dim2_fail); RUN_TEST_ALL_DATATYPES(test_gru_no_vconcat_weights_odd_dim2_pass); RUN_TEST_ALL_DATATYPES(test_gru_prev_bidir_weights_odd_dim2_fail); RUN_TEST_ALL_DATATYPES(test_nchw_1x1x4x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x2x3); RUN_TEST_ALL_DATATYPES(test_nchw_1x3x32x32); RUN_TEST_ALL_DATATYPES(test_nchw_2x129x3x33); RUN_TEST_ALL_DATATYPES(test_nchw_1x63x1x32); RUN_TEST_ALL_DATATYPES(test_nchw_1x64x1x31); RUN_TEST_ALL_DATATYPES(test_nchw_1x64x1x32); RUN_TEST_ALL_DATATYPES(test_nchw_1x64x1x33); RUN_TEST_ALL_DATATYPES(test_nchw_1x65x1x32); RUN_TEST_ALL_DATATYPES(test_nchw_1x127x1x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x128x1x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x129x1x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x1x63); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x1x64); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x1x65); RUN_TEST_ALL_DATATYPES(test_nhwc_nchw_comp_1x4x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_nchw_comp_1x32x32x3); RUN_TEST_ALL_DATATYPES(test_nhwc_nchw_comp_2x3x33x129); RUN_TEST_ALL_DATATYPES(test_hwck_1x4x4x1); RUN_TEST_ALL_DATATYPES(test_hwck_1x2x3x4); RUN_TEST_ALL_DATATYPES(test_hwck_2x3x33x129); RUN_TEST_ALL_DATATYPES(test_hwck_1x32x32x3); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x32x63); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x31x64); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x32x64); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x33x64); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x32x65); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x4x127); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x4x128); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x4x129); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x63x4); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x64x4); RUN_TEST_ALL_DATATYPES(test_hwck_1x1x65x4); RUN_TEST_ALL_DATATYPES(test_ztensor_reuse_with_reset); RUN_TEST_ALL_DATATYPES(test_ztensor_reuse_without_reset); RUN_TEST_ALL_DATATYPES(test_format_after_stickify_4dfeature_success); RUN_TEST_ALL_DATATYPES(test_format_after_stickify_4dfeature_fail); RUN_TEST_ALL_DATATYPES(test_ztensor_null_buffer); RUN_TEST_ALL_DATATYPES(test_ztensor_not_enough_buffersize); RUN_TEST_ALL_DATATYPES(test_ztensor_fp16_bad_values); RUN_TEST_ALL_DATATYPES(test_ztensor_fp32_bad_values); return UNITY_END(); } ���������������������������������������zDNN-1.0.1/tests/testDriver_tensor_desc.c�����������������������������������������������������������0000664�0000000�0000000�00000045321�14364043643�0020367�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <stdio.h> #include <stdlib.h> #include <string.h> void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} // convenience routine for init and verify (pre-transformed) void set_and_verify_pre_transformed_descriptor(uint32_t dims[], zdnn_data_layouts layout, zdnn_data_types type, zdnn_status exp_status, char *error_msg) { zdnn_status status; zdnn_tensor_desc pre_tfrmd_desc; zdnn_init_pre_transformed_desc(layout, type, &pre_tfrmd_desc, dims[0], dims[1], dims[2], dims[3]); status = verify_pre_transformed_descriptor(&pre_tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED(status == exp_status, "%s (%08x)", error_msg, status); } // convenience routine for init and verify (transformed) void set_and_verify_transformed_descriptor( uint32_t dims[], zdnn_data_layouts layout, zdnn_data_types type, zdnn_data_formats format, zdnn_status exp_status, char *error_msg) { zdnn_status status; zdnn_tensor_desc tfrmd_desc; init_transformed_desc(layout, type, format, &tfrmd_desc, dims[0], dims[1], dims[2], dims[3]); status = verify_transformed_descriptor(&tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED(status == exp_status, "%s (%08x)", error_msg, status); } void verify_dims() { uint32_t max_dim_size = zdnn_get_nnpa_max_dim_idx_size(); uint32_t zero_dim[ZDNN_MAX_DIMS] = {0, 1, 1, 1}; uint32_t limit_minus1[ZDNN_MAX_DIMS] = {1, max_dim_size - 1, 1, 1}; uint32_t at_limit[ZDNN_MAX_DIMS] = {1, 1, max_dim_size, 1}; uint32_t limit_plus1[ZDNN_MAX_DIMS] = {1, 1, max_dim_size + 1, 1}; set_and_verify_transformed_descriptor( zero_dim, ZDNN_NHWC, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_INVALID_SHAPE, "Not returning ZDNN_INVALID_SHAPE for 0 dim tensor"); set_and_verify_transformed_descriptor( limit_minus1, ZDNN_NHWC, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_OK, "Not returning ZDNN_OK for below dims limit tensor"); set_and_verify_transformed_descriptor( at_limit, ZDNN_NHWC, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_OK, "Not returning ZDNN_OK for at dims limit tensor"); set_and_verify_transformed_descriptor( limit_plus1, ZDNN_NHWC, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_INVALID_SHAPE, "Not returning ZDNN_INVALID_SHAPE for above dims limit tensor"); } void verify_layout() { uint32_t dims[ZDNN_MAX_DIMS] = {1, 1, 1, 1}; // only pre-transformed descriptor cares about layout set_and_verify_pre_transformed_descriptor( dims, ZDNN_NHWC, test_datatype, ZDNN_OK, "Not returning ZDNN_OK for pre-transformed with ZDNN_NHWC"); } void verify_max_tensor_size() { uint32_t max_dim_size = zdnn_get_nnpa_max_dim_idx_size(); // try to come up with dim3 so that (1, dim3, max_dim_size, max_dim_size) // would sit right at the MAX TENSOR SIZE limit uint32_t dim3 = zdnn_get_nnpa_max_tensor_size() / (max_dim_size / AIU_STICKS_PER_PAGE) / (max_dim_size / AIU_2BYTE_CELLS_PER_STICK) / AIU_PAGESIZE_IN_BYTES; unsigned int limit_minus1[ZDNN_MAX_DIMS] = {1, dim3, max_dim_size - 1, max_dim_size}; unsigned int at_limit[ZDNN_MAX_DIMS] = {1, dim3, max_dim_size, max_dim_size}; unsigned int limit_plus1[ZDNN_MAX_DIMS] = {1, dim3, max_dim_size + 1, max_dim_size}; set_and_verify_transformed_descriptor( limit_minus1, ZDNN_NHWC, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_OK, "Not returning ZDNN_OK for below tensor size limit tensor"); set_and_verify_transformed_descriptor( at_limit, ZDNN_NHWC, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_OK, "Not returning ZDNN_OK for at tensor size limit tensor"); set_and_verify_transformed_descriptor( limit_plus1, ZDNN_NHWC, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_INVALID_SHAPE, "Not returning ZDNN_INVALID_SHAPE for above tensor size limit tensor"); } void verify_datatype_pre_tranformed() { uint32_t dims[ZDNN_MAX_DIMS] = {1, 1, 1, 1}; set_and_verify_transformed_descriptor( dims, ZDNN_NHWC, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_INVALID_TYPE, "Not returning ZDNN_INVALID_TYPE with ZDNN_NHWC"); } void verify_datatype_tranformed() { uint32_t dims[ZDNN_MAX_DIMS] = {1, 1, 1, 1}; set_and_verify_pre_transformed_descriptor( dims, ZDNN_4D, test_datatype, ZDNN_INVALID_TYPE, "Not returning ZDNN_INVALID_TYPE with ZDNN_4D"); } void verify_generated_format() { zdnn_tensor_desc pre_tfrmd_feature_desc, tfrmd_feature_desc; zdnn_tensor_desc pre_tfrmd_kernel_desc, tfrmd_kernel_desc; zdnn_init_pre_transformed_desc(ZDNN_NHWC, test_datatype, &pre_tfrmd_feature_desc, 1, 1, 1, 1); zdnn_init_pre_transformed_desc(ZDNN_HWCK, test_datatype, &pre_tfrmd_kernel_desc, 1, 1, 1, 1); zdnn_generate_transformed_desc(&pre_tfrmd_feature_desc, &tfrmd_feature_desc); zdnn_generate_transformed_desc(&pre_tfrmd_kernel_desc, &tfrmd_kernel_desc); TEST_ASSERT_MESSAGE(tfrmd_feature_desc.format == ZDNN_FORMAT_4DFEATURE, "tfrmd_feature_desc doesn't have correct format set"); TEST_ASSERT_MESSAGE(tfrmd_kernel_desc.format == ZDNN_FORMAT_4DKERNEL, "tfrmd_kernel_desc doesn't have correct format set"); } #define BAD_FORMAT 255 #define BAD_LAYOUT 255 void format_undefined_fail() { uint32_t dims[ZDNN_MAX_DIMS] = {1, 1, 1, 1}; set_and_verify_transformed_descriptor( dims, ZDNN_NHWC, test_datatype, BAD_FORMAT, ZDNN_INVALID_FORMAT, "BAD_FORMAT doesn't yield ZDNN_INVALID_FORMAT"); } void format_feature_layout_notagree_fail() { uint32_t dims[ZDNN_MAX_DIMS] = {1, 1, 1, 1}; set_and_verify_transformed_descriptor( dims, ZDNN_HWCK, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_INVALID_LAYOUT, "ZDNN_FORMAT_4DFEATURE + ZDNN_HWCK doesn't yield ZDNN_INVALID_LAYOUT"); } void format_kernel_layout_notagree_fail() { uint32_t dims[ZDNN_MAX_DIMS] = {1, 1, 1, 1}; set_and_verify_transformed_descriptor( dims, ZDNN_NHWC, test_datatype, ZDNN_FORMAT_4DKERNEL, ZDNN_INVALID_LAYOUT, "ZDNN_FORMAT_4DKERNEL + ZDNN_NHWC doesn't yield ZDNN_INVALID_LAYOUT"); } void format_feature_layout_undefined_fail() { uint32_t dims[ZDNN_MAX_DIMS] = {1, 1, 1, 1}; set_and_verify_transformed_descriptor( dims, BAD_LAYOUT, test_datatype, ZDNN_FORMAT_4DFEATURE, ZDNN_INVALID_LAYOUT, "ZDNN_FORMAT_4DFEATURE + undefined layout doesn't yield " "ZDNN_INVALID_LAYOUT"); } void format_kernel_layout_undefined_fail() { uint32_t dims[ZDNN_MAX_DIMS] = {1, 1, 1, 1}; set_and_verify_transformed_descriptor( dims, BAD_LAYOUT, test_datatype, ZDNN_FORMAT_4DKERNEL, ZDNN_INVALID_LAYOUT, "ZDNN_FORMAT_4DKERNEL + undefined layout doesn't yield " "ZDNN_INVALID_LAYOUT"); } void verify_ztensor_slicing(uint32_t num_slices, uint32_t *shape, zdnn_data_layouts layout, size_t buffer_size, zdnn_status exp_status) { uint64_t num_elements; switch (layout) { // 1D isn't valid as it has no dim4. Used for negative test case. case (ZDNN_1D): num_elements = shape[0]; break; case (ZDNN_2DS): num_elements = shape[0] * shape[1]; break; case (ZDNN_3DS): num_elements = shape[0] * shape[1] * shape[2]; break; case (ZDNN_4D): case (ZDNN_NHWC): case (ZDNN_NCHW): num_elements = shape[0] * shape[1] * shape[2] * shape[3]; break; default: TEST_FAIL_MESSAGE_FORMATTED( "I'm dreadfully sorry but I don't seem to know how to deal with a %s " "layout. Could you teach me?", get_data_layout_str(layout)); break; } uint64_t num_slice_elements = num_elements / num_slices; float values[num_elements]; gen_random_float_array(num_elements, values); zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( shape, layout, test_datatype, NO_CONCAT, false, values); // Print out the sliced ztensor BEGIN_BLOCK_IF_LOGLEVEL_TRACE { printf("%s() with type %s: dumpdata_ztensor of unsliced input\n", __func__, get_data_type_str(test_datatype)); dumpdata_ztensor(input_ztensor, AS_FLOAT, false); } // Make copies of the original input to confirm it isn't altered later. zdnn_ztensor copy_input_ztensor; zdnn_tensor_desc copy_pre_trfmd_desc; zdnn_tensor_desc copy_trfmd_desc; memcpy(©_input_ztensor, input_ztensor, sizeof(zdnn_ztensor)); memcpy(©_pre_trfmd_desc, input_ztensor->pre_transformed_desc, sizeof(zdnn_tensor_desc)); memcpy(©_trfmd_desc, input_ztensor->transformed_desc, sizeof(zdnn_tensor_desc)); // Create output structs zdnn_tensor_desc output_pre_tfrmd_desc[num_slices]; zdnn_tensor_desc output_tfrmd_desc[num_slices]; zdnn_ztensor output_ztensors[num_slices]; // Slice the input and if we expect it to succeed, check that values in each // slice matches the expected values for that slice. for (uint32_t slice = 0; slice < num_slices; slice++) { zdnn_status status = ztensor_slice_dim4( input_ztensor, slice, buffer_size, &output_pre_tfrmd_desc[slice], &output_tfrmd_desc[slice], &output_ztensors[slice]); TEST_ASSERT_MESSAGE_FORMATTED(status == exp_status, "ztensor_slice_dim4() on slice %u failed, " "status = %08x (%s)", slice, status, zdnn_get_status_message(status)); // Only test that output values are valid in positive test cases if (exp_status == ZDNN_OK) { // Print out the sliced ztensor BEGIN_BLOCK_IF_LOGLEVEL_TRACE { printf("%s() with type %s: dumpdata_ztensor of slice %u\n", __func__, get_data_type_str(test_datatype), slice); dumpdata_ztensor(&output_ztensors[slice], AS_FLOAT, false); } // Check output buffer_size matches the specified value or calculated // value if a size wasn't specified. size_t expected_buffer_size; if (buffer_size) { expected_buffer_size = buffer_size; } else { expected_buffer_size = zdnn_getsize_ztensor(input_ztensor->transformed_desc) / num_slices; } TEST_ASSERT_MESSAGE_FORMATTED( expected_buffer_size == output_ztensors[slice].buffer_size, "expected sliced buffer_size to be %" PRIu64 " but found %" PRIu64, expected_buffer_size, output_ztensors[slice].buffer_size); // Check that slice's values match the expected portion of the input assert_ztensor_values(&output_ztensors[slice], false, &values[slice * num_slice_elements]); } } // Confirm input structs weren't altered during slicing TEST_ASSERT_MESSAGE( memcmp(input_ztensor, ©_input_ztensor, sizeof(zdnn_ztensor)) == 0, "input_ztensor was unexpectedly altered"); TEST_ASSERT_MESSAGE( memcmp(input_ztensor->pre_transformed_desc, ©_pre_trfmd_desc, sizeof(zdnn_tensor_desc)) == 0, "input_ztensor->pre_transformed_desc was unexpectedly altered"); TEST_ASSERT_MESSAGE( memcmp(input_ztensor->transformed_desc, ©_trfmd_desc, sizeof(zdnn_tensor_desc)) == 0, "input_ztensor->transformed_desc was unexpectedly altered"); // Cleanup allocations free(input_ztensor); } void test_slicing_specified_buffer() { uint32_t num_slices = 5; uint32_t shape[] = {num_slices, 2049}; size_t specified_buffer = 135168; verify_ztensor_slicing(num_slices, shape, ZDNN_2DS, specified_buffer, ZDNN_OK); } void test_slicing_fail_input_has_only_one_dim4() { uint32_t num_slices = 1; uint32_t shape[] = {num_slices, 2049}; verify_ztensor_slicing(num_slices, shape, ZDNN_2DS, 0, ZDNN_INVALID_SHAPE); } void test_slicing_fail_too_many_slices() { uint32_t num_slices = 2; uint32_t shape[] = {num_slices, 2049}; // Create input ztensor zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( shape, ZDNN_2DS, test_datatype, NO_CONCAT, true, ZERO_ARRAY); // Create output structs zdnn_tensor_desc output_pre_tfrmd_desc; zdnn_tensor_desc output_tfrmd_desc; zdnn_ztensor output_ztensors; // idx is 0 indexed so this should fail because it's too large uint32_t slice_idx = num_slices; // Confirm expected failure status zdnn_status status = ztensor_slice_dim4(input_ztensor, slice_idx, 0, &output_pre_tfrmd_desc, &output_tfrmd_desc, &output_ztensors); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_INVALID_SHAPE, "ztensor_slice_dim4() on slice_idx %u failed, status = %08x (%s)", slice_idx, status, zdnn_get_status_message(status)); } void test_slicing_1D_fail() { uint32_t num_slices = 2; uint32_t shape[] = {num_slices}; verify_ztensor_slicing(num_slices, shape, ZDNN_1D, 0, ZDNN_INVALID_LAYOUT); } void test_slicing_2DS_5x2049() { uint32_t num_slices = 5; uint32_t shape[] = {num_slices, 2049}; verify_ztensor_slicing(num_slices, shape, ZDNN_2DS, 0, ZDNN_OK); } void test_slicing_3DS_5x33x65() { uint32_t num_slices = 5; uint32_t shape[] = {num_slices, 33, 65}; verify_ztensor_slicing(num_slices, shape, ZDNN_3DS, 0, ZDNN_OK); } void verify_transformed_layout(zdnn_data_layouts from_layout, bool is_concat, uint32_t dim4, uint32_t dim3, uint32_t dim2, uint32_t dim1, zdnn_data_layouts exp_to_layout, zdnn_status exp_status) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_status status; switch (from_layout) { case ZDNN_2DS: zdnn_init_pre_transformed_desc(from_layout, test_datatype, &pre_tfrmd_desc, dim2, dim1); break; case ZDNN_3DS: zdnn_init_pre_transformed_desc(from_layout, test_datatype, &pre_tfrmd_desc, dim3, dim2, dim1); break; case ZDNN_4DS: zdnn_init_pre_transformed_desc(from_layout, test_datatype, &pre_tfrmd_desc, dim4, dim2, dim1); break; default: TEST_FAIL_MESSAGE_FORMATTED("unknown from_layout %d", from_layout); } if (!is_concat) { status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); } else { if (from_layout == ZDNN_2DS) { status = zdnn_generate_transformed_desc_concatenated( &pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_BIASES | PREV_LAYER_NONE, &tfrmd_desc); } else if (from_layout == ZDNN_3DS) { status = zdnn_generate_transformed_desc_concatenated( &pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_NONE, &tfrmd_desc); } else { // error test: caller will attempt to do is_concat = true with something // other than 2DS/3DS status = zdnn_generate_transformed_desc_concatenated( &pre_tfrmd_desc, RNN_TYPE_LSTM | USAGE_HIDDEN_WEIGHTS | PREV_LAYER_UNI, &tfrmd_desc); } } TEST_ASSERT_MESSAGE_FORMATTED( status == exp_status, "zdnn_generate_transformed_desc(_concatenated)() returned " "status %08x \"%s\" but expected %08x \"%s\"", status, zdnn_get_status_message(status), exp_status, zdnn_get_status_message(exp_status)); if (exp_status == ZDNN_OK) { TEST_ASSERT_MESSAGE_FORMATTED( tfrmd_desc.layout == exp_to_layout, "transformed layout is not %s (%d), found %s (%d)", get_data_layout_str(exp_to_layout), exp_to_layout, get_data_layout_str(tfrmd_desc.layout), tfrmd_desc.layout); } } void verify_2ds_transformed_layout_normal() { verify_transformed_layout(ZDNN_2DS, false, 9999, 9999, 1, 1, ZDNN_NHWC, ZDNN_OK); } void verify_2ds_transformed_layout_concat() { verify_transformed_layout(ZDNN_2DS, true, 9999, 9999, 1, 1, ZDNN_FICO, ZDNN_OK); } void verify_3ds_transformed_layout_normal() { verify_transformed_layout(ZDNN_3DS, false, 9999, 1, 1, 1, ZDNN_NHWC, ZDNN_OK); } void verify_3ds_transformed_layout_concat() { verify_transformed_layout(ZDNN_3DS, true, 9999, 1, 1, 1, ZDNN_FICO, ZDNN_OK); } void verify_4ds_transformed_layout_normal() { verify_transformed_layout(ZDNN_4DS, false, 1, 1, 1, 1, ZDNN_NHWC, ZDNN_OK); } void verify_4ds_transformed_layout_concat_fail() { // exp_to_layout does not matter, supposed to error out verify_transformed_layout(ZDNN_4DS, true, 1, 1, 1, 1, ZDNN_NHWC, ZDNN_INVALID_LAYOUT); } // ------------------------------------------------------------------------------------------------ int main(void) { UNITY_BEGIN(); RUN_TEST_ALL_TFRMD_DATATYPES(verify_dims); RUN_TEST_ALL_DATATYPES(verify_layout); RUN_TEST_ALL_TFRMD_DATATYPES(verify_max_tensor_size); // test all data-types possible RUN_TEST_ALL_DATATYPES(verify_datatype_pre_tranformed); RUN_TEST_ALL_TFRMD_DATATYPES(verify_datatype_tranformed); RUN_TEST_ALL_TFRMD_DATATYPES(verify_generated_format); RUN_TEST_ALL_TFRMD_DATATYPES(format_undefined_fail); RUN_TEST_ALL_TFRMD_DATATYPES(format_feature_layout_notagree_fail); RUN_TEST_ALL_TFRMD_DATATYPES(format_kernel_layout_notagree_fail); RUN_TEST_ALL_TFRMD_DATATYPES(format_feature_layout_undefined_fail); RUN_TEST_ALL_TFRMD_DATATYPES(format_kernel_layout_undefined_fail); RUN_TEST_ALL_TFRMD_DATATYPES(verify_2ds_transformed_layout_normal); RUN_TEST_ALL_TFRMD_DATATYPES(verify_2ds_transformed_layout_concat); RUN_TEST_ALL_TFRMD_DATATYPES(verify_3ds_transformed_layout_normal); RUN_TEST_ALL_TFRMD_DATATYPES(verify_3ds_transformed_layout_concat); RUN_TEST_ALL_TFRMD_DATATYPES(verify_4ds_transformed_layout_normal); RUN_TEST_ALL_TFRMD_DATATYPES(verify_4ds_transformed_layout_concat_fail); RUN_TEST_ALL_DATATYPES(test_slicing_specified_buffer); RUN_TEST_ALL_DATATYPES(test_slicing_fail_input_has_only_one_dim4); RUN_TEST_ALL_DATATYPES(test_slicing_fail_too_many_slices); RUN_TEST_ALL_DATATYPES(test_slicing_1D_fail); RUN_TEST_ALL_DATATYPES(test_slicing_2DS_5x2049); RUN_TEST_ALL_DATATYPES(test_slicing_3DS_5x33x65); return UNITY_END(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_tensor_verify.c���������������������������������������������������������0000664�0000000�0000000�00000132462�14364043643�0020760�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> void setUp(void) { /* This is run before EACH TEST */ } void tearDown(void) {} /* * Test ztensor format when created and updated. */ void verify_ztensor_format() { VERIFY_HW_ENV; // verify required HW env is available. zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; void *data; uint32_t dim4 = 1, dim3 = 4, dim2 = 4, dim1 = 1; zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP32, &pre_tfrmd_desc, dim4, dim3, dim2, dim1); status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() failed (status = %08x)", status); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc() failed (status = %08x)", status); // verify proper state of is_transformed field after ztensor created TEST_ASSERT_MESSAGE( false == ztensor.is_transformed, "Expected ztensor to indicate transform not completed yet."); data = create_and_fill_random_fp_data(&ztensor); // transform the app tensor's data into stickified data LOG_DEBUG("about to transform ztensor", NO_ARG); status = zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE(ZDNN_OK == status, "zdnn_transform_ztensor did not return OK as expected"); // verify proper state of is_transformed field after ztensor has stickified // data TEST_ASSERT_MESSAGE(true == ztensor.is_transformed, "Expected ztensor to indicate transform was completed."); // Free allocated storage free(data); zdnn_free_ztensor_buffer(&ztensor); } /// Common test routine for normal tensors /// /// \param[in] num_inputs Number of input tensors /// \param[in] input_shape_lst Pointer to array of pointers to input dim /// arrays /// \param[in] input_format_lst Pointer to array of input formats /// \param[in] input_type_lst Pointer to array of input types /// \param[in] num_outputs Number of output tensors /// \param[in] output_shape_lst Pointer to array of pointers to output dim /// arrays /// \param[in] output_format_lst Pointer to array of output formats /// \param[in] output_type_lst Pointer to array of output types /// \param[in] exp_status Expected status /// \param[in] error_msg Error message to prepend to the standard error /// message /// void test_normal(uint8_t num_inputs, uint32_t **input_shape_lst, zdnn_data_formats *input_format_lst, zdnn_data_types *input_type_lst, uint8_t num_outputs, uint32_t **output_shape_lst, zdnn_data_formats *output_format_lst, zdnn_data_types *output_type_lst, zdnn_status exp_status, char *error_msg) { zdnn_ztensor input_ztensor[num_inputs]; zdnn_ztensor output_ztensor[num_outputs]; zdnn_status status = ZDNN_OK; // allocate a transformed descriptor with input_shape_lst[i], // input_format_lst[i] and input_type_lst[i] for (int i = 0; i < num_inputs; i++) { uint32_t *shape = input_shape_lst[i]; input_ztensor[i].transformed_desc = malloc(sizeof(zdnn_tensor_desc)); init_transformed_desc( input_format_lst[i] == ZDNN_FORMAT_4DFEATURE ? ZDNN_NHWC : ZDNN_HWCK, input_type_lst[i], input_format_lst[i], input_ztensor[i].transformed_desc, shape[0], shape[1], shape[2], shape[3]); } // same idea with the outputs for (int i = 0; i < num_outputs; i++) { uint32_t *shape = output_shape_lst[i]; output_ztensor[i].transformed_desc = malloc(sizeof(zdnn_tensor_desc)); init_transformed_desc( output_format_lst[i] == ZDNN_FORMAT_4DFEATURE ? ZDNN_NHWC : ZDNN_HWCK, output_type_lst[i], output_format_lst[i], output_ztensor[i].transformed_desc, shape[0], shape[1], shape[2], shape[3]); } // number of inputs to send to verify_tensors() depends on num_inputs status = verify_tensors( &input_ztensor[0], (num_inputs > 1) ? &input_ztensor[1] : NULL, (num_inputs > 2) ? &input_ztensor[2] : NULL, &output_ztensor[0]); TEST_ASSERT_MESSAGE_FORMATTED( exp_status == status, "%s Expected status = %08x, actual status = %08x", error_msg, exp_status, status); for (int i = 0; i < num_inputs; i++) { free(input_ztensor[i].transformed_desc); } for (int i = 0; i < num_outputs; i++) { free(output_ztensor[i].transformed_desc); } } /* * Test verification of valid output tensor along with an input tensor. * All tensors will be built with same properties. */ void verify_1input_pass() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t *input_shape_lst[] = {io_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(1, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_OK, "The output and the input tensor is different."); } /* * Test verification of valid output tensor along with 2 input tensors. * All tensors will be built with same properties. */ void verify_2input_pass() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t *input_shape_lst[] = {io_shape, io_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = {ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(2, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_OK, "The output and the input tensors are different."); } /* * Test verification of valid output tensor along with 3 input tensors. * All tensors will be built with same properties. */ void verify_3input_pass() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t *input_shape_lst[] = {io_shape, io_shape, io_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(3, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_OK, "The output and the input tensors are different."); } /* * Test verification of different shapes between 2 input tensors. * Input tensors will have different shapes. * Output tensor will have same properties as Input tensor 1. */ void verify_input2_fail_shape() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t different_shape[ZDNN_MAX_DIMS] = {1, 2, 3, 4}; uint32_t *input_shape_lst[] = {io_shape, different_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = {ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(2, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_INVALID_SHAPE, "Failed to fail on different input tensor shapes."); } /* * Test verification of different shapes between 3 input tensors. * Input tensor 3 will have different shapes. * Output tensor will have same properties as Input tensor 1 and 2. */ void verify_input3_fail_shape() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t different_shape[ZDNN_MAX_DIMS] = {1, 2, 3, 4}; uint32_t *input_shape_lst[] = {io_shape, io_shape, different_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(3, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_INVALID_SHAPE, "Failed to fail on different input tensor shapes."); } /* * Test verification of different data formats between 2 input tensors. * Input tensors will have different data formats. * Output tensor will have same properties as Input tensor 1. */ void verify_input2_fail_format() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t *input_shape_lst[] = {io_shape, io_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = {ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DKERNEL}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(2, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_INVALID_FORMAT, "Failed to fail on different input tensor data formats."); } /* * Test verification of different data formats between 3 input tensors. * Input tensor 3 will have different data formats. * Output tensor will have same properties as Input tensor 1 and 2. */ void verify_input3_fail_format() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t *input_shape_lst[] = {io_shape, io_shape, io_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DKERNEL}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(3, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_INVALID_FORMAT, "Failed to fail on different input tensor data formats."); } /* * Test verification of different data types between 2 input tensors. * Input tensors will have different data types. * Output tensor will have same properties as Input tensor 1. */ void verify_input2_fail_dtype() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t *input_shape_lst[] = {io_shape, io_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, FP32}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = {ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(2, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_INVALID_TYPE, "Failed to fail on different input tensor data types."); } /* * Test verification of different data types between 3 input tensors. * Input tensor 3 will have different data type. * Output tensor will have same properties as Input tensor 1 and 2. */ void verify_input3_fail_dtype() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t *input_shape_lst[] = {io_shape, io_shape, io_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, FP32}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(3, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_INVALID_TYPE, "Failed to fail on different input tensor data types."); } /* * Test verification of different shapes between output and input tensor. * Input and Output tensor will have a different shape. */ void verify_output_fail_shape() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t different_shape[ZDNN_MAX_DIMS] = {1, 2, 3, 4}; uint32_t *input_shape_lst[] = {io_shape}; uint32_t *output_shape_lst[] = {different_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(1, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_INVALID_SHAPE, "Failed to fail on different output/input tensor shapes."); } /* * Test verification of different data format between output and input * tensors. Both input tensors will the same properties. Output tensor will * have a different data format. */ void verify_output_fail_format() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t *input_shape_lst[] = {io_shape, io_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {ZDNN_DLFLOAT16}; zdnn_data_formats input_format_lst[] = {ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DKERNEL}; test_normal(2, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_INVALID_FORMAT, "Failed to fail on different output/input tensor data formats."); } /* * Test verification of different data types between output and input tensors. * All three input tensors will have the same properties. * Output tensor will have a different data type. */ void verify_output_fail_dtype() { uint32_t io_shape[ZDNN_MAX_DIMS] = {1, 1, 4, 3}; uint32_t *input_shape_lst[] = {io_shape, io_shape, io_shape}; uint32_t *output_shape_lst[] = {io_shape}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_types output_type_lst[] = {FP32}; zdnn_data_formats input_format_lst[] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_formats output_format_lst[] = {ZDNN_FORMAT_4DFEATURE}; test_normal(3, input_shape_lst, input_format_lst, input_type_lst, 1, output_shape_lst, output_format_lst, output_type_lst, ZDNN_INVALID_TYPE, "Failed to fail on different output/input tensor data types."); } #define MATMUL_NUM_INPUTS 3 /// Common test routine for matmul op + mutmul bcast op tensors /// /// \param[in] uint8_t function_code, /// NNPA_MATMUL_OP or NNPA_MATMUL_OP_BCAST23 /// \param[in] input_shape_lst /// 2D array, MATMUL_NUM_INPUTS x ZDNN_MAX_DIMS number of /// dimensions /// \param[in] input_shape_displace_lst /// MATMUL_NUM_INPUTS x ZDNN_MAX_DIMS number of /// displacement for each of the entries in input_shape_lst /// (e.g., +1, +5, -3, etc) /// \param[in] input_format_lst /// array, MATMUL_NUM_INPUTS number of entries of formats /// \param[in] input_type_lst /// array, MATMUL_NUM_INPUTS number of entries of types /// \param[in] output_shape /// 1D array, ZDNN_MAX_DIMS number of dimensions /// \param[in] output_shape_displace /// ZDNN_MAX_DIMS number of displacement for each of the /// entries in output_shape /// \param[in] output_format output format /// \param[in] output_type output type /// \param[in] exp_status Expected status /// void test_matmul( uint8_t function_code, uint32_t input_shape_lst[MATMUL_NUM_INPUTS][ZDNN_MAX_DIMS], int32_t input_shape_displace_lst[MATMUL_NUM_INPUTS][ZDNN_MAX_DIMS], zdnn_data_formats *input_format_lst, zdnn_data_types *input_type_lst, uint32_t *output_shape, int32_t *output_shape_displace, zdnn_data_formats output_format, zdnn_data_types output_type, zdnn_status exp_status) { zdnn_ztensor input_ztensor[MATMUL_NUM_INPUTS]; zdnn_ztensor output_ztensor; zdnn_status status = ZDNN_OK; /* create MATMUL_NUM_INPUTS numbers of transformed descriptors, using: input_shape_lst[i] + input_shape_displace_lst[i] as shape e.g., input_shape_lst[i] = {1, 2, 3, 4} input_shape_displace_lst[i] = {0, 1, -1, 5} resultant to init_transformed_desc() = { 1 + 0 = 1, 2 + 1 = 3, 3 + -1 = 2, 4 + 5 = 9 } input_format_lst[i] as format input_type_lst[i] as type */ for (int i = 0; i < MATMUL_NUM_INPUTS; i++) { input_ztensor[i].transformed_desc = malloc(sizeof(zdnn_tensor_desc)); LOG_DEBUG("input %d -> format %d, type %d\n", i, input_format_lst[i], input_type_lst[i]); LOG_DEBUG(" dim4 %d, displace %d\n", input_shape_lst[i][0], input_shape_displace_lst[i][0]); LOG_DEBUG(" dim3 %d, displace %d\n", input_shape_lst[i][1], input_shape_displace_lst[i][1]); LOG_DEBUG(" dim2 %d, displace %d\n", input_shape_lst[i][2], input_shape_displace_lst[i][2]); LOG_DEBUG(" dim1 %d, displace %d\n", input_shape_lst[i][3], input_shape_displace_lst[i][3]); init_transformed_desc( input_format_lst[i] == ZDNN_FORMAT_4DFEATURE ? ZDNN_NHWC : ZDNN_HWCK, input_type_lst[i], input_format_lst[i], input_ztensor[i].transformed_desc, input_shape_lst[i][0] + input_shape_displace_lst[i][0], input_shape_lst[i][1] + input_shape_displace_lst[i][1], input_shape_lst[i][2] + input_shape_displace_lst[i][2], input_shape_lst[i][3] + input_shape_displace_lst[i][3]); } LOG_DEBUG("output -> format %d, type %d\n", output_format, output_type); LOG_DEBUG(" dim4 %d, displace %d\n", output_shape[0], output_shape_displace[0]); LOG_DEBUG(" dim3 %d, displace %d\n", output_shape[1], output_shape_displace[1]); LOG_DEBUG(" dim2 %d, displace %d\n", output_shape[2], output_shape_displace[2]); LOG_DEBUG(" dim1 %d, displace %d\n", output_shape[3], output_shape_displace[3]); output_ztensor.transformed_desc = malloc(sizeof(zdnn_tensor_desc)); init_transformed_desc( output_format == ZDNN_FORMAT_4DFEATURE ? ZDNN_NHWC : ZDNN_HWCK, output_type, output_format, output_ztensor.transformed_desc, output_shape[0] + output_shape_displace[0], output_shape[1] + output_shape_displace[1], output_shape[2] + output_shape_displace[2], output_shape[3] + output_shape_displace[3]); if (function_code == NNPA_MATMUL_OP) status = verify_matmul_op_tensors(&input_ztensor[0], &input_ztensor[1], &input_ztensor[2], &output_ztensor); else if (function_code == NNPA_MATMUL_OP_BCAST23) { status = verify_matmul_bcast_op_tensors(&input_ztensor[0], &input_ztensor[1], &input_ztensor[2], &output_ztensor); } else { TEST_FAIL_MESSAGE("unknown mode"); } TEST_ASSERT_MESSAGE_FORMATTED(exp_status == status, "Expected status = %08x, actual status = %08x", exp_status, status); for (int i = 0; i < MATMUL_NUM_INPUTS; i++) { free(input_ztensor[i].transformed_desc); } free(output_ztensor.transformed_desc); } void test_matmul_third( int32_t input_shape_displace_lst[MATMUL_NUM_INPUTS][ZDNN_MAX_DIMS], zdnn_data_formats *input_format_lst, zdnn_data_types *input_type_lst, int32_t *output_shape_displace, zdnn_data_formats output_format, zdnn_data_types output_type, zdnn_status exp_status) { uint32_t matmul_op_first_shape[ZDNN_MAX_DIMS] = {4, 1, 16, 8}; uint32_t matmul_op_second_shape[ZDNN_MAX_DIMS] = {4, 1, 8, 4}; uint32_t matmul_op_third_shape[ZDNN_MAX_DIMS] = {4, 1, 1, 4}; // concatenate the 1D arrays into 2D input for test_matmul() uint32_t input_shape_lst[MATMUL_NUM_INPUTS][ZDNN_MAX_DIMS]; memcpy(input_shape_lst[0], matmul_op_first_shape, sizeof(uint32_t) * ZDNN_MAX_DIMS); memcpy(input_shape_lst[1], matmul_op_second_shape, sizeof(uint32_t) * ZDNN_MAX_DIMS); memcpy(input_shape_lst[2], matmul_op_third_shape, sizeof(uint32_t) * ZDNN_MAX_DIMS); uint32_t matmul_op_result_shape[ZDNN_MAX_DIMS] = {4, 1, 16, 4}; test_matmul(NNPA_MATMUL_OP, input_shape_lst, input_shape_displace_lst, input_format_lst, input_type_lst, matmul_op_result_shape, output_shape_displace, output_format, output_type, exp_status); } void test_matmul_bcast_op( int32_t input_shape_displace_lst[MATMUL_NUM_INPUTS][ZDNN_MAX_DIMS], zdnn_data_formats *input_format_lst, zdnn_data_types *input_type_lst, int32_t *output_shape_displace, zdnn_data_formats output_format, zdnn_data_types output_type, zdnn_status exp_status) { uint32_t feature = 32, batch = 4, spad_x4 = 256, timestep = 4; uint32_t input_shape[ZDNN_MAX_DIMS] = {timestep, 1, batch, feature}; uint32_t weights_shape[ZDNN_MAX_DIMS] = {1, 1, feature, spad_x4}; uint32_t bias_shape[ZDNN_MAX_DIMS] = {1, 1, 1, spad_x4}; // concatenate the 1D arrays into 2D input for test_matmul() uint32_t input_shape_lst[MATMUL_NUM_INPUTS][ZDNN_MAX_DIMS]; memcpy(input_shape_lst[0], input_shape, sizeof(uint32_t) * ZDNN_MAX_DIMS); memcpy(input_shape_lst[1], weights_shape, sizeof(uint32_t) * ZDNN_MAX_DIMS); memcpy(input_shape_lst[2], bias_shape, sizeof(uint32_t) * ZDNN_MAX_DIMS); uint32_t fused_shape[ZDNN_MAX_DIMS] = {timestep, 1, batch, spad_x4}; test_matmul(NNPA_MATMUL_OP_BCAST23, input_shape_lst, input_shape_displace_lst, input_format_lst, input_type_lst, fused_shape, output_shape_displace, output_format, output_type, exp_status); } /* * Test verification of valid matmul third tensors. * All tensors will be built with acceptable properties. */ void verify_matmul_op_pass() { int32_t input_shape_displace_lst[MATMUL_NUM_INPUTS][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; test_matmul_third(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_OK); } /* * Test verification of failed matmul op output shape. * All input tensors will have acceptable descriptors. * Output will have invalid number in i-th dimension. */ void verify_matmul_op_fail_output_shape() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; for (int i = 0; i < ZDNN_MAX_DIMS; i++) { int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; output_shape_displace[i] = 1; test_matmul_third(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_SHAPE); } } /* * Test verification of failed matmul op third input shape. * Output will have valid descriptor. * Input j will have a bad i-th dimension. */ void verify_matmul_op_fail_input_shape() { zdnn_data_formats input_format_lst[] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; for (int j = 0; j < MATMUL_NUM_INPUTS; j++) { for (int i = 0; i < ZDNN_MAX_DIMS; i++) { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; input_shape_displace_lst[j][i] = 1; test_matmul_third(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_SHAPE); } } } /* * Test verification of failed matmul op output format. * All input tensors will have acceptable descriptors. * Output will have mismatched format. */ void verify_matmul_op_fail_output_format() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DKERNEL; zdnn_data_types output_type = ZDNN_DLFLOAT16; test_matmul_third(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_FORMAT); } /* * Test verification of failed matmul op third input format. * Output will have valid descriptor. * Input i will have a different format. */ void verify_matmul_op_fail_input_format() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; for (int i = 0; i < MATMUL_NUM_INPUTS; i++) { zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; input_format_lst[i] = ZDNN_FORMAT_4DKERNEL; test_matmul_third(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_FORMAT); } } /* * Test verification of failed matmul op output type. * All input tensors will have acceptable descriptors. * Output will have mismatched type. */ void verify_matmul_op_fail_output_type() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = FP32; test_matmul_third(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_TYPE); } /* * Test verification of failed matmul third input type. * Output will have valid descriptor. * Input i will have a different type. */ void verify_matmul_op_fail_input_type() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; for (int i = 0; i < MATMUL_NUM_INPUTS; i++) { zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; input_type_lst[i] = FP32; test_matmul_third(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_TYPE); } } /* * Test verification of valid matmul bcast op tensors. * All tensors will be built with acceptable properties. */ void verify_matmul_bcast_op_pass() { int32_t input_shape_displace_lst[MATMUL_NUM_INPUTS][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; test_matmul_bcast_op(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_OK); } /* * Test verification of failed matmul bcast op output shape. * All input tensors will have acceptable descriptors. * Output will have invalid number in i-th dimension. */ void verify_matmul_bcast_op_fail_output_shape() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; for (int i = 0; i < ZDNN_MAX_DIMS; i++) { int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; output_shape_displace[i] = 1; test_matmul_bcast_op(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_SHAPE); } } /* * Test verification of failed matmul bcast op input shape. * Output will have valid descriptor. * Input j will have a bad i-th dimension. */ void verify_matmul_bcast_op_fail_input_shape() { zdnn_data_formats input_format_lst[] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[] = {ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; for (int j = 0; j < MATMUL_NUM_INPUTS; j++) { for (int i = 0; i < ZDNN_MAX_DIMS; i++) { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; input_shape_displace_lst[j][i] = 1; test_matmul_bcast_op(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_SHAPE); } } } /* * Test verification of failed matmul bcast op input format. * All input/output tensors will have acceptable descriptors, except * input2 will have mismatched format. */ void verify_matmul_bcast_op_fail_input_format() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DKERNEL, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; test_matmul_bcast_op(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_FORMAT); } /* * Test verification of failed matmul bcast op output format. * All input tensors will have acceptable descriptors. * Output will have mismatched format. */ void verify_matmul_bcast_op_fail_output_format() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DKERNEL; zdnn_data_types output_type = ZDNN_DLFLOAT16; test_matmul_bcast_op(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_FORMAT); } /* * Test verification of failed matmul bcast op output type. * All input tensors will have acceptable descriptors. * Output will have mismatched type. */ void verify_matmul_bcast_op_fail_output_type() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = FP32; test_matmul_bcast_op(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_TYPE); } /* * Test verification of failed matmul bcast op input type. * Output will have valid descriptor. * Input i will have a different type. */ void verify_matmul_bcast_op_fail_input_type() { int32_t input_shape_displace_lst[][ZDNN_MAX_DIMS] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; zdnn_data_formats input_format_lst[MATMUL_NUM_INPUTS] = { ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE, ZDNN_FORMAT_4DFEATURE}; int32_t output_shape_displace[ZDNN_MAX_DIMS] = {0, 0, 0, 0}; zdnn_data_formats output_format = ZDNN_FORMAT_4DFEATURE; zdnn_data_types output_type = ZDNN_DLFLOAT16; for (int i = 0; i < MATMUL_NUM_INPUTS; i++) { zdnn_data_types input_type_lst[MATMUL_NUM_INPUTS] = { ZDNN_DLFLOAT16, ZDNN_DLFLOAT16, ZDNN_DLFLOAT16}; input_type_lst[i] = FP32; test_matmul_bcast_op(input_shape_displace_lst, input_format_lst, input_type_lst, output_shape_displace, output_format, output_type, ZDNN_INVALID_TYPE); } } /// Common test routine for batchnorm tensors /// /// \param[in] sbtg_input_b_dim_idx /// which dimension (4, 3, 2 or 1) of scale tensor shape to /// sabotage, set to 0 if nothing to sabotage /// \param[in] sbtg_input_b_val scale tensor sabotage value /// \param[in] sbtg_input_c_dim_idx /// which dimension (4, 3, 2 or 1) of bias tensor shape to /// sabotage, set to 0 if nothing to sabotage /// \param[in] sbtg_input_c_val bias tensor sabotage value /// \param[in] exp_status Expected status /// void test_batchnorm(uint8_t sbtg_input_b_dim_idx, uint32_t sbtg_input_b_val, int8_t sbtg_input_c_dim_idx, uint32_t sbtg_input_c_val, zdnn_status exp_status) { zdnn_tensor_desc tfrmd_desc_input_a, tfrmd_desc_input_b, tfrmd_desc_input_c, tfrmd_desc_output; zdnn_ztensor input_a, input_b, input_c, output; input_a.transformed_desc = &tfrmd_desc_input_a; input_b.transformed_desc = &tfrmd_desc_input_b; input_c.transformed_desc = &tfrmd_desc_input_c; output.transformed_desc = &tfrmd_desc_output; uint32_t input_a_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 4}; uint32_t input_b_shape[ZDNN_MAX_DIMS] = {1, 1, 1, 4}; uint32_t input_c_shape[ZDNN_MAX_DIMS] = {1, 1, 1, 4}; uint32_t output_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 4}; zdnn_status status; // e.g., sabotage dim_idx = 4 -> modify shape[0] // sabotage dim_idx = 1 -> modify shape[3] if (sbtg_input_b_dim_idx != 0) { input_b_shape[ZDNN_MAX_DIMS - sbtg_input_b_dim_idx] = sbtg_input_b_val; } if (sbtg_input_c_dim_idx != 0) { input_c_shape[ZDNN_MAX_DIMS - sbtg_input_c_dim_idx] = sbtg_input_c_val; } init_transformed_desc(ZDNN_NHWC, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &tfrmd_desc_input_a, input_a_shape[0], input_a_shape[1], input_a_shape[2], input_a_shape[3]); init_transformed_desc(ZDNN_NHWC, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &tfrmd_desc_input_b, input_b_shape[0], input_b_shape[1], input_b_shape[2], input_b_shape[3]); init_transformed_desc(ZDNN_NHWC, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &tfrmd_desc_input_c, input_c_shape[0], input_c_shape[1], input_c_shape[2], input_c_shape[3]); // The output is a 4D tensor of same shape, format, and data type as the // input init_transformed_desc(ZDNN_NHWC, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &tfrmd_desc_output, output_shape[0], output_shape[1], output_shape[2], output_shape[3]); status = verify_batchnorm_tensors(&input_a, &input_b, &input_c, &output); TEST_ASSERT_MESSAGE_FORMATTED(exp_status == status, "Expected status = %08x, actual status = %08x", exp_status, status); } /* * Simple test of verifying default inputs and output. */ void batchnorm_verify_pass() { test_batchnorm(0, 0, 0, 0, ZDNN_OK); } /* * Test that expects error due to dimension-2 of scale tensor is not 1 */ void batchnorm_verify_input_b_bad_dim2_fail() { test_batchnorm(2, 2, 0, 0, ZDNN_INVALID_SHAPE); } /* * Test that expects error due to dimension-1 of scale tensor is not the same as * the other tensors */ void batchnorm_verify_input_b_bad_dim1_fail() { test_batchnorm(1, 3, 0, 0, ZDNN_INVALID_SHAPE); } /* * Test that expects error due to dimension-2 of bias tensor is not 1 */ void batchnorm_verify_input_c_bad_dim2_fail() { test_batchnorm(0, 0, 2, 2, ZDNN_INVALID_SHAPE); } /* * Test that expects error due to dimension-1 of bias tensor is not the same as * the other tensors */ void batchnorm_verify_input_c_bad_dim1_fail() { test_batchnorm(0, 0, 1, 3, ZDNN_INVALID_SHAPE); } /// Common test routine for relu tensors /// /// \param[in] input_shape Pointer to input dim array /// \param[in] input_format Input format /// \param[in] input_type Input type /// \param[in] output_shape Pointer to output dim array /// \param[in] output_format Output format /// \param[in] output_type Output type /// \param[in] exp_status Expected status /// \param[in] error_msg Error message to prepend to the standard error /// message /// void test_relu(uint32_t input_shape[], zdnn_data_formats input_format, zdnn_data_types input_type, uint32_t output_shape[], zdnn_data_formats output_format, zdnn_data_types output_type, zdnn_status exp_status, char *error_msg) { zdnn_status status = ZDNN_OK; zdnn_ztensor input, output; zdnn_tensor_desc tfrmd_desc_input, tfrmd_desc_output; input.transformed_desc = &tfrmd_desc_input; output.transformed_desc = &tfrmd_desc_output; init_transformed_desc(ZDNN_NHWC, input_type, input_format, input.transformed_desc, input_shape[0], input_shape[1], input_shape[2], input_shape[3]); uint32_t clipping_value = 0; init_transformed_desc(ZDNN_NHWC, output_type, output_format, output.transformed_desc, output_shape[0], output_shape[1], output_shape[2], output_shape[3]); status = verify_relu_tensors(&input, clipping_value, &output); TEST_ASSERT_MESSAGE_FORMATTED( exp_status == status, "%s Expected status = %08x, actual status = %08x", error_msg, exp_status, status); } void relu_verify_pass() { uint32_t input_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 4}; uint32_t output_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 4}; test_relu(input_shape, ZDNN_FORMAT_4DFEATURE, ZDNN_DLFLOAT16, output_shape, ZDNN_FORMAT_4DFEATURE, ZDNN_DLFLOAT16, ZDNN_OK, "The output and the input tensor is different."); } void relu_verify_fail_shape() { uint32_t input_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 3}; uint32_t output_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 4}; test_relu(input_shape, ZDNN_FORMAT_4DFEATURE, ZDNN_DLFLOAT16, output_shape, ZDNN_FORMAT_4DFEATURE, ZDNN_DLFLOAT16, ZDNN_INVALID_SHAPE, "Failed to fail on different shapes."); } void relu_verify_fail_format() { uint32_t input_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 4}; uint32_t output_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 4}; test_relu(input_shape, ZDNN_FORMAT_4DFEATURE, ZDNN_DLFLOAT16, output_shape, ZDNN_FORMAT_4DKERNEL, ZDNN_DLFLOAT16, ZDNN_INVALID_FORMAT, "Failed to fail on different formats."); } void relu_verify_fail_dtype() { uint32_t input_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 4}; uint32_t output_shape[ZDNN_MAX_DIMS] = {1, 1, 2, 4}; test_relu(input_shape, ZDNN_FORMAT_4DFEATURE, FP32, output_shape, ZDNN_FORMAT_4DFEATURE, ZDNN_DLFLOAT16, ZDNN_INVALID_TYPE, "Failed to fail on different types."); } int main() { UNITY_BEGIN(); RUN_TEST(verify_ztensor_format); RUN_TEST(verify_1input_pass); RUN_TEST(verify_2input_pass); RUN_TEST(verify_3input_pass); RUN_TEST(verify_input2_fail_shape); RUN_TEST(verify_input3_fail_shape); RUN_TEST(verify_input2_fail_format); RUN_TEST(verify_input3_fail_format); RUN_TEST(verify_input2_fail_dtype); RUN_TEST(verify_input3_fail_dtype); RUN_TEST(verify_output_fail_shape); RUN_TEST(verify_output_fail_format); RUN_TEST(verify_output_fail_dtype); RUN_TEST(verify_matmul_op_pass); RUN_TEST(verify_matmul_op_fail_output_shape); RUN_TEST(verify_matmul_op_fail_input_shape); RUN_TEST(verify_matmul_op_fail_output_format); RUN_TEST(verify_matmul_op_fail_input_format); RUN_TEST(verify_matmul_op_fail_output_type); RUN_TEST(verify_matmul_op_fail_input_type); RUN_TEST(verify_matmul_bcast_op_pass); RUN_TEST(verify_matmul_bcast_op_fail_output_shape); RUN_TEST(verify_matmul_bcast_op_fail_input_shape); RUN_TEST(verify_matmul_bcast_op_fail_output_format); RUN_TEST(verify_matmul_bcast_op_fail_input_format); RUN_TEST(verify_matmul_bcast_op_fail_output_type); RUN_TEST(verify_matmul_bcast_op_fail_input_type); RUN_TEST(batchnorm_verify_pass); RUN_TEST(batchnorm_verify_input_b_bad_dim2_fail); RUN_TEST(batchnorm_verify_input_b_bad_dim1_fail); RUN_TEST(batchnorm_verify_input_c_bad_dim2_fail); RUN_TEST(batchnorm_verify_input_c_bad_dim1_fail); RUN_TEST(relu_verify_pass); RUN_TEST(relu_verify_fail_shape); RUN_TEST(relu_verify_fail_format); RUN_TEST(relu_verify_fail_dtype); return UNITY_END(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_tensor_verify_conv2d.c��������������������������������������������������0000664�0000000�0000000�00000045001�14364043643�0022223�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <string.h> // struct for tensor information typedef struct tensor_info { uint32_t dims[ZDNN_MAX_DIMS]; zdnn_data_layouts layout; zdnn_data_types dtype; } tensor_info; // struct for a set of inputs for a testcase (padding + tensors + strides) typedef struct input_set { zdnn_pool_padding padding; tensor_info input; tensor_info kernel; tensor_info bias; tensor_info output; uint32_t stride_height; uint32_t stride_width; } input_set; // "good input sets" - initialized during setUp(), shall NOT be modified by // testcases afterwards input_set same_padding_nonzero_stride; input_set valid_padding_nonzero_stride; input_set valid_padding_zero_stride; #define DIM4 dims[0] #define DIM3 dims[1] #define DIM2 dims[2] #define DIM1 dims[3] #define INIT_TENSOR(set, info, dim4, dim3, dim2, dim1, l, t) \ set.info.DIM4 = dim4; \ set.info.DIM3 = dim3; \ set.info.DIM2 = dim2; \ set.info.DIM1 = dim1; \ set.info.layout = l; \ set.info.dtype = t; void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; same_padding_nonzero_stride.padding = SAME_PADDING; INIT_TENSOR(same_padding_nonzero_stride, input, 4, 6, 9, 5, ZDNN_NHWC, FP32); INIT_TENSOR(same_padding_nonzero_stride, kernel, 3, 8, 5, 8, ZDNN_HWCK, FP32); INIT_TENSOR(same_padding_nonzero_stride, bias, 8, -1, -1, -1, ZDNN_1D, FP32); // -1 are ignored since it's 1D INIT_TENSOR(same_padding_nonzero_stride, output, 4, 2, 5, 8, ZDNN_NHWC, FP32); same_padding_nonzero_stride.stride_height = 3; same_padding_nonzero_stride.stride_width = 2; valid_padding_nonzero_stride.padding = VALID_PADDING; INIT_TENSOR(valid_padding_nonzero_stride, input, 4, 6, 9, 5, ZDNN_NHWC, FP32); INIT_TENSOR(valid_padding_nonzero_stride, kernel, 3, 8, 5, 8, ZDNN_HWCK, FP32); INIT_TENSOR(valid_padding_nonzero_stride, bias, 8, -1, -1, -1, ZDNN_1D, FP32); INIT_TENSOR(valid_padding_nonzero_stride, output, 4, 2, 1, 8, ZDNN_NHWC, FP32); valid_padding_nonzero_stride.stride_height = 3; valid_padding_nonzero_stride.stride_width = 2; valid_padding_zero_stride.padding = VALID_PADDING; INIT_TENSOR(valid_padding_zero_stride, input, 4, 3, 8, 5, ZDNN_NHWC, FP32); INIT_TENSOR(valid_padding_zero_stride, kernel, 3, 8, 5, 8, ZDNN_HWCK, FP32); INIT_TENSOR(valid_padding_zero_stride, bias, 8, -1, -1, -1, ZDNN_1D, FP32); INIT_TENSOR(valid_padding_zero_stride, output, 4, 1, 1, 8, ZDNN_NHWC, FP32); valid_padding_zero_stride.stride_height = 0; valid_padding_zero_stride.stride_width = 0; } void tearDown(void) { /* This is run after EACH TEST */ } #define NON_EXISTENT_FORMAT -1 #define NON_EXISTENT_DTYPE -1 void run_verify_conv2d_tensors_full(input_set set, zdnn_conv2d_act act_func, bool use_non_existent_format, bool use_non_existent_dtype, zdnn_status expected_status) { zdnn_status status = GENERAL_TESTCASE_FAILURE; zdnn_ztensor *input_ztensor = alloc_ztensor_with_values(set.input.dims, set.input.layout, set.input.dtype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values(set.kernel.dims, set.kernel.layout, set.kernel.dtype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values(set.bias.dims, set.bias.layout, set.bias.dtype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values(set.output.dims, set.output.layout, set.output.dtype, NO_CONCAT, true, ZERO_ARRAY); if (use_non_existent_dtype) { output_ztensor->transformed_desc->type = NON_EXISTENT_DTYPE; } if (use_non_existent_format) { output_ztensor->transformed_desc->format = NON_EXISTENT_FORMAT; } func_sp_parm1_conv2d conv2d_parm1; conv2d_parm1.val = 0; conv2d_parm1.bits.act = act_func; conv2d_parm1.bits.pad = set.padding; func_sp_parm4_conv2d conv2d_parm4; conv2d_parm4.val = 0; conv2d_parm4.bits.clipping_value = 0; // Make call to verify with our newly created ztensors and other inputs TEST_ASSERT_MESSAGE_FORMATTED( verify_conv2d_tensors(input_ztensor, kernel_ztensor, bias_ztensor, conv2d_parm1.val, set.stride_height, set.stride_width, conv2d_parm4.val, output_ztensor) == expected_status, "Call to verify_conv2d_tensors() returned zdnn_status %08x but we " "expected %08x", status, expected_status); free_ztensor_buffers(4, input_ztensor, kernel_ztensor, bias_ztensor, output_ztensor); } void run_verify_conv2d_tensors(input_set set, zdnn_conv2d_act act_func, zdnn_status expected_status) { run_verify_conv2d_tensors_full(set, act_func, false, false, expected_status); } void same_padding_pass() { input_set set; memcpy(&set, &same_padding_nonzero_stride, sizeof(input_set)); run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_OK); } void valid_padding_pass() { input_set set; memcpy(&set, &valid_padding_nonzero_stride, sizeof(input_set)); run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_OK); memcpy(&set, &valid_padding_zero_stride, sizeof(input_set)); run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_OK); } // although actual op would fail, tensor-verify would pass void unknown_padding_type_pass() { input_set set; memcpy(&set, &valid_padding_nonzero_stride, sizeof(input_set)); set.padding = -1; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_OK); } void output_different_dtype_fail() { input_set set[3]; memcpy(set, &same_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 1, &valid_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 2, &valid_padding_zero_stride, sizeof(input_set)); for (int i = 0; i < sizeof(set) / sizeof(input_set); i++) { run_verify_conv2d_tensors_full(set[i], CONV2D_ACT_NONE, false, true, ZDNN_INVALID_TYPE); } } void output_different_format_fail() { input_set set[3]; memcpy(set, &same_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 1, &valid_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 2, &valid_padding_zero_stride, sizeof(input_set)); for (int i = 0; i < sizeof(set) / sizeof(input_set); i++) { run_verify_conv2d_tensors_full(set[i], CONV2D_ACT_NONE, true, false, ZDNN_INVALID_FORMAT); } } void bias_not_bias_fail() { /* The dimension-2, dimension-3, and dimension-4 index sizes of the input 3 tensor must be 1. */ input_set set[3]; memcpy(set, &same_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 1, &valid_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 2, &valid_padding_zero_stride, sizeof(input_set)); for (int i = 0; i < sizeof(set) / sizeof(input_set); i++) { set[i].bias.dims[0] = 2; set[i].bias.dims[1] = 8; set[i].bias.layout = ZDNN_2D; run_verify_conv2d_tensors(set[i], CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } } void different_output_dim4_input_dim4_fail() { /* The dimension-4-index-size of the output tensor must be equal to the dimension-4-index-size of the input 1 tensor. */ input_set set[3]; memcpy(set, &same_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 1, &valid_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 2, &valid_padding_zero_stride, sizeof(input_set)); for (int i = 0; i < sizeof(set) / sizeof(input_set); i++) { set[i].output.DIM4 = set[i].input.DIM4 + 1; run_verify_conv2d_tensors(set[i], CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } } void different_output_dim1_input2_dim1_fail() { /* The dimension-1 index size of the output tensor must be equal to the dimension-1 index size of the input 2 tensor and the dimension-1-index size of the input 3 tensor. */ input_set set[3]; memcpy(set, &same_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 1, &valid_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 2, &valid_padding_zero_stride, sizeof(input_set)); for (int i = 0; i < sizeof(set) / sizeof(input_set); i++) { set[i].output.DIM1 = set[i].kernel.DIM1 + 1; run_verify_conv2d_tensors(set[i], CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } } void different_output_dim1_input3_dim1_fail() { /* The dimension-1 index size of the output tensor must be equal to the dimension-1 index size of the input 2 tensor and the dimension-1-index size of the input 3 tensor. */ input_set set[3]; memcpy(set, &same_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 1, &valid_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 2, &valid_padding_zero_stride, sizeof(input_set)); for (int i = 0; i < sizeof(set) / sizeof(input_set); i++) { // bias is 1D so dimension-1-index came from dims[0] set[i].output.DIM1 = set[i].bias.dims[0] + 1; run_verify_conv2d_tensors(set[i], CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } } void different_input_dim1_input2_dim2_fail() { /* The dimension-1 index size of the input 1 tensor must be equal to the dimension-2 index size of the input 2 tensor. */ input_set set[3]; memcpy(set, &same_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 1, &valid_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 2, &valid_padding_zero_stride, sizeof(input_set)); for (int i = 0; i < sizeof(set) / sizeof(input_set); i++) { set[i].input.DIM1 = set[i].kernel.DIM2 + 1; run_verify_conv2d_tensors(set[i], CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } } /***************************************************** If the dimension-2-stride and the dimension-3- stride are both zero all of the following additional conditions must be true: *****************************************************/ void different_input1_dim2_input2_dim3_fail() { /* The input 1 tensor dimension-2-index-size must be equal to the dimension-3-index-size of input 2 tensor. */ input_set set; memcpy(&set, &valid_padding_zero_stride, sizeof(input_set)); set.kernel.DIM3 = set.input.DIM2 + 1; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void different_input1_dim3_input2_dim4_fail() { /* The input 1 tensor dimension-3-index-size of the input tensor must be equal to the dimension-4-index-size of input 2 tensor. */ input_set set; memcpy(&set, &valid_padding_zero_stride, sizeof(input_set)); set.kernel.DIM4 = set.input.DIM3 + 1; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void output_dim2_not_one_fail() { /* The dimension-2-index-size and the dimension-3-index-size of the output tensor must be one. */ input_set set; memcpy(&set, &valid_padding_zero_stride, sizeof(input_set)); set.output.DIM2 = 2; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void output_dim3_not_one_fail() { /* The dimension-2-index-size and the dimension-3-index-size of the output tensor must be one. */ input_set set; memcpy(&set, &valid_padding_zero_stride, sizeof(input_set)); set.output.DIM3 = 2; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void zero_height_width_not_validpadding_fail() { /* The specified padding must be VALID. */ input_set set; memcpy(&set, &valid_padding_zero_stride, sizeof(input_set)); set.padding = SAME_PADDING; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_STRIDE_PADDING); } /********************************************* If the dimension-2-stride and the dimension-3- stride are both greater than zero all of the following additional conditions must be true: *********************************************/ void valid_input_dim2_lessthan_kernel_dim3_fail() { /* When the specified padding is VALID, the dimension-2-index-size of the input 1 tensor must be greater than or equal to the dimension-3-index-size of input tensor 2. */ input_set set; memcpy(&set, &valid_padding_nonzero_stride, sizeof(input_set)); set.input.DIM2 = set.kernel.DIM3 - 1; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void valid_input_dim3_lessthan_kernel_dim4_fail() { /* When the specified padding is VALID, the dimension-3-index-size of the input 1 tensor must be greater than or equal to the dimension-4-index-size of the input 2 tensor. */ input_set set; memcpy(&set, &valid_padding_nonzero_stride, sizeof(input_set)); set.input.DIM3 = set.kernel.DIM4 - 1; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void same_big_math_equation1_fail() { /* When the specified padding is SAME, the following relationship between the dimension-2-index-size and dimension-3-index-size of the input 1 tensor and output tensor must be satisfied: Dimension-2-index-size of the output tensor = ceil( Dimension-2-index-size of the input 1 tensor / Dimension-2-stride) Dimension-3-index-size of the output tensor = ceil( Dimension-3-index-size of the input 1 tensor / Dimension-3-stride) */ input_set set; memcpy(&set, &same_padding_nonzero_stride, sizeof(input_set)); set.stride_width = 1; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void same_big_math_equation2_fail() { /* When the specified padding is SAME, the following relationship between the dimension-2-index-size and dimension-3-index-size of the input 1 tensor and output tensor must be satisfied: Dimension-2-index-size of the output tensor = ceil( Dimension-2-index-size of the input 1 tensor / Dimension-2-stride) Dimension-3-index-size of the output tensor = ceil( Dimension-3-index-size of the input 1 tensor / Dimension-3-stride) */ input_set set; memcpy(&set, &same_padding_nonzero_stride, sizeof(input_set)); set.stride_height = 1; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void valid_big_math_equation1_fail() { /* When the specified padding is VALID, the following relationship between the dimension-2-index-size and dimension-3-index-sizes of the input 1 tensor, dimension-3-index-size and dimension-4-index-size of the input 2 tensor and output tensor must be satisfied: Dimension-2-index-size of the output tensor = ceil( (Dimension-2-index-size of the input 1 tensor - Dimension-3-index-size of the input 2 tensor + 1 ) / Dimension-2-stride Dimension-3-index-size of the output tensor = ceil( (Dimension-3-index-size of the input 1 tensor - Dimension-4-index-size of the input 2 tensor + 1 ) / Dimension-3-stride */ input_set set; memcpy(&set, &valid_padding_nonzero_stride, sizeof(input_set)); set.stride_width = 1; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void valid_big_math_equation2_fail() { /* When the specified padding is VALID, the following relationship between the dimension-2-index-size and dimension-3-index-sizes of the input 1 tensor, dimension-3-index-size and dimension-4-index-size of the input 2 tensor and output tensor must be satisfied: Dimension-2-index-size of the output tensor = ceil( (Dimension-2-index-size of the input 1 tensor - Dimension-3-index-size of the input 2 tensor + 1 ) / Dimension-2-stride Dimension-3-index-size of the output tensor = ceil( (Dimension-3-index-size of the input 1 tensor - Dimension-4-index-size of the input 2 tensor + 1 ) / Dimension-3-stride */ input_set set; memcpy(&set, &valid_padding_nonzero_stride, sizeof(input_set)); set.stride_height = 1; run_verify_conv2d_tensors(set, CONV2D_ACT_NONE, ZDNN_INVALID_SHAPE); } void height_zero_width_nonzero_fail() { /* If either the dimension-2-stride or the dimension3-stride is non-zero, then both strides must be non-zero. */ input_set set[2]; memcpy(set, &same_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 1, &valid_padding_nonzero_stride, sizeof(input_set)); for (int i = 0; i < sizeof(set) / sizeof(input_set); i++) { set[i].stride_height = 0; run_verify_conv2d_tensors(set[i], CONV2D_ACT_NONE, ZDNN_INVALID_STRIDES); } } void height_nonzero_width_zero_fail() { /* If either the dimension-2-stride or the dimension3-stride is non-zero, then both strides must be non-zero. */ input_set set[2]; memcpy(set, &same_padding_nonzero_stride, sizeof(input_set)); memcpy(set + 1, &valid_padding_nonzero_stride, sizeof(input_set)); for (int i = 0; i < sizeof(set) / sizeof(input_set); i++) { set[i].stride_width = 0; run_verify_conv2d_tensors(set[i], CONV2D_ACT_NONE, ZDNN_INVALID_STRIDES); } } int main() { UNITY_BEGIN(); RUN_TEST(same_padding_pass); RUN_TEST(valid_padding_pass); RUN_TEST(unknown_padding_type_pass); RUN_TEST(output_different_dtype_fail); RUN_TEST(output_different_format_fail); RUN_TEST(bias_not_bias_fail); RUN_TEST(different_output_dim4_input_dim4_fail); RUN_TEST(different_output_dim1_input2_dim1_fail); RUN_TEST(different_output_dim1_input3_dim1_fail); RUN_TEST(different_input_dim1_input2_dim2_fail); RUN_TEST(different_input1_dim2_input2_dim3_fail); RUN_TEST(different_input1_dim3_input2_dim4_fail); RUN_TEST(different_input1_dim3_input2_dim4_fail); RUN_TEST(output_dim2_not_one_fail); RUN_TEST(output_dim3_not_one_fail); RUN_TEST(zero_height_width_not_validpadding_fail); RUN_TEST(valid_input_dim2_lessthan_kernel_dim3_fail); RUN_TEST(valid_input_dim3_lessthan_kernel_dim4_fail); RUN_TEST(same_big_math_equation1_fail); RUN_TEST(same_big_math_equation2_fail); RUN_TEST(valid_big_math_equation1_fail); RUN_TEST(valid_big_math_equation2_fail); RUN_TEST(height_zero_width_nonzero_fail); RUN_TEST(height_nonzero_width_zero_fail); return UNITY_END(); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_tensor_verify_lstm_gru.c������������������������������������������������0000664�0000000�0000000�00000026600�14364043643�0022670�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} #define BAD_FORMAT 255 #define BAD_TYPE 255 #define DEFAULT_NUM_TIMESTEPS 3 #define DEFAULT_NUM_BATCHES 4 #define DEFAULT_NUM_FEATURES 7 #define DEFAULT_NUM_HIDDEN 16 const uint32_t num_batches = DEFAULT_NUM_BATCHES; const uint32_t num_hidden = DEFAULT_NUM_HIDDEN; #define MAX_DESC_LEN 256 char msg[MAX_DESC_LEN]; typedef enum tensor_idx { FUSED, BIAS, CELLSTATE, OUTPUT, OUTPUT2, MAX_TENSOR_IDX, NONE = MAX_TENSOR_IDX } tensor_idx; // roll our own instead of using get_func_code_num_gates() in case that one // breaks #define NUM_GATES(f) ((f == NNPA_LSTMACT) ? 4 : 3) void create_ztensors(uint8_t function_code, zdnn_ztensor **rnn_ztens) { zdnn_data_layouts layout = ZDNN_NHWC; zdnn_data_types dtype = FP32; uint8_t num_gates = NUM_GATES(function_code); // baseline dimensions with correct requirements uint32_t *shape[MAX_TENSOR_IDX]; // create ztensors using transformed shape + ZDNN_NHWC to make the code // simplier, so that we can loop through them all rather than dealing with // different pre-transformed layouts etc. shape[FUSED] = (uint32_t[]){num_gates, 1, num_batches, num_hidden}; shape[BIAS] = (uint32_t[]){num_gates, 1, num_batches, num_hidden}; shape[CELLSTATE] = (uint32_t[]){1, 1, num_batches, num_hidden}; shape[OUTPUT] = (uint32_t[]){1, 1, num_batches, num_hidden}; shape[OUTPUT2] = shape[OUTPUT]; // they share the same shape, final timestep only // rnn_ztens[FUSED] is the fuzed_ztensor split as a timestep // rnn_ztens[BIAS] is the bias_add_ztensor that would be the result of the // bias_add call within NNPA_LSTMACT function. // rnn_ztens[CELLSTATE] is the cell state ztensor (only used in NNPA_LSTMACT) // rnn_ztens[OUTPUT] is the result as output_ztensor1 // rnn_ztens[OUTPUT2] is the result as output_ztensor2 for (int i = 0; i < MAX_TENSOR_IDX; i++) { rnn_ztens[i] = alloc_ztensor_with_values(shape[i], layout, dtype, NO_CONCAT, true, ZERO_ARRAY); } } void set_dim(zdnn_tensor_desc *desc, uint8_t dim_idx, uint32_t value) { switch (dim_idx) { case (1): desc->dim1 = value; break; case (2): desc->dim2 = value; break; case (3): desc->dim3 = value; break; case (4): desc->dim4 = value; break; default: TEST_FAIL_MESSAGE_FORMATTED("%d is not a valid dim_idx to set.", dim_idx); break; } } // Verify return status by sabotaging a ztensor void verify(uint8_t function_code, tensor_idx idx, bool sabotage_dim, uint8_t dim_idx, uint32_t dim_val, bool sabotage_type, zdnn_data_types type, bool sabotage_format, zdnn_data_formats format, zdnn_status exp_status, char *description) { // Create the test tensors zdnn_ztensor *rnn_ztens[MAX_TENSOR_IDX]; create_ztensors(function_code, rnn_ztens); // Sabotage the dim/format/type of the ztensor specified in idx if (idx != NONE) { if (sabotage_dim) { set_dim(rnn_ztens[idx]->transformed_desc, dim_idx, dim_val); } if (sabotage_type) { rnn_ztens[idx]->transformed_desc->type = type; } if (sabotage_format) { rnn_ztens[idx]->transformed_desc->format = format; } } zdnn_status actual_status = verify_lstm_or_gru_act_tensors( function_code, rnn_ztens[FUSED], rnn_ztens[BIAS], rnn_ztens[CELLSTATE], rnn_ztens[OUTPUT], rnn_ztens[OUTPUT2]); if (actual_status != exp_status) { TEST_FAIL_MESSAGE_FORMATTED( "%s: Actual status return (%08x) does not match expected (%08x).", description, actual_status, exp_status); } // Cleanup for (int i = 0; i < MAX_TENSOR_IDX; i++) { free_ztensor_buffers(1, rnn_ztens[i]); } } // Verify return status by sabotaging the ztensor dimension void verify_shape(uint8_t function_code, tensor_idx idx, uint8_t dim_idx, uint32_t dim_val, zdnn_status exp_status, char *description) { verify(function_code, idx, true, dim_idx, dim_val, false, 0, false, 0, exp_status, description); } // Verify return status by sabotaging the ztensor data type void verify_type(uint8_t function_code, tensor_idx idx, zdnn_data_types type, zdnn_status exp_status, char *description) { verify(function_code, idx, false, 0, 0, true, type, false, 0, exp_status, description); } // Verify return status by sabotaging the ztensor format void verify_format(uint8_t function_code, tensor_idx idx, zdnn_data_formats format, zdnn_status exp_status, char *description) { verify(function_code, idx, false, 0, 0, false, 0, true, format, exp_status, description); } // this macro assume values of NNPA_LSTMACT and NNPA_GRUACT are next to each // other #define LOOP_LSTM_AND_GRU(lg) \ for (int lg = NNPA_LSTMACT; lg < NNPA_GRUACT; lg++) #define TEST_DIM_VAL(tensor_idx, dim_idx, val, exp_status) \ snprintf(msg, MAX_DESC_LEN, "%s %s dim%s", __func__, \ act == NNPA_LSTMACT ? "LSTM" : "GRU", #dim_idx); \ verify_shape(act, tensor_idx, dim_idx, val, exp_status, msg); /* * Test verification of valid activation tensors. * All tensors will be built with acceptable properties. */ void verify_pass() { // Expect no known error, no bad dims will be set LOOP_LSTM_AND_GRU(act) { TEST_DIM_VAL(NONE, 0, 0, ZDNN_OK); } } /* * Test verification of failed output shape. * Correct shape is (1, 1, num_batches, num_hidden) * All input tensors will have acceptable descriptors. */ void verify_fail_output_shape() { LOOP_LSTM_AND_GRU(act) { // Expect failure when output_ztensor dimension 4 (timestep) is not 1 TEST_DIM_VAL(OUTPUT, 4, 2, ZDNN_INVALID_SHAPE); // Expect failure when output_ztensor dimension 3 is not 1 TEST_DIM_VAL(OUTPUT, 3, 2, ZDNN_INVALID_SHAPE); // Expect failure when output_ztensor dimension 2 does not match num_batches TEST_DIM_VAL(OUTPUT, 2, num_batches + 1, ZDNN_INVALID_SHAPE); // Expect failure when output_ztensor dimension 1 does not match num_hidden TEST_DIM_VAL(OUTPUT, 1, num_hidden + 1, ZDNN_INVALID_SHAPE); } } /* * Test verification of failed output2 shape. * Correct shape is (1, 1, num_batches, num_hidden) * All input tensors will have acceptable descriptors. */ void verify_fail_output2_shape() { LOOP_LSTM_AND_GRU(act) { // Expect failure when output_ztensor dimension 4 (timestep) is not 1 TEST_DIM_VAL(OUTPUT2, 4, 2, ZDNN_INVALID_SHAPE); // Expect failure when output_ztensor dimension 3 is not 1 TEST_DIM_VAL(OUTPUT2, 3, 2, ZDNN_INVALID_SHAPE); // Expect failure when output_ztensor dimension 2 does not match num_batches TEST_DIM_VAL(OUTPUT2, 2, num_batches + 1, ZDNN_INVALID_SHAPE); // Expect failure when output_ztensor dimension 1 does not match num_hidden TEST_DIM_VAL(OUTPUT2, 1, num_hidden + 1, ZDNN_INVALID_SHAPE); } } /* * Test verification of failed fuzed_ztensor shape. * Correct shape is (4, 1, num_batches, num_hidden) for LSTM, * (3, 1, num_batches, num_hidden) for GRU * All input tensors except fused will have acceptable descriptors. */ void verify_fail_fused_shape() { LOOP_LSTM_AND_GRU(act) { uint32_t num_gates = NUM_GATES(act); // Expect failure when bias dimension 4 is not 4 (LSTM) or 3 (GRU) TEST_DIM_VAL(FUSED, 4, num_gates + 1, ZDNN_INVALID_SHAPE); // Expect failure when fused dimension 3 is not 1 TEST_DIM_VAL(FUSED, 3, 2, ZDNN_INVALID_SHAPE); // Expect failure when fused dimension 2 does not match num_batches TEST_DIM_VAL(FUSED, 2, num_batches + 1, ZDNN_INVALID_SHAPE); // Expect failure when fused dimension 1 does not match num_hidden TEST_DIM_VAL(FUSED, 1, num_hidden + 1, ZDNN_INVALID_SHAPE); } } /* * Test verification of failed bias_add_ztensor shape. * Correct shape is (4, 1, num_batches, num_hidden) for LSTM, * (3, 1, num_batches, num_hidden) for GRU * All input tensors except bias will have acceptable descriptors. */ void verify_fail_bias_shape() { LOOP_LSTM_AND_GRU(act) { uint32_t num_gates = NUM_GATES(act); // Expect failure when bias dimension 4 is not 4 (LSTM) or 3 (GRU) TEST_DIM_VAL(BIAS, 4, num_gates + 1, ZDNN_INVALID_SHAPE); // Expect failure when bias dimension 3 is not 1 TEST_DIM_VAL(BIAS, 3, 2, ZDNN_INVALID_SHAPE); // Expect failure when bias dimension 2 does not match input TEST_DIM_VAL(BIAS, 2, num_batches + 1, ZDNN_INVALID_SHAPE); // Expect failure when bias dimension 1 does not match input TEST_DIM_VAL(BIAS, 1, num_hidden + 1, ZDNN_INVALID_SHAPE); } } /* * Test verification of failed cell state ztensor shape. * Correct shape is (1, 1, num_batches, num_hidden) * All input tensors except cell-state will have acceptable descriptors. */ void verify_fail_cellstate_shape() { LOOP_LSTM_AND_GRU(act) { // Expect failure when cellstate dimension 4 is not 1 TEST_DIM_VAL(CELLSTATE, 4, 2, ZDNN_INVALID_SHAPE); // Expect failure when cellstate dimension 3 is not 1 TEST_DIM_VAL(CELLSTATE, 3, 2, ZDNN_INVALID_SHAPE); // Expect failure when cellstate dimension 2 does not match num_batches TEST_DIM_VAL(CELLSTATE, 2, num_batches + 1, ZDNN_INVALID_SHAPE); // Expect failure when cellstate dimension 2 does not matchnum_hidden TEST_DIM_VAL(CELLSTATE, 1, num_hidden + 1, ZDNN_INVALID_SHAPE); } } #define TEST_FORMAT(tensor_idx, format, exp_status) \ snprintf(msg, MAX_DESC_LEN, "%s %s %s", __func__, \ act == NNPA_LSTMACT ? "LSTM" : "GRU", #tensor_idx); \ verify_format(act, tensor_idx, format, exp_status, msg); /* * Test verification of failed format. */ void verify_fail_format() { LOOP_LSTM_AND_GRU(act) { for (int i = 0; i < MAX_TENSOR_IDX; i++) { TEST_FORMAT(i, BAD_FORMAT, ZDNN_INVALID_FORMAT); } } } #define TEST_TYPE(tensor_idx, type, exp_status) \ snprintf(msg, MAX_DESC_LEN, "%s %s %s", __func__, \ act == NNPA_LSTMACT ? "LSTM" : "GRU", #tensor_idx); \ verify_type(act, tensor_idx, type, exp_status, msg); /* * Test verification of failed type. */ void verify_fail_type() { LOOP_LSTM_AND_GRU(act) { for (int i = 0; i < MAX_TENSOR_IDX; i++) { TEST_TYPE(i, BAD_TYPE, ZDNN_INVALID_TYPE); } } } int main() { UNITY_BEGIN(); RUN_TEST(verify_pass); RUN_TEST(verify_fail_output_shape); RUN_TEST(verify_fail_output2_shape); RUN_TEST(verify_fail_fused_shape); RUN_TEST(verify_fail_bias_shape); RUN_TEST(verify_fail_cellstate_shape); RUN_TEST(verify_fail_format); RUN_TEST(verify_fail_type); return UNITY_END(); } ��������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_tensor_verify_pool_avg_max.c��������������������������������������������0000664�0000000�0000000�00000044217�14364043643�0023513�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_pool.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } #define NON_EXISTENT_FORMAT -1 #define NON_EXISTENT_DTYPE -1 void run_verify_pool_avg_max_tensors( uint32_t *input_shape, zdnn_data_layouts input_layout, zdnn_data_types input_dtype, uint32_t *output_shape, zdnn_data_layouts output_layout, zdnn_data_types output_dtype, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, bool use_mismatch_dtype, zdnn_status expected_status) { // Create status to check status after verify calls zdnn_status status; // We don't care about the values for these tests so just pass the zero array zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_shape, input_layout, input_dtype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_shape, output_layout, output_dtype, NO_CONCAT, true, ZERO_ARRAY); // Special scenario. Test is checking what happens when input and output data // types don't match. alloc_ztensor_with_values() above transforms into real // ztensors, with ZDNN_DLFLOAT16. Forcibly break that for such tests. if (use_mismatch_dtype) { input_ztensor->transformed_desc->type = NON_EXISTENT_DTYPE; } // Make call to verify with our newly created ztensors and other inputs if ((status = verify_pool_avg_max_tensors( input_ztensor, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_ztensor)) != expected_status) { TEST_FAIL_MESSAGE_FORMATTED( "Call to verify_pool_avg_max_tensors() returned zdnn_status %08x " "\"%s\" but we expected %08x \"%s\"", status, zdnn_get_status_message(status), expected_status, zdnn_get_status_message(expected_status)); } // Cleanup free_ztensor_buffers(2, input_ztensor, output_ztensor); } /* * Simple test to confirm verification does not return any known error codes * with valid SAME_PADDING values */ void verify_same_pass() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 3, 3, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; uint32_t stride_height = 3; uint32_t stride_width = 2; run_verify_pool_avg_max_tensors( input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, SAME_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_OK); } /* * Simple test to confirm verification passes with valid VALID_PADDING values */ void verify_valid_pass() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 2, 2, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; uint32_t stride_height = 3; uint32_t stride_width = 2; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_OK); } /* * Verifying the input tensor with output. Should fail * because the input and output tensors have different dtypes */ void verify_dtype_mismatch_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 3, 3, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; uint32_t stride_height = 3; uint32_t stride_width = 2; // Setting output dtype to FP16 instead of FP32 should cause failure run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP16, SAME_PADDING, kernel_height, kernel_width, stride_height, stride_width, true, ZDNN_INVALID_TYPE); } /* * Verifying the input tensor with output. Should fail * because the input and output tensor have different formats. */ void verify_format_mismatch_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 2, 2, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; uint32_t stride_height = 3; uint32_t stride_width = 2; // Setting input format to ZDNN_HWCK instead of NHWC should cause failure run_verify_pool_avg_max_tensors(input_shape, ZDNN_HWCK, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_FORMAT); } /* * Verifying the input tensor with output. Should fail * because the innermost dimension of the input and output are different */ void verify_bad_c_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; // Setting shape[3] to 4 instead of 1 should cause failure uint32_t output_shape[] = {1, 3, 3, 4}; uint32_t kernel_height = 4; uint32_t kernel_width = 4; uint32_t stride_height = 3; uint32_t stride_width = 3; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, SAME_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the input tensor with output. Should fail * because the outermost dimension of the input and output are different */ void verify_bad_n_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; // Setting shape[0] to 4 instead of 1 should cause failure uint32_t output_shape[] = {4, 3, 3, 1}; uint32_t kernel_height = 4; uint32_t kernel_width = 4; uint32_t stride_height = 3; uint32_t stride_width = 3; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, SAME_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Simple test to confirm verification does not return any known error codes * with valid SAME_PADDING values when strides are 0 */ void verify_0_strides_pass() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 1, 1, 1}; uint32_t kernel_height = 8; uint32_t kernel_width = 5; uint32_t stride_height = 0; uint32_t stride_width = 0; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_OK); } /* * Verifying the 0 stride values. Should fail * because the the padding_type must be VALID_PADDING when strides are 0 */ void verify_0_strides_same_padding_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 1, 1, 1}; uint32_t kernel_height = 8; uint32_t kernel_width = 5; uint32_t stride_height = 0; uint32_t stride_width = 0; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, SAME_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_STRIDE_PADDING); } /* * Verifying the 0 stride values. Should fail * because the second dimension stride value is greater than 0, * and the third dimension stride value is 0. */ void verify_0_strides_stride_width_not_zero_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 3, 3, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; uint32_t stride_height = 0; // Setting stride_width to 1 instead of 0 should cause failure uint32_t stride_width = 1; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_STRIDES); } /* * Verifying the stride values. Should fail because the third dimension stride * value is greater than 0, and the second dimension stride value is 0. */ void verify_0_strides_stride_height_not_zero_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 3, 3, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; // Setting stride_height to 1 instead of 0 should cause failure uint32_t stride_height = 1; uint32_t stride_width = 0; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_STRIDES); } /* * Verifying the input tensor with output. Should fail * because stride values are both 0 and input dimension 2 is not equal to * window dim 2 */ void verify_0_strides_bad_kernel_width_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 1, 1, 1}; uint32_t kernel_height = 8; // Setting kernel_width to 4 instead of 5 should cause failure uint32_t kernel_width = 4; uint32_t stride_height = 0; uint32_t stride_width = 0; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the input tensor with output. Should fail * because stride values are both 0 and input dimension 3 is not equal * to window_size dimension 3 */ void verify_0_strides_bad_kernel_height_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 1, 1, 1}; // Setting kernel_height to 7 instead of 8 should cause failure uint32_t kernel_height = 7; uint32_t kernel_width = 5; uint32_t stride_height = 0; uint32_t stride_width = 0; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the output tensor. Should fail because stride values are both 0 and * output dimensions 2 and 3 are not equal to 1 */ void verify_0_strides_bad_out_width_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; // Setting shape[2] to 2 instead of 1 should cause failure uint32_t output_shape[] = {1, 1, 2, 1}; uint32_t kernel_height = 8; uint32_t kernel_width = 5; uint32_t stride_height = 0; uint32_t stride_width = 0; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the output tensor. Should fail because stride values are both 0 and * output dimensions 2 and 3 are not equal to 1 */ void verify_0_strides_bad_out_height_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; // Setting shape[1] to 2 instead of 1 should cause failure uint32_t output_shape[] = {1, 2, 1, 1}; uint32_t kernel_height = 8; uint32_t kernel_width = 5; uint32_t stride_height = 0; uint32_t stride_width = 0; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the input and window values. Should fail * because the second dimension window value is greater than the * second dimension of the input tensor and the padding is VALID. */ void verify_valid_bad_kernel_width_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 2, 2, 1}; uint32_t kernel_height = 3; // Setting kernel_width to 6 instead of 2 should cause failure uint32_t kernel_width = 6; uint32_t stride_height = 3; uint32_t stride_width = 2; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the input and window values. Should fail * because the third dimension window value is greater than the * third dimension of the input tensor and the padding is VALID. */ void verify_valid_bad_kernel_height_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; uint32_t output_shape[] = {1, 2, 2, 1}; // Setting kernel_width to 9 instead of 3 should cause failure uint32_t kernel_height = 9; uint32_t kernel_width = 2; uint32_t stride_height = 3; uint32_t stride_width = 2; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the output tensor has the correct shape given the padding. * This test should fail because the dimension 3 of the output tensor is not * equal to the expected value and the padding is VALID_PADDING */ void verify_valid_bad_out_width_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; // Setting shape[2] to 3 instead of 2 should cause expected failure uint32_t output_shape[] = {1, 2, 3, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; uint32_t stride_height = 3; uint32_t stride_width = 2; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the output tensor has the correct shape given the padding. This * test should fail because the dimension 2 of the output tensor is not equal to * the expected value and the padding is VALID_PADDING */ void verify_valid_bad_out_height_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; // Setting shape[1] to 3 instead of 2 should cause expected failure uint32_t output_shape[] = {1, 3, 2, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; uint32_t stride_height = 3; uint32_t stride_width = 2; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, VALID_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the output tensor has the correct shape given the padding. This * test should fail because the dimension 3 of the output tensor is not equal to * the expected value and the padding is SAME_PADDING */ void verify_same_bad_out_width_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; // Setting shape[2] to 4 instead of 3 should cause expected failure uint32_t output_shape[] = {1, 3, 4, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; uint32_t stride_height = 3; uint32_t stride_width = 2; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, SAME_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } /* * Verifying the output tensor has the correct shape given the padding. This * test should fail because the dimension 2 of the output tensor is not equal to * the expected value and the padding is SAME_PADDING */ void verify_same_bad_out_height_fail() { uint32_t input_shape[] = {1, 8, 5, 1}; // Setting shape[1] to 4 instead of 3 should cause expected failure uint32_t output_shape[] = {1, 4, 3, 1}; uint32_t kernel_height = 3; uint32_t kernel_width = 2; uint32_t stride_height = 3; uint32_t stride_width = 2; run_verify_pool_avg_max_tensors(input_shape, ZDNN_NHWC, FP32, output_shape, ZDNN_NHWC, FP32, SAME_PADDING, kernel_height, kernel_width, stride_height, stride_width, false, ZDNN_INVALID_SHAPE); } int main() { UNITY_BEGIN(); RUN_TEST(verify_same_pass); RUN_TEST(verify_valid_pass); RUN_TEST(verify_format_mismatch_fail); RUN_TEST(verify_dtype_mismatch_fail); RUN_TEST(verify_bad_c_fail); RUN_TEST(verify_bad_n_fail); RUN_TEST(verify_0_strides_pass); RUN_TEST(verify_0_strides_same_padding_fail); RUN_TEST(verify_0_strides_stride_width_not_zero_fail); RUN_TEST(verify_0_strides_stride_height_not_zero_fail); RUN_TEST(verify_0_strides_bad_kernel_width_fail); RUN_TEST(verify_0_strides_bad_kernel_height_fail); RUN_TEST(verify_0_strides_bad_out_width_fail); RUN_TEST(verify_0_strides_bad_out_height_fail); RUN_TEST(verify_valid_bad_kernel_width_fail); RUN_TEST(verify_valid_bad_kernel_height_fail); RUN_TEST(verify_valid_bad_out_width_fail); RUN_TEST(verify_valid_bad_out_height_fail); RUN_TEST(verify_same_bad_out_width_fail); RUN_TEST(verify_same_bad_out_height_fail); return UNITY_END(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_tensor_verify_zdnn_lstm_gru.c�������������������������������������������0000664�0000000�0000000�00000043021�14364043643�0023715�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} #define BAD_FORMAT 255 #define BAD_TYPE 255 #define DEFAULT_NUM_TIMESTEPS 3 #define DEFAULT_NUM_BATCHES 4 #define DEFAULT_NUM_FEATURES 7 #define DEFAULT_NUM_HIDDEN 16 const uint32_t num_timesteps = DEFAULT_NUM_TIMESTEPS; const uint32_t num_batches = DEFAULT_NUM_BATCHES; const uint32_t num_features = DEFAULT_NUM_FEATURES; const uint32_t num_hidden = DEFAULT_NUM_HIDDEN; #define MAX_DESC_LEN 256 char msg[MAX_DESC_LEN]; typedef enum tensor_idx { INPUT, H0, C0, WEIGHTS, BIASES, HIDDEN_WEIGHTS, HIDDEN_BIASES, HN_OUTPUT, CF_OUTPUT, MAX_TENSOR_IDX, NONE = MAX_TENSOR_IDX } tensor_idx; // roll our own instead of using get_func_code_num_gates() in case that one // breaks #define NUM_GATES(f) ((f == NNPA_LSTMACT) ? 4 : 3) void create_ztensors(uint8_t function_code, uint32_t num_timesteps, uint32_t num_batches, uint32_t num_features, uint32_t num_hidden, uint32_t num_dirs, bool all_timesteps_out, zdnn_ztensor **rnn_ztens) { zdnn_data_layouts layout = ZDNN_NHWC; zdnn_data_types dtype = FP32; uint8_t num_gates = NUM_GATES(function_code); // baseline dimensions with correct requirements: fwd all-timesteps output uint32_t *shape[MAX_TENSOR_IDX]; // create ztensors using transformed shape + ZDNN_NHWC to make the code // simplier, so that we can loop through them all rather than dealing with // different pre-transformed layouts etc. // // if the dims transformation logic changes then these shapes need to be // changed too. shape[INPUT] = (uint32_t[]){num_timesteps, 1, num_batches, num_features}; shape[H0] = (uint32_t[]){num_dirs, 1, num_batches, num_hidden}; shape[C0] = (uint32_t[]){num_dirs, 1, num_batches, num_hidden}; shape[WEIGHTS] = (uint32_t[]){num_dirs, 1, num_features, num_gates * PADDED(num_hidden)}; shape[BIASES] = (uint32_t[]){num_dirs, 1, 1, num_gates * PADDED(num_hidden)}; shape[HIDDEN_WEIGHTS] = (uint32_t[]){num_dirs, 1, num_hidden, num_gates * PADDED(num_hidden)}; shape[HIDDEN_BIASES] = (uint32_t[]){num_dirs, 1, 1, num_gates * PADDED(num_hidden)}; shape[HN_OUTPUT] = (uint32_t[]){all_timesteps_out ? num_timesteps : 1, 1, num_batches, (num_dirs < 2) ? num_hidden : num_dirs * PADDED(num_hidden)}; shape[CF_OUTPUT] = (uint32_t[]){1, 1, num_batches, (num_dirs < 2) ? num_hidden : num_dirs * PADDED(num_hidden)}; for (int i = 0; i < MAX_TENSOR_IDX; i++) { rnn_ztens[i] = alloc_ztensor_with_values(shape[i], layout, dtype, NO_CONCAT, true, ZERO_ARRAY); } if (function_code == NNPA_GRUACT) { // set these to NULL so the test will blow up if used inappropriately shape[C0] = NULL; shape[CF_OUTPUT] = NULL; } } void set_dim(zdnn_tensor_desc *desc, uint8_t dim_idx, uint32_t value) { switch (dim_idx) { case (1): desc->dim1 = value; break; case (2): desc->dim2 = value; break; case (3): desc->dim3 = value; break; case (4): desc->dim4 = value; break; default: TEST_FAIL_MESSAGE_FORMATTED("%d is not a valid dim_idx to set.", dim_idx); break; } } // Verify return status by sabotaging a ztensor void verify(uint8_t function_code, lstm_gru_direction direction, bool all_timesteps_out, tensor_idx idx, bool sabotage_dim, uint8_t dim_idx, uint32_t dim_val, bool sabotage_type, zdnn_data_types type, bool sabotage_format, zdnn_data_formats format, zdnn_status exp_status, char *description) { // Create the test tensors set zdnn_ztensor *rnn_ztens[MAX_TENSOR_IDX]; create_ztensors(function_code, num_timesteps, num_batches, num_features, num_hidden, (direction == BIDIR) ? 2 : 1, all_timesteps_out, rnn_ztens); // Sabotage the dim/format/type of the ztensor specified in idx if (idx != NONE) { if (sabotage_dim) { set_dim(rnn_ztens[idx]->transformed_desc, dim_idx, dim_val); } if (sabotage_type) { rnn_ztens[idx]->transformed_desc->type = type; } if (sabotage_format) { rnn_ztens[idx]->transformed_desc->format = format; } } zdnn_status actual_status = verify_zdnn_lstm_or_gru_tensors( function_code, rnn_ztens[INPUT], rnn_ztens[H0], rnn_ztens[C0], rnn_ztens[WEIGHTS], rnn_ztens[BIASES], rnn_ztens[HIDDEN_WEIGHTS], rnn_ztens[HIDDEN_BIASES], (direction == BIDIR) ? 2 : 1, rnn_ztens[HN_OUTPUT], rnn_ztens[CF_OUTPUT]); if (actual_status != exp_status) { TEST_FAIL_MESSAGE_FORMATTED( "%s: Actual status return (%08x) does not match expected (%08x).", description, actual_status, exp_status); } // Cleanup for (int i = 0; i < MAX_TENSOR_IDX; i++) { free_ztensor_buffers(1, rnn_ztens[i]); } } // Verify return status by sabotaging the ztensor dimension void verify_shape(uint8_t function_code, lstm_gru_direction direction, bool all_timesteps_out, tensor_idx idx, uint8_t dim_idx, uint32_t dim_val, zdnn_status exp_status, char *description) { verify(function_code, direction, all_timesteps_out, idx, true, dim_idx, dim_val, false, 0, false, 0, exp_status, description); } // Verify return status by sabotaging the ztensor data type void verify_type(uint8_t function_code, lstm_gru_direction direction, bool all_timesteps_out, tensor_idx idx, zdnn_data_types type, zdnn_status exp_status, char *description) { verify(function_code, direction, all_timesteps_out, idx, false, 0, 0, true, type, false, 0, exp_status, description); } // Verify return status by sabotaging the ztensor format void verify_format(uint8_t function_code, lstm_gru_direction direction, bool all_timesteps_out, tensor_idx idx, zdnn_data_formats format, zdnn_status exp_status, char *description) { verify(function_code, direction, all_timesteps_out, idx, false, 0, 0, false, 0, true, format, exp_status, description); } // this macro assume values of NNPA_LSTMACT and NNPA_GRUACT are next to each // other #define LOOP_LSTM_AND_GRU(lg) \ for (int lg = NNPA_LSTMACT; lg < NNPA_GRUACT; lg++) // this macro assume lstm_gru_direction is an 0, 1, 2... enum #define LOOP_ALL_LSTM_GRU_DIRECTIONS(lgd) for (int lgd = 0; lgd < 3; lgd++) // this macro assumes false = 0, true = 1 #define LOOP_TRUE_AND_FALSE(tf) for (int tf = 0; tf < 2; tf++) /* * Test verification of valid activation tensors. * All tensors will be built with acceptable properties. */ void verify_pass() { // Expect no known error, no bad dims will be set LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { snprintf(msg, MAX_DESC_LEN, "%s %s %s all_timesteps_out: %s", __func__, act == NNPA_LSTMACT ? "LSTM" : "GRU", get_rnn_direction_str(direction), all_timesteps_out ? "true" : "false"); verify_shape(act, direction, all_timesteps_out, NONE, 0, 0, ZDNN_OK, msg); } } } } /* * Verify num_timesteps is 0 situation */ void verify_timestep_zero_fail() { LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { snprintf(msg, MAX_DESC_LEN, "%s %s %s all_timesteps_out: %s", __func__, act == NNPA_LSTMACT ? "LSTM" : "GRU", get_rnn_direction_str(direction), all_timesteps_out ? "true" : "false"); verify_shape(act, direction, all_timesteps_out, INPUT, 3, 0, ZDNN_INVALID_SHAPE, msg); } } } } /* * Verify num_timesteps mismatch situations */ void verify_timestep_mismatch_fail() { LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { snprintf(msg, MAX_DESC_LEN, "%s %s %s all_timesteps_out: %s", __func__, act == NNPA_LSTMACT ? "LSTM" : "GRU", get_rnn_direction_str(direction), all_timesteps_out ? "true" : "false"); verify_shape(act, direction, all_timesteps_out, H0, 3, num_timesteps + 1, ZDNN_INVALID_SHAPE, msg); } } } } /* * Verify num_batches mismatch situations */ void verify_batches_mismatch_fail() { LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { // input, h0, c0 and all outputs require the same dim2 (num_batches) #define TEST(tensor_idx) \ snprintf(msg, MAX_DESC_LEN, "%s %s %s %s all_timesteps_out: %s", __func__, \ act == NNPA_LSTMACT ? "LSTM" : "GRU", #tensor_idx, \ get_rnn_direction_str(direction), \ all_timesteps_out ? "true" : "false"); \ verify_shape(act, direction, all_timesteps_out, tensor_idx, 2, \ num_batches + 1, ZDNN_INVALID_SHAPE, msg); TEST(INPUT); TEST(H0); TEST(C0); TEST(HN_OUTPUT); TEST(CF_OUTPUT); #undef TEST } } } } /* * Verify num_features mismatch situations */ void verify_features_mismatch_fail() { LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { snprintf(msg, MAX_DESC_LEN, "%s %s %s all_timesteps_out: %s", __func__, act == NNPA_LSTMACT ? "LSTM" : "GRU", get_rnn_direction_str(direction), all_timesteps_out ? "true" : "false"); verify_shape(act, direction, all_timesteps_out, WEIGHTS, 2, num_features + 1, ZDNN_INVALID_SHAPE, msg); } } } } /* * Verify num_hidden mismatch situations */ void verify_hidden_mismatch_fail() { LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { // h0, c0 and all outputs require the same dim1 (num_hidden) #define TEST(tensor_idx) \ snprintf(msg, MAX_DESC_LEN, "%s %s%s %s all_timesteps_out: %s", __func__, \ act == NNPA_LSTMACT ? "LSTM" : "GRU", #tensor_idx, \ get_rnn_direction_str(direction), \ all_timesteps_out ? "true" : "false"); \ verify_shape(act, direction, all_timesteps_out, tensor_idx, 1, \ num_hidden + 1, ZDNN_INVALID_SHAPE, msg); TEST(H0); TEST(C0); TEST(HN_OUTPUT); TEST(CF_OUTPUT); #undef TEST // hidden_weights dim2 is num_hidden snprintf(msg, MAX_DESC_LEN, "%s %s %s %s all_timesteps_out: %s", __func__, act == NNPA_LSTMACT ? "LSTM" : "GRU", "HIDDEN_WEIGHTS", get_rnn_direction_str(direction), all_timesteps_out ? "true" : "false"); verify_shape(act, direction, all_timesteps_out, HIDDEN_WEIGHTS, 2, num_hidden + 1, ZDNN_INVALID_SHAPE, msg); // (hidden_) weights and biases should have in_pad value in dim1 uint32_t in_pad = NUM_GATES(act) * PADDED(num_hidden); #define TEST(tensor_idx) \ snprintf(msg, MAX_DESC_LEN, "%s %s %s %s all_timesteps_out: %s", __func__, \ act == NNPA_LSTMACT ? "LSTM" : "GRU", #tensor_idx, \ get_rnn_direction_str(direction), \ all_timesteps_out ? "true" : "false"); \ verify_shape(act, direction, all_timesteps_out, tensor_idx, 1, in_pad + 1, \ ZDNN_INVALID_SHAPE, msg); TEST(WEIGHTS); TEST(BIASES); TEST(HIDDEN_WEIGHTS); TEST(HIDDEN_BIASES); #undef TEST // the outputs should have out_pad value in dim1 uint32_t out_pad = (direction != BIDIR) ? num_hidden : 2 * PADDED(num_hidden); #define TEST(tensor_idx) \ snprintf(msg, MAX_DESC_LEN, "%s %s %s all_timesteps_out: %s", __func__, \ #tensor_idx, get_rnn_direction_str(direction), \ all_timesteps_out ? "true" : "false"); \ verify_shape(act, direction, all_timesteps_out, tensor_idx, 1, out_pad + 1, \ ZDNN_INVALID_SHAPE, msg); TEST(HN_OUTPUT); TEST(CF_OUTPUT); #undef TEST } } } } /* * Verify num_dirs mismatch situations */ void verify_dirs_mismatch_fail() { LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { // h0, c0 and all outputs require the same dim4 (num_dirs) #define TEST(tensor_idx) \ snprintf(msg, MAX_DESC_LEN, "%s %s %s %s all_timesteps_out: %s", __func__, \ act == NNPA_LSTMACT ? "LSTM" : "GRU", #tensor_idx, \ get_rnn_direction_str(direction), \ all_timesteps_out ? "true" : "false"); \ verify_shape(act, direction, all_timesteps_out, tensor_idx, 4, \ ((direction != BIDIR) ? 1 : 2) + 1, ZDNN_INVALID_SHAPE, msg); TEST(H0); TEST(C0); TEST(WEIGHTS); TEST(BIASES); TEST(HIDDEN_WEIGHTS); TEST(HIDDEN_BIASES); #undef TEST } } } } /* * Verify other dims not covered in other tests */ void verify_other_dims_fail() { LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { // dim3 of all tensors should be 1 #define TEST(tensor_idx) \ snprintf(msg, MAX_DESC_LEN, "%s %s %s %s all_timesteps_out: %s", __func__, \ act == NNPA_LSTMACT ? "LSTM" : "GRU", #tensor_idx, \ get_rnn_direction_str(direction), \ all_timesteps_out ? "true" : "false"); \ verify_shape(act, direction, all_timesteps_out, tensor_idx, 3, 2, \ ZDNN_INVALID_SHAPE, msg); TEST(INPUT); TEST(H0); TEST(C0); TEST(WEIGHTS); TEST(BIASES); TEST(HIDDEN_WEIGHTS); TEST(HIDDEN_BIASES); TEST(HN_OUTPUT); TEST(CF_OUTPUT); #undef TEST // dim2 of (hidden_)biases should be 1 #define TEST(tensor_idx) \ snprintf(msg, MAX_DESC_LEN, "%s %s %s %s all_timesteps_out: %s", __func__, \ act == NNPA_LSTMACT ? "LSTM" : "GRU", #tensor_idx, \ get_rnn_direction_str(direction), \ all_timesteps_out ? "true" : "false"); \ verify_shape(act, direction, all_timesteps_out, tensor_idx, 2, 2, \ ZDNN_INVALID_SHAPE, msg); TEST(BIASES); TEST(HIDDEN_BIASES); #undef TEST } } } } /* * Test verification of failed format */ void verify_fail_format() { LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { snprintf(msg, MAX_DESC_LEN, "%s %s %s all_timesteps_out: %s", __func__, act == NNPA_LSTMACT ? "LSTM" : "GRU", get_rnn_direction_str(direction), all_timesteps_out ? "true" : "false"); verify_format(act, direction, all_timesteps_out, HN_OUTPUT, BAD_FORMAT, ZDNN_INVALID_FORMAT, msg); } } } } /* * Test verification of failed type */ void verify_fail_type() { LOOP_LSTM_AND_GRU(act) { LOOP_ALL_LSTM_GRU_DIRECTIONS(direction) { LOOP_TRUE_AND_FALSE(all_timesteps_out) { snprintf(msg, MAX_DESC_LEN, "%s %s %s all_timesteps_out: %s", __func__, act == NNPA_LSTMACT ? "LSTM" : "GRU", get_rnn_direction_str(direction), all_timesteps_out ? "true" : "false"); verify_type(act, direction, all_timesteps_out, HN_OUTPUT, BAD_TYPE, ZDNN_INVALID_TYPE, msg); } } } } int main() { UNITY_BEGIN(); RUN_TEST(verify_pass); RUN_TEST(verify_timestep_zero_fail); RUN_TEST(verify_timestep_mismatch_fail); RUN_TEST(verify_batches_mismatch_fail); RUN_TEST(verify_features_mismatch_fail); RUN_TEST(verify_hidden_mismatch_fail); RUN_TEST(verify_dirs_mismatch_fail); RUN_TEST(verify_other_dims_fail); RUN_TEST(verify_fail_format); RUN_TEST(verify_fail_type); return UNITY_END(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_transform_dims.c��������������������������������������������������������0000664�0000000�0000000�00000026231�14364043643�0021105�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> void setUp(void) {} void tearDown(void) {} /* Common routine for testing dimension translation Transformed dimensions must match the expected */ void test_tfrmd_dims(zdnn_data_layouts pre_tfrmd_layout, uint32_t pre_tfrmd_dim4, uint32_t pre_tfrmd_dim3, uint32_t pre_tfrmd_dim2, uint32_t pre_tfrmd_dim1, uint32_t tfrmd_dim4, uint32_t tfrmd_dim3, uint32_t tfrmd_dim2, uint32_t tfrmd_dim1) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_status status; switch (pre_tfrmd_layout) { case (ZDNN_1D): zdnn_init_pre_transformed_desc(pre_tfrmd_layout, test_datatype, &pre_tfrmd_desc, pre_tfrmd_dim1); break; case (ZDNN_2D): case (ZDNN_2DS): zdnn_init_pre_transformed_desc(pre_tfrmd_layout, test_datatype, &pre_tfrmd_desc, pre_tfrmd_dim2, pre_tfrmd_dim1); break; case (ZDNN_3D): case (ZDNN_3DS): zdnn_init_pre_transformed_desc(pre_tfrmd_layout, test_datatype, &pre_tfrmd_desc, pre_tfrmd_dim3, pre_tfrmd_dim2, pre_tfrmd_dim1); break; default: zdnn_init_pre_transformed_desc( pre_tfrmd_layout, test_datatype, &pre_tfrmd_desc, pre_tfrmd_dim4, pre_tfrmd_dim3, pre_tfrmd_dim2, pre_tfrmd_dim1); } status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() failed (status = %08x)", status); TEST_ASSERT_MESSAGE_FORMATTED( tfrmd_desc.dim4 == tfrmd_dim4, "tfrmd_desc.dim4 (%u) doesn't match expected (%u)", tfrmd_desc.dim4, tfrmd_dim4); TEST_ASSERT_MESSAGE_FORMATTED( tfrmd_desc.dim3 == tfrmd_dim3, "tfrmd_desc.dim3 (%u) doesn't match expected (%u)", tfrmd_desc.dim3, tfrmd_dim3); TEST_ASSERT_MESSAGE_FORMATTED( tfrmd_desc.dim2 == tfrmd_dim2, "tfrmd_desc.dim2 (%u) doesn't match expected (%u)", tfrmd_desc.dim2, tfrmd_dim4); TEST_ASSERT_MESSAGE_FORMATTED( tfrmd_desc.dim1 == tfrmd_dim1, "tfrmd_desc.dim1 (%u) doesn't match expected (%u)", tfrmd_desc.dim1, tfrmd_dim4); } /* Common routine for testing dimension translation (concatenated types) Transformed dimensions must match the expected pre_tfrmd_dim3 is ignored when pre_tfrmd_layout is ZDNN_2DS */ void test_tfrmd_concat_dims(zdnn_data_layouts pre_tfrmd_layout, uint32_t pre_tfrmd_dim3, uint32_t pre_tfrmd_dim2, uint32_t pre_tfrmd_dim1, zdnn_concat_info info) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_status status; uint32_t expected_dim4 = 0, expected_dim3 = 0, expected_dim2 = 0, expected_dim1 = 0; uint8_t num_concats = 0; if (CONCAT_RNN_TYPE(info) == RNN_TYPE_LSTM) { num_concats = 4; } else if (CONCAT_RNN_TYPE(info) == RNN_TYPE_GRU) { num_concats = 3; } else { TEST_FAIL_MESSAGE_FORMATTED("bad concat info: %08x\n", info); } switch (pre_tfrmd_layout) { case (ZDNN_2DS): expected_dim4 = pre_tfrmd_dim2; expected_dim3 = 1; expected_dim2 = 1; expected_dim1 = CEIL(pre_tfrmd_dim1, AIU_2BYTE_CELLS_PER_STICK) * AIU_2BYTE_CELLS_PER_STICK * num_concats; zdnn_init_pre_transformed_desc(pre_tfrmd_layout, test_datatype, &pre_tfrmd_desc, pre_tfrmd_dim2, pre_tfrmd_dim1); break; case (ZDNN_3DS): expected_dim4 = pre_tfrmd_dim3; expected_dim3 = 1; if ((CONCAT_USAGE(info) == USAGE_WEIGHTS) && (CONCAT_PREV_LAYER(info) == PREV_LAYER_BIDIR)) { expected_dim2 = CEIL(pre_tfrmd_dim2 / 2, AIU_2BYTE_CELLS_PER_STICK) * AIU_2BYTE_CELLS_PER_STICK * 2; } else { expected_dim2 = pre_tfrmd_dim2; } expected_dim1 = CEIL(pre_tfrmd_dim1, AIU_2BYTE_CELLS_PER_STICK) * AIU_2BYTE_CELLS_PER_STICK * num_concats; zdnn_init_pre_transformed_desc(pre_tfrmd_layout, test_datatype, &pre_tfrmd_desc, pre_tfrmd_dim3, pre_tfrmd_dim2, pre_tfrmd_dim1); break; default: TEST_FAIL_MESSAGE("unknown pre_tfrmd_layout"); break; } status = zdnn_generate_transformed_desc_concatenated(&pre_tfrmd_desc, info, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() status is %08x (%s) " "but expects %08x (%s))", status, zdnn_get_status_message(status), ZDNN_OK, zdnn_get_status_message(ZDNN_OK)); TEST_ASSERT_MESSAGE_FORMATTED( tfrmd_desc.dim4 == expected_dim4, "tfrmd_desc.dim4 (%u) doesn't match expected (%u)", tfrmd_desc.dim4, expected_dim4); TEST_ASSERT_MESSAGE_FORMATTED( tfrmd_desc.dim3 == expected_dim3, "tfrmd_desc.dim3 (%u) doesn't match expected (%u)", tfrmd_desc.dim3, expected_dim3); TEST_ASSERT_MESSAGE_FORMATTED( tfrmd_desc.dim2 == expected_dim2, "tfrmd_desc.dim2 (%u) doesn't match expected (%u)", tfrmd_desc.dim2, expected_dim2); TEST_ASSERT_MESSAGE_FORMATTED( tfrmd_desc.dim1 == expected_dim1, "tfrmd_desc.dim1 (%u) doesn't match expected (%u)", tfrmd_desc.dim1, expected_dim1); } void test_tfrmd_dims_nhwc_1() { test_tfrmd_dims(ZDNN_NHWC, 1, 1, 1, 3, 1, 1, 1, 3); } void test_tfrmd_dims_nhwc_2() { test_tfrmd_dims(ZDNN_NHWC, 4, 3, 2, 7, 4, 3, 2, 7); } void test_tfrmd_dims_4d() { test_tfrmd_dims(ZDNN_4D, 2, 3, 2, 3, 2, 3, 2, 3); } void test_tfrmd_dims_3ds_1() { test_tfrmd_dims(ZDNN_3DS, 0, 5, 1, 3, 5, 1, 1, 3); } void test_tfrmd_dims_3ds_2() { test_tfrmd_dims(ZDNN_3DS, 0, 3, 4, 2, 3, 1, 4, 2); } void test_tfrmd_dims_3d() { test_tfrmd_dims(ZDNN_3D, 0, 16, 32, 5, 1, 16, 32, 5); } void test_tfrmd_dims_2ds() { test_tfrmd_dims(ZDNN_2DS, 0, 0, 4, 2, 4, 1, 1, 2); } void test_tfrmd_dims_2d() { test_tfrmd_dims(ZDNN_2D, 0, 0, 2, 5, 1, 1, 2, 5); } void test_tfrmd_dims_1d() { test_tfrmd_dims(ZDNN_1D, 0, 0, 0, 5, 1, 1, 1, 5); } void test_tfrmd_dims_lstm_biases() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_tfrmd_concat_dims(ZDNN_2DS, 0, 2, 16, RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j]); } } } void test_tfrmd_dims_lstm_no_vconcat_weights() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_tfrmd_concat_dims(ZDNN_3DS, 2, 15, 72, RNN_TYPE_LSTM | no_vconcat_infos[i]); } } void test_tfrmd_dims_lstm_prev_bidir_weights() { test_tfrmd_concat_dims(ZDNN_3DS, 2, 20, 72, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS); } void test_tfrmd_dims_gru_biases() { for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_tfrmd_concat_dims(ZDNN_2DS, 0, 2, 16, RNN_TYPE_GRU | prev_layers[i] | biases_usages[j]); } } } void test_tfrmd_dims_gru_no_vconcat_weights() { for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_tfrmd_concat_dims(ZDNN_3DS, 2, 15, 72, RNN_TYPE_GRU | no_vconcat_infos[i]); } } void test_tfrmd_dims_gru_prev_bidir_weights() { test_tfrmd_concat_dims(ZDNN_3DS, 2, 20, 72, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS); } void test_concat_weights_dim2(zdnn_concat_info info, uint32_t dim3, uint32_t dim2, uint32_t dim1, zdnn_status exp_status) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_status status; zdnn_init_pre_transformed_desc(ZDNN_3DS, test_datatype, &pre_tfrmd_desc, dim3, dim2, dim1); status = zdnn_generate_transformed_desc_concatenated(&pre_tfrmd_desc, info, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED(status == exp_status, "zdnn_generate_transformed_desc_concatenated(" ") unexpected status (status = %08x, " "expects = %08x)", status, exp_status); } void test_tfrmd_dims_lstm_no_vconcat_weights_odd_dim2_pass() { test_concat_weights_dim2(RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_UNI, 3, 9, 10, ZDNN_OK); } void test_tfrmd_dims_lstm_prev_bidir_weights_odd_dim2_fail() { test_concat_weights_dim2(RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_BIDIR, 3, 9, 10, ZDNN_INVALID_SHAPE); } void test_tfrmd_dims_gru_no_vconcat_weights_odd_dim2_pass() { test_concat_weights_dim2(RNN_TYPE_LSTM | USAGE_WEIGHTS | PREV_LAYER_UNI, 3, 9, 10, ZDNN_OK); } void test_tfrmd_dims_gru_prev_bidir_weights_odd_dim2_fail() { test_concat_weights_dim2(RNN_TYPE_GRU | USAGE_WEIGHTS | PREV_LAYER_BIDIR, 3, 9, 10, ZDNN_INVALID_SHAPE); } void test_tfrmd_dims_4ds_uni_rnn_output() { test_tfrmd_dims(ZDNN_4DS, 2, 1, 3, 4, 2, 1, 3, 4); } void test_tfrmd_dims_4ds_bidir_rnn_output() { test_tfrmd_dims(ZDNN_4DS, 2, 2, 3, 4, 2, 1, 3, 128); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_nhwc_1); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_nhwc_2); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_4d); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_3ds_1); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_3ds_2); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_3d); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_2ds); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_2d); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_1d); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_lstm_biases); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_lstm_no_vconcat_weights); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_lstm_prev_bidir_weights); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_gru_biases); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_gru_no_vconcat_weights); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_gru_prev_bidir_weights); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_lstm_no_vconcat_weights_odd_dim2_pass); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_lstm_prev_bidir_weights_odd_dim2_fail); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_gru_no_vconcat_weights_odd_dim2_pass); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_gru_prev_bidir_weights_odd_dim2_fail); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_4ds_uni_rnn_output); RUN_TEST_ALL_DATATYPES(test_tfrmd_dims_4ds_bidir_rnn_output); return UNITY_END(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_unstickify.c������������������������������������������������������������0000664�0000000�0000000�00000074434�14364043643�0020256�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} //================================================================================================= // tests for unstickify /* Use 1x4x4x1 as example: 1) Create the input tensor descriptor 2) Create the raw (i.e., dense) input tensor data with random FP16/FP32/BFLOAT values 1 >= x > SMALLEST_RANDOM_FP. For 1x4x4x1 we have 16 elements. 3) Create a zTensor with that. 4a) If caller wants to use offsets, we'll "stickify" the input tensor data by putting things in ztensor.buffer directly: stick_area[offsets[n] = fp16_to_dlf16(input_data[n]). 4b) If NO_OFFSETS, we'll use the official stickify routine. 5) Send that zTensor to unstickify, result goes to "data_unstickified" 6) compare the raw input tensor data against that "data_unstickified" array. The rationale is since we're using random FP data, if there's something wrong with the unstickify routine then it's very unlikely to match 100% with the raw input data. */ void test_unstickify(uint32_t dim4, uint32_t dim3, uint32_t dim2, uint32_t dim1, zdnn_data_layouts layout, offset_mode offset_mode, const char *path) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; void *data, *data_unstickified; switch (layout) { case (ZDNN_1D): zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, dim1); break; case (ZDNN_2D): case (ZDNN_2DS): zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, dim2, dim1); break; case (ZDNN_3D): case (ZDNN_3DS): zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, dim3, dim2, dim1); break; default: zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, dim4, dim3, dim2, dim1); } status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() failed (status = %08x)", status); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc() failed (status = %08x)", status); uint64_t num_elements = get_num_elements(&ztensor, ELEMENTS_PRE); data = create_and_fill_random_fp_data(&ztensor); data_unstickified = malloc(num_elements * get_data_type_size(pre_tfrmd_desc.type)); if (offset_mode == NO_OFFSETS) { // Stickify tensor using the official API status = zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_transform_ztensor failed (status = %08x)", status); } else { // "stickify" by converting input values to DLFLOAT16s and writing directly // to the ztensor's buffer. size_t *offsets; if (layout != ZDNN_4DS) { offsets = alloc_offsets(&ztensor, offset_mode, path); } else { offsets = alloc_rnn_output_offsets(&ztensor); } for (uint64_t i = 0; i < num_elements; i++) { uint16_t stickified_input_value = 0; switch (test_datatype) { case BFLOAT: stickified_input_value = cnvt_1_bfloat_to_dlf16(((uint16_t *)data)[i]); break; case FP16: stickified_input_value = cnvt_1_fp16_to_dlf16(((uint16_t *)data)[i]); break; case FP32: stickified_input_value = cnvt_1_fp32_to_dlf16(((float *)data)[i]); break; default: TEST_FAIL_MESSAGE("Unsupported data type"); free(data_unstickified); return; } // offsets[i] is in # of bytes // ztensor.buffer is void* // stickified_input_value is uint16_t *(uint16_t *)((uintptr_t)(ztensor.buffer) + offsets[i]) = stickified_input_value; } free(offsets); // hack, since we never actually stickified anything ztensor.is_transformed = true; } status = zdnn_transform_origtensor(&ztensor, data_unstickified); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_transform_origtensor failed (status = %08x)", status); BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { dumpdata_origtensor(&pre_tfrmd_desc, data, AS_FLOAT); dumpdata_ztensor(&ztensor, AS_FLOAT, false); dumpdata_origtensor(&pre_tfrmd_desc, data_unstickified, AS_FLOAT); } char *error_fmt = "Incorrect value at element %" PRIu64 ": Unstickified: " "%.6f, Expected: %.6f"; // the zdnn_transform_origtensor() values went through a // FP16/32/BFLOAT16 -> DLFLOAT16 -> FP16/32/BFLOAT16 roundtrip, so we can't // just compare them with like a memcmp() because we could have lost precision // during the process for (uint64_t i = 0; i < num_elements; i++) { switch (test_datatype) { case BFLOAT: { // raw tensor value, this is the "expected" value uint16_t data_val = ((uint16_t *)data)[i]; // BFLOAT -> DLFLOAT16 -> BFLOAT roundtrip'd tensor // value uint16_t data_unstickified_val = ((uint16_t *)data_unstickified)[i]; TEST_ASSERT_MESSAGE_FORMATTED( almost_equal_bfloat(data_unstickified_val, data_val), error_fmt, i, cnvt_1_bfloat_to_fp32(data_unstickified_val), cnvt_1_bfloat_to_fp32(data_val)); break; } case FP16: { // raw tensor value uint16_t data_val = ((uint16_t *)data)[i]; // FP16 -> DLFLOAT16 -> FP16 roundtrip'd tensor value uint16_t data_unstickified_val = ((uint16_t *)data_unstickified)[i]; TEST_ASSERT_MESSAGE_FORMATTED( almost_equal_fp16(data_unstickified_val, data_val), error_fmt, i, cnvt_1_fp16_to_fp32(data_unstickified_val), cnvt_1_fp16_to_fp32(data_val)); break; } case FP32: { // raw tensor value float data_val = ((float *)data)[i]; // FP32 -> DLFLOAT16 -> FP32 roundtrip'd tensor value float data_unstickified_val = ((float *)data_unstickified)[i]; TEST_ASSERT_MESSAGE_FORMATTED( almost_equal_float(data_unstickified_val, data_val), error_fmt, i, data_unstickified_val, data_val); break; } default: TEST_FAIL_MESSAGE("Unsupported data type"); return; } } free(data); free(data_unstickified); zdnn_free_ztensor_buffer(&ztensor); } /************************************************************** * NHWC **************************************************************/ #define NHWC_TEST_BASIC(n, h, w, c) \ void test_nhwc_##n##x##h##x##w##x##c() { \ test_unstickify(n, h, w, c, ZDNN_NHWC, QUICK_OFFSETS, NULL); \ } /* * Tensor with 16 entries, NHWC * 1,4,4,1 NHWC will use one cell per stick, 4 sticks per page and a total of * 4 pages. */ NHWC_TEST_BASIC(1, 4, 4, 1); NHWC_TEST_BASIC(1, 4, 4, 2); /* * Tensor with 1024 entries, NHWC * 1,32,32,1 NHWC will use 1 cell per stick, all sticks in the page, * and 32 pages. */ NHWC_TEST_BASIC(1, 32, 32, 1); NHWC_TEST_BASIC(1, 32, 32, 2); NHWC_TEST_BASIC(1, 32, 32, 3); NHWC_TEST_BASIC(1, 1, 2, 1); NHWC_TEST_BASIC(1, 1, 2, 2); NHWC_TEST_BASIC(1, 1, 2, 4); NHWC_TEST_BASIC(1, 1, 2, 7); NHWC_TEST_BASIC(1, 1, 4, 1); NHWC_TEST_BASIC(1, 1, 4, 2); NHWC_TEST_BASIC(1, 1, 4, 4); NHWC_TEST_BASIC(1, 1, 4, 7); NHWC_TEST_BASIC(1, 1, 7, 1); NHWC_TEST_BASIC(1, 1, 7, 2); NHWC_TEST_BASIC(1, 1, 7, 4); NHWC_TEST_BASIC(1, 1, 7, 7); NHWC_TEST_BASIC(1, 1, 8, 1); NHWC_TEST_BASIC(1, 1, 8, 2); NHWC_TEST_BASIC(1, 1, 8, 4); NHWC_TEST_BASIC(1, 1, 8, 7); NHWC_TEST_BASIC(1, 1, 13, 1); NHWC_TEST_BASIC(1, 1, 13, 2); NHWC_TEST_BASIC(1, 1, 13, 4); NHWC_TEST_BASIC(1, 1, 13, 7); NHWC_TEST_BASIC(1, 1, 100, 1); NHWC_TEST_BASIC(1, 1, 100, 2); NHWC_TEST_BASIC(1, 1, 100, 4); NHWC_TEST_BASIC(1, 1, 100, 7); NHWC_TEST_BASIC(2, 3, 2, 1); NHWC_TEST_BASIC(2, 3, 2, 2); NHWC_TEST_BASIC(2, 3, 2, 4); NHWC_TEST_BASIC(2, 3, 2, 7); NHWC_TEST_BASIC(2, 3, 4, 1); NHWC_TEST_BASIC(2, 3, 4, 2); NHWC_TEST_BASIC(2, 3, 4, 4); NHWC_TEST_BASIC(2, 3, 4, 7); NHWC_TEST_BASIC(2, 3, 7, 1); NHWC_TEST_BASIC(2, 3, 7, 2); NHWC_TEST_BASIC(2, 3, 7, 4); NHWC_TEST_BASIC(2, 3, 7, 7); NHWC_TEST_BASIC(2, 3, 8, 1); NHWC_TEST_BASIC(2, 3, 8, 2); NHWC_TEST_BASIC(2, 3, 8, 4); NHWC_TEST_BASIC(2, 3, 8, 7); NHWC_TEST_BASIC(2, 3, 13, 1); NHWC_TEST_BASIC(2, 3, 13, 2); NHWC_TEST_BASIC(2, 3, 13, 4); NHWC_TEST_BASIC(2, 3, 13, 7); NHWC_TEST_BASIC(2, 3, 100, 1); NHWC_TEST_BASIC(2, 3, 100, 2); NHWC_TEST_BASIC(2, 3, 100, 4); NHWC_TEST_BASIC(2, 3, 100, 7); NHWC_TEST_BASIC(3, 2, 2, 1); NHWC_TEST_BASIC(3, 2, 2, 2); NHWC_TEST_BASIC(3, 2, 2, 4); NHWC_TEST_BASIC(3, 2, 2, 7); NHWC_TEST_BASIC(3, 2, 4, 1); NHWC_TEST_BASIC(3, 2, 4, 2); NHWC_TEST_BASIC(3, 2, 4, 4); NHWC_TEST_BASIC(3, 2, 4, 7); NHWC_TEST_BASIC(3, 2, 7, 1); NHWC_TEST_BASIC(3, 2, 7, 2); NHWC_TEST_BASIC(3, 2, 7, 4); NHWC_TEST_BASIC(3, 2, 7, 7); NHWC_TEST_BASIC(3, 2, 8, 1); NHWC_TEST_BASIC(3, 2, 8, 2); NHWC_TEST_BASIC(3, 2, 8, 4); NHWC_TEST_BASIC(3, 2, 8, 7); NHWC_TEST_BASIC(3, 2, 13, 1); NHWC_TEST_BASIC(3, 2, 13, 2); NHWC_TEST_BASIC(3, 2, 13, 4); NHWC_TEST_BASIC(3, 2, 13, 7); NHWC_TEST_BASIC(3, 2, 100, 1); NHWC_TEST_BASIC(3, 2, 100, 2); NHWC_TEST_BASIC(3, 2, 100, 4); NHWC_TEST_BASIC(3, 2, 100, 7); void test_nhwc_1x1x1xe1(int e1) { test_unstickify(1, 1, 1, e1, ZDNN_NHWC, QUICK_OFFSETS, NULL); } void test_nhwc_1x1x1x4() { test_nhwc_1x1x1xe1(4); } void test_nhwc_1x1x1x5() { test_nhwc_1x1x1xe1(5); } void test_nhwc_1x1x1x8() { test_nhwc_1x1x1xe1(8); } void test_nhwc_1x1x1x9() { test_nhwc_1x1x1xe1(9); } void test_nhwc_1x1x1x63() { test_nhwc_1x1x1xe1(63); } void test_nhwc_1x1x1x64() { test_nhwc_1x1x1xe1(64); } void test_nhwc_1x1x1x65() { test_nhwc_1x1x1xe1(65); } void test_nhwc_1x1x1x127() { test_nhwc_1x1x1xe1(127); } void test_nhwc_1x1x1x128() { test_nhwc_1x1x1xe1(128); } /* * Tensor with 16 entries, 3DS * 4,4,1 3DS will use one cell per stick, 4 sticks per page and a total of 4 * pages. */ void test_3ds_4x4x1() { // first entry doesn't matter test_unstickify(9999, 4, 4, 1, ZDNN_3DS, QUICK_OFFSETS, NULL); } /* * Tensor with 3072 entries, 3DS * 32,32,3 3DS will use 3 cells per stick, all sticks in the page, * and 32 pages. */ void test_3ds_32x32x3() { // first entry doesn't matter test_unstickify(9999, 32, 32, 3, ZDNN_3DS, QUICK_OFFSETS, NULL); } /* * Tensor with 8 entries, 2DS * 4,2 2DS will use two cells per stick, (implied 1 stick per page) and a * total of 4 pages. */ void test_2ds_4x2() { // first two entries don't matter in 2DS test_unstickify(9999, 9999, 4, 2, ZDNN_2DS, QUICK_OFFSETS, NULL); } /* * Tensor with 4k entries, 2DS * We expect this to require 4 pages total. Each dim2 will require 2 pages. * The first page will have all 64 cells of all 32 sticks filled holding 2048 * values. A second page will have 1 stick with 1 cell filled to hold val * 2049. */ void test_2ds_2x2049() { // first two entries don't matter in 2DS test_unstickify(9999, 9999, 2, 2049, ZDNN_2DS, QUICK_OFFSETS, NULL); } /************************************************************** * NCHW **************************************************************/ #define NCHW_TEST_WITH_FILE(n, c, h, w) \ void test_nchw_##n##x##c##x##h##x##w() { \ test_unstickify(n, c, h, w, ZDNN_NCHW, FILE_OFFSETS, \ OFFSET_FILE(nchw, n, c, h, w)); \ } NCHW_TEST_WITH_FILE(1, 1, 4, 4) NCHW_TEST_WITH_FILE(1, 4, 2, 3) NCHW_TEST_WITH_FILE(1, 3, 32, 32) NCHW_TEST_WITH_FILE(2, 129, 3, 33) NCHW_TEST_WITH_FILE(1, 64, 1, 31) NCHW_TEST_WITH_FILE(1, 64, 1, 32) NCHW_TEST_WITH_FILE(1, 64, 1, 33) NCHW_TEST_WITH_FILE(1, 63, 1, 32) NCHW_TEST_WITH_FILE(1, 65, 1, 32) NCHW_TEST_WITH_FILE(1, 127, 1, 4) NCHW_TEST_WITH_FILE(1, 128, 1, 4) NCHW_TEST_WITH_FILE(1, 129, 1, 4) NCHW_TEST_WITH_FILE(1, 4, 1, 63) NCHW_TEST_WITH_FILE(1, 4, 1, 64) NCHW_TEST_WITH_FILE(1, 4, 1, 65) /************************************************************** * RNN OUTPUT **************************************************************/ #define RNN_OUT_TEST(d4, d3, d2, d1) \ void test_rnn_output_##d4##x##d3##x##d2##x##d1() { \ test_unstickify(d4, d3, d2, d1, ZDNN_4DS, QUICK_OFFSETS, NULL); \ } RNN_OUT_TEST(5, 1, 4, 3) RNN_OUT_TEST(1, 1, 4, 3) RNN_OUT_TEST(5, 1, 4, 64) RNN_OUT_TEST(1, 1, 4, 64) RNN_OUT_TEST(5, 1, 4, 65) RNN_OUT_TEST(1, 1, 4, 65) RNN_OUT_TEST(5, 1, 31, 5) RNN_OUT_TEST(1, 1, 31, 5) RNN_OUT_TEST(5, 1, 60, 5) RNN_OUT_TEST(1, 1, 60, 5) RNN_OUT_TEST(5, 2, 4, 3) RNN_OUT_TEST(1, 2, 4, 3) RNN_OUT_TEST(5, 2, 4, 64) RNN_OUT_TEST(1, 2, 4, 64) RNN_OUT_TEST(5, 2, 4, 65) RNN_OUT_TEST(1, 2, 4, 65) RNN_OUT_TEST(5, 2, 31, 5) RNN_OUT_TEST(1, 2, 31, 5) RNN_OUT_TEST(5, 2, 60, 5) RNN_OUT_TEST(1, 2, 60, 5) void test_unstickify_4dfeature_twice() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; zdnn_init_pre_transformed_desc(ZDNN_NHWC, test_datatype, &pre_tfrmd_desc, 1, 4, 4, 1); status = zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc() failed (status = %08x)", status); status = zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc() failed (status = %08x)", status); unsigned char *data_unstickified = malloc(get_num_elements(&ztensor, ELEMENTS_PRE) * get_data_type_size(pre_tfrmd_desc.type)); ztensor.is_transformed = true; // hack, since we never actually // stickified anything status = zdnn_transform_origtensor(&ztensor, data_unstickified); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "First unstickify: expected status = %08x, actual status = %08x", ZDNN_OK, status); // second one should still be OK status = zdnn_transform_origtensor(&ztensor, data_unstickified); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "Second unstickify: expected status = %08x, actual status = %08x", ZDNN_OK, status); } void test_stickify_unstickify(uint32_t dim4, uint32_t dim3, uint32_t dim2, uint32_t dim1, zdnn_data_layouts layout) { test_unstickify(dim4, dim3, dim2, dim1, layout, NO_OFFSETS, NULL); } /* * Tensor with 16 entries, NHWC * 1,4,4,1 NHWC will use one cell per stick, 4 sticks per page and a total of * 4 pages. */ // void test_stickify_unstickify_nhwc_1x4x4x1() { test_stickify_unstickify(1, 4, 4, 1, ZDNN_NHWC); } void test_stickify_unstickify_nhwc_1x4x4x2() { test_stickify_unstickify(1, 4, 4, 2, ZDNN_NHWC); } /* * Tensor with 3072 entries, NHWC * 1,32,32,1 NHWC will use 1 cell per stick, all sticks in the page, * and 32 pages. */ // void test_stickify_unstickify_nhwc_1x32x32x1() { test_stickify_unstickify(1, 32, 32, 1, ZDNN_NHWC); } void test_stickify_unstickify_nhwc_1x32x32x2() { test_stickify_unstickify(1, 32, 32, 2, ZDNN_NHWC); } void test_stickify_unstickify_nhwc_1x32x32x3() { test_stickify_unstickify(1, 32, 32, 3, ZDNN_NHWC); } void test_stickify_unstickify_nhwc_1x2x33x65() { test_stickify_unstickify(1, 2, 33, 65, ZDNN_NHWC); } void test_stickify_unstickify_nchw_1x4x4x1() { test_stickify_unstickify(1, 4, 4, 1, ZDNN_NCHW); } void test_stickify_unstickify_nchw_1x32x32x3() { test_stickify_unstickify(1, 32, 32, 3, ZDNN_NCHW); } void test_stickify_unstickify_nchw_1x2x33x65() { test_stickify_unstickify(1, 2, 33, 65, ZDNN_NCHW); } // This routine tests the conversion from DLF to FP16. // Input: a "bad" value in DLFloat, which will "trip" the // floating point exception trigger on VCFN void test_ztensor_bad_value_FP16(uint16_t bad_value) { #define TOO_LARGE_DLF16_POS 0x7E00 #define TOO_LARGE_DLF16_NEG 0xFE00 #define TOO_SMALL_DLF16_POS 0x0001 #define TOO_SMALL_DLF16_NEG 0x8001 // Note: Ninf = "NaN or INF" #define NINF_DLF16_POS 0x7FFF #define NINF_DLF16_NEG 0xFFFF #define STICK_ENTRIES_FP16 7 uint32_t stick_entries_to_try[STICK_ENTRIES_FP16] = {0, 1, 7, 8, 9, 62, 63}; zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; unsigned char *data; zdnn_status status; uint16_t *array; // Alternate view on the stickified_data (ztensor.buffer) unsigned char *unstickified_data; // Build a transformed ztensor with valid data zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP16, &pre_tfrmd_desc, 1, 1, 1, 64); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); data = create_and_fill_random_fp_data(&ztensor); // Transform the data to an is_stickified ztensor, so we can test // unstickification later status = zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE_FORMATTED(status == ZDNN_OK, "zdnn_transform_ztensor failed (status = %08x)", status); // Create an area to unstickify/convert back to uint64_t num_elements = get_num_elements(&ztensor, ELEMENTS_PRE); zdnn_data_types dtype = ztensor.pre_transformed_desc->type; unstickified_data = malloc(num_elements * get_data_type_size(dtype)); array = (uint16_t *)ztensor.buffer; /* use stickified_data as an array */ for (int i = 0; i < STICK_ENTRIES_FP16; i++) { array[stick_entries_to_try[i]] = bad_value; status = zdnn_transform_origtensor(&ztensor, unstickified_data); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_CONVERT_FAILURE, "zdnn_transform_origtensor() succeeded (status = %08x, expects = " "%08x, i = %d, value = %04x)", status, ZDNN_CONVERT_FAILURE, i, bad_value); array[stick_entries_to_try[i]] = 0; // set entry to 0 for next iteration } // Free allocated storage free(data); free(unstickified_data); zdnn_free_ztensor_buffer(&ztensor); } // Test unstickify conversions DLFloat to FP16 (VCFN) void test_ztensor_fp16_bad_values() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE("needs NNPA to trigger overflow"); #endif test_ztensor_bad_value_FP16( TOO_LARGE_DLF16_POS); // is not a number, will cause overflow test_ztensor_bad_value_FP16( TOO_LARGE_DLF16_NEG); // is not a number, will cause overflow // TODO: // The following look valid in the documentation, but do not happen on test // system at this time // test_ztensor_bad_value_FP16( // TOO_SMALL_DLF16_POS); // is not a number, will cause overflow // test_ztensor_bad_value_FP16( // TOO_SMALL_DLF16_NEG); // is not a number, will cause overflow test_ztensor_bad_value_FP16( NINF_DLF16_POS); // is not a number, will cause invalid op test_ztensor_bad_value_FP16(NINF_DLF16_NEG); // is not a number, will cause // invalid op } // This routine tests the conversion from DLF to FP32. // Input: a "bad" value in DLFloat, which will "trip" the // floating point exception trigger on VCLFNH/VCLFNL // NOTE: Only Not-A-Number values will trip the exception. // "Anything DLFLOAT16 can represent, FP32 can do better." -TinTo void test_ztensor_bad_value_FP32(uint16_t bad_value) { #define NAN_DL16_POS 0x7FFF #define NAN_DL16_NEG 0xFFFF #define STICK_ENTRIES_FP32 9 uint32_t stick_entries_to_try[STICK_ENTRIES_FP32] = {0, 1, 3, 4, 7, 8, 9, 15, 63}; zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; unsigned char *data; uint16_t *array; zdnn_status status; unsigned char *unstickified_data; // Build a transformed ztensor with valid data zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP32, &pre_tfrmd_desc, 1, 1, 1, 64); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); data = create_and_fill_random_fp_data(&ztensor); // Transform the data to an stickified ztensor, so we can test // unstickification later status = zdnn_transform_ztensor(&ztensor, data); TEST_ASSERT_MESSAGE_FORMATTED(status == ZDNN_OK, "zdnn_transform_ztensor failed (status = %08x)", status); // Create an area to unstickify/convert back to uint64_t num_elements = get_num_elements(&ztensor, ELEMENTS_PRE); zdnn_data_types dtype = ztensor.pre_transformed_desc->type; unstickified_data = malloc(num_elements * get_data_type_size(dtype)); array = (uint16_t *)ztensor.buffer; /* use stickified_data as an array */ for (int i = 0; i < STICK_ENTRIES_FP32; i++) { array[stick_entries_to_try[i]] = bad_value; status = zdnn_transform_origtensor(&ztensor, unstickified_data); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_CONVERT_FAILURE, "zdnn_transform_origtensor() succeeded (status = %08x, expects = " "%08x, i = %d, value = %04x)", status, ZDNN_CONVERT_FAILURE, i, bad_value); array[stick_entries_to_try[i]] = 0; // set entry to 0 for next iteration } // Free allocated storage free(data); free(unstickified_data); zdnn_free_ztensor_buffer(&ztensor); } // Test unstickify conversions DLFloat to FP32 (VCLFNx void test_ztensor_fp32_bad_values() { #ifdef ZDNN_CONFIG_NO_NNPA TEST_IGNORE_MESSAGE("needs NNPA to trigger overflow"); #endif // too large or too small not possible, test_ztensor_bad_value_FP32( NAN_DL16_POS); // is not a number, will cause overflow test_ztensor_bad_value_FP32( NAN_DL16_NEG); // is not a number, will cause overflow } // Test unstickify invalid transform type void test_unstickify_transform_desc_invalid_type() { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; zdnn_status status; unsigned char *unstickified_data; // Create descriptors and ztensor // For test, pre_transformed desc must be valid. All other transformed desc // options must be valid. Type will be changed. zdnn_init_pre_transformed_desc(ZDNN_NHWC, FP32, &pre_tfrmd_desc, 1, 1, 1, 64); zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor_with_malloc(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); // Allocate storage for unstickified data. Although not required for test, if // expected status doesn't occur, this space may be touched and would require // to be allocated or it may blow up. uint64_t num_elements = get_num_elements(&ztensor, ELEMENTS_PRE); unstickified_data = malloc(num_elements * get_data_type_size(ztensor.transformed_desc->type)); // Set is_transformed to true as this check occurs prior to type check ztensor.is_transformed = true; // Update type to an invalid type. ztensor.transformed_desc->type = test_datatype; status = zdnn_transform_origtensor(&ztensor, unstickified_data); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_INVALID_TYPE, "zdnn_transform_origtensor() unexpected status (status = %08x, " "expects = %08x)", status, ZDNN_INVALID_TYPE); free(unstickified_data); zdnn_free_ztensor_buffer(&ztensor); } int main(void) { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(test_nhwc_1x4x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x4x4x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x32x32x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x32x32x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x32x32x3); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x2x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x2x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x2x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x2x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x4x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x7x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x7x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x7x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x7x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x8x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x8x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x8x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x8x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x13x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x13x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x13x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x13x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x100x1); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x100x2); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x100x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x100x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x2x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x2x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x2x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x2x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x4x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x4x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x4x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x7x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x7x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x7x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x7x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x8x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x8x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x8x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x8x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x13x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x13x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x13x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x13x7); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x100x1); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x100x2); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x100x4); RUN_TEST_ALL_DATATYPES(test_nhwc_2x3x100x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x2x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x2x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x2x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x2x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x4x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x4x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x4x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x4x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x7x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x7x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x7x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x7x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x8x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x8x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x8x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x8x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x13x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x13x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x13x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x13x7); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x100x1); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x100x2); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x100x4); RUN_TEST_ALL_DATATYPES(test_nhwc_3x2x100x7); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x4); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x5); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x8); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x9); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x63); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x64); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x65); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x127); RUN_TEST_ALL_DATATYPES(test_nhwc_1x1x1x128); RUN_TEST_ALL_DATATYPES(test_3ds_4x4x1); RUN_TEST_ALL_DATATYPES(test_3ds_32x32x3); RUN_TEST_ALL_DATATYPES(test_2ds_4x2); RUN_TEST_ALL_DATATYPES(test_2ds_2x2049); RUN_TEST_ALL_DATATYPES(test_nchw_1x1x4x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x2x3); RUN_TEST_ALL_DATATYPES(test_nchw_1x3x32x32); RUN_TEST_ALL_DATATYPES(test_nchw_2x129x3x33); RUN_TEST_ALL_DATATYPES(test_nchw_1x63x1x32); RUN_TEST_ALL_DATATYPES(test_nchw_1x64x1x31); RUN_TEST_ALL_DATATYPES(test_nchw_1x64x1x32); RUN_TEST_ALL_DATATYPES(test_nchw_1x64x1x33); RUN_TEST_ALL_DATATYPES(test_nchw_1x65x1x32); RUN_TEST_ALL_DATATYPES(test_nchw_1x127x1x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x128x1x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x129x1x4); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x1x63); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x1x64); RUN_TEST_ALL_DATATYPES(test_nchw_1x4x1x65); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x1x4x3); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x1x4x3); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x1x4x64); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x1x4x64); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x1x4x65); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x1x4x65); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x1x31x5); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x1x31x5); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x1x60x5); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x1x60x5); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x2x4x3); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x2x4x3); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x2x4x64); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x2x4x64); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x2x4x65); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x2x4x65); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x2x31x5); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x2x31x5); RUN_TEST_ALL_DATATYPES(test_rnn_output_5x2x60x5); RUN_TEST_ALL_DATATYPES(test_rnn_output_1x2x60x5); RUN_TEST_ALL_DATATYPES(test_stickify_unstickify_nhwc_1x4x4x1); RUN_TEST_ALL_DATATYPES(test_stickify_unstickify_nhwc_1x4x4x2); RUN_TEST_ALL_DATATYPES(test_stickify_unstickify_nhwc_1x32x32x1); RUN_TEST_ALL_DATATYPES(test_stickify_unstickify_nhwc_1x32x32x2); RUN_TEST_ALL_DATATYPES(test_stickify_unstickify_nhwc_1x32x32x3); RUN_TEST_ALL_DATATYPES(test_stickify_unstickify_nhwc_1x2x33x65); RUN_TEST_ALL_DATATYPES(test_stickify_unstickify_nchw_1x4x4x1); RUN_TEST_ALL_DATATYPES(test_stickify_unstickify_nchw_1x32x32x3); RUN_TEST_ALL_DATATYPES(test_stickify_unstickify_nchw_1x2x33x65); RUN_TEST_ALL_DATATYPES(test_unstickify_4dfeature_twice); RUN_TEST_ALL_DATATYPES(test_unstickify_transform_desc_invalid_type); RUN_TEST(test_ztensor_fp16_bad_values); RUN_TEST(test_ztensor_fp32_bad_values); return UNITY_END(); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_utils.c�����������������������������������������������������������������0000664�0000000�0000000�00000023364�14364043643�0017222�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> void setUp(void) {} void tearDown(void) {} void test_num_elements(zdnn_data_layouts layout, uint32_t *shape, uint64_t exp_pre, uint64_t exp_aiu) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; switch (layout) { case ZDNN_1D: zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, shape[0]); break; case ZDNN_2D: case ZDNN_2DS: zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, shape[0], shape[1]); break; case ZDNN_3D: case ZDNN_3DS: zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, shape[0], shape[1], shape[2]); break; default: zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, shape[0], shape[1], shape[2], shape[3]); break; } zdnn_generate_transformed_desc(&pre_tfrmd_desc, &tfrmd_desc); zdnn_init_ztensor(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); // Get output from each mode uint64_t num_elements_pre = get_num_elements(&ztensor, ELEMENTS_PRE); uint64_t num_elements_aiu = get_num_elements(&ztensor, ELEMENTS_AIU); // Check each mode's output matches the expected value. TEST_ASSERT_MESSAGE_FORMATTED( exp_pre == num_elements_pre, "For %s tensor we expected %" PRIu64 " elements but ELEMENTS_PRE returned %" PRIu64 " elements", get_data_layout_str(tfrmd_desc.layout), exp_pre, num_elements_pre); TEST_ASSERT_MESSAGE_FORMATTED( exp_aiu == num_elements_aiu, "For %s tensor we expected %" PRIu64 " elements but ELEMENTS_AIU returned %" PRIu64 " elements", get_data_layout_str(tfrmd_desc.layout), exp_aiu, num_elements_aiu); } void test_num_elements_concat(zdnn_data_layouts layout, zdnn_concat_info info, uint32_t *shape, uint64_t exp_single_gate, uint64_t exp_all_gates, uint64_t exp_aiu) { zdnn_tensor_desc pre_tfrmd_desc, tfrmd_desc; zdnn_ztensor ztensor; // SIM alters AIU_2BYTE_CELLS_PER_STICK which affects the padded dim1 set // by zdnn_generate_transformed_desc_concatenated(). That changes the // expected number of all elements (which includes padding), so skip if SIM #ifdef ZDNN_CONFIG_SIMULATION TEST_PASS(); #endif switch (layout) { case ZDNN_2DS: zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, shape[0], shape[1]); break; case ZDNN_3DS: zdnn_init_pre_transformed_desc(layout, test_datatype, &pre_tfrmd_desc, shape[0], shape[1], shape[2]); break; default: TEST_FAIL_MESSAGE_FORMATTED("invalid pre-transformed layout: %s", get_data_layout_str(layout)); } zdnn_generate_transformed_desc_concatenated(&pre_tfrmd_desc, info, &tfrmd_desc); zdnn_init_ztensor(&pre_tfrmd_desc, &tfrmd_desc, &ztensor); // Get output from each mode uint64_t num_elements_single_gate = get_num_elements(&ztensor, ELEMENTS_PRE_SINGLE_GATE); uint64_t num_elements_all_gates = get_num_elements(&ztensor, ELEMENTS_PRE_ALL_GATES); uint64_t num_elements_aiu = get_num_elements(&ztensor, ELEMENTS_AIU); // Check each mode's output matches the expected value. TEST_ASSERT_MESSAGE_FORMATTED( num_elements_single_gate == exp_single_gate, "For %s tensor we expected %" PRIu64 " elements but ELEMENTS_PRE_SINGLE_GATE returned %" PRIu64 " elements (info = %08x)", get_data_layout_str(tfrmd_desc.layout), exp_single_gate, num_elements_single_gate, info); TEST_ASSERT_MESSAGE_FORMATTED( "For %s tensor we expected %" PRIu64 " elements but ELEMENTS_PRE_ALL_GATES returned %" PRIu64 " elements (info = %08x)", get_data_layout_str(tfrmd_desc.layout), exp_all_gates, num_elements_all_gates, info); TEST_ASSERT_MESSAGE_FORMATTED( "For %s tensor we expected %" PRIu64 " elements but ELEMENTS_AIU returned %" PRIu64 " elements (info = %08x)", get_data_layout_str(tfrmd_desc.layout), exp_aiu, num_elements_aiu, info); } /* * Test to ensure get_num_elements works with a NHWC tensor. */ void get_num_elements_nhwc() { uint32_t shape[] = {1, 4, 4, 1}; test_num_elements(ZDNN_NHWC, shape, 16, 16); } /* * Test to ensure get_num_elements works with a 4D tensor. */ void get_num_elements_4d() { uint32_t shape[] = {1, 32, 15, 5}; test_num_elements(ZDNN_4D, shape, 2400, 2400); } /* * Test to ensure get_num_elements works with a 3DS tensor. */ void get_num_elements_3ds() { uint32_t shape[] = {3, 4, 4}; test_num_elements(ZDNN_3DS, shape, 48, 48); } /* * Test to ensure get_num_elements works with a 3D tensor. */ void get_num_elements_3d() { uint32_t shape[] = {15, 4, 2}; test_num_elements(ZDNN_3D, shape, 120, 120); } /* * Test to ensure get_num_elements works with a 2DS tensor. */ void get_num_elements_2ds() { uint32_t shape[] = {4, 4}; test_num_elements(ZDNN_2DS, shape, 16, 16); } /* * Test to ensure get_num_elements works with a 2D tensor. */ void get_num_elements_2d() { uint32_t shape[] = {15, 4}; test_num_elements(ZDNN_2D, shape, 60, 60); } /* * Test to ensure get_num_elements works with a 1D tensor. */ void get_num_elements_1d() { uint32_t shape[] = {16}; test_num_elements(ZDNN_1D, shape, 16, 16); } /* * Test to ensure get_num_elements works with a 3DS LSTM tensor that doesn't * require vertical concatenation. */ void get_num_elements_lstm_no_vconcat_weights() { uint32_t shape[] = {2, 3, 4}; for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_num_elements_concat(ZDNN_3DS, RNN_TYPE_LSTM | no_vconcat_infos[i], shape, 24, 96, 1536); } } /* * Test to ensure get_num_elements works with a 3DS LSTM tensor that requires * vertical concatenation. */ void get_num_elements_lstm_prev_bidir_weights() { uint32_t shape[] = {2, 6, 4}; test_num_elements_concat(ZDNN_3DS, RNN_TYPE_LSTM | PREV_LAYER_BIDIR | USAGE_WEIGHTS, shape, 48, 192, 65536); } /* * Test to ensure get_num_elements works with a (hidden-)biases 2DS LSTM * tensor. */ void get_num_elements_lstm_biases() { uint32_t shape[] = {2, 3}; for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_num_elements_concat( ZDNN_2DS, RNN_TYPE_LSTM | prev_layers[i] | biases_usages[j], shape, 6, 24, 512); } } } /* * Test to ensure get_num_elements works with a 3DS GRU tensor that doesn't * require vertical concatenation. */ void get_num_elements_gru_no_vconcat_weights() { uint32_t shape[] = {2, 3, 4}; for (int i = 0; i < NUM_NO_VCONCAT_INFOS; i++) { test_num_elements_concat(ZDNN_3DS, RNN_TYPE_GRU | no_vconcat_infos[i], shape, 24, 72, 1152); } } /* * Test to ensure get_num_elements works with a 3DS GRU tensor that requires * vertical concatenation. */ void get_num_elements_gru_prev_bidir_weights() { uint32_t shape[] = {2, 6, 4}; test_num_elements_concat(ZDNN_3DS, RNN_TYPE_GRU | PREV_LAYER_BIDIR | USAGE_WEIGHTS, shape, 48, 144, 49152); } /* * Test to ensure get_num_elements works with a (hidden-)biases 2DS GRU * tensor. */ void get_num_elements_gru_biases() { uint32_t shape[] = {2, 3}; for (int i = 0; i < NUM_PREV_LAYERS; i++) { for (int j = 0; j < NUM_BIASES_USAGES; j++) { test_num_elements_concat(ZDNN_2DS, RNN_TYPE_GRU | prev_layers[i] | biases_usages[j], shape, 6, 18, 384); } } } /* * Test to ensure get_num_elements works with an RNN uni output tensor, which * the ELEMENTS_AIU result will not have any padding */ void get_num_elements_uni_output() { uint32_t shape[] = {2, 1, 3, 4}; test_num_elements(ZDNN_4DS, shape, 24, 24); } /* * Test to ensure get_num_elements works with an RNN bidir output tensor, which * the ELEMENTS_AIU result WILL have paddings */ void get_num_elements_bidir_output() { uint32_t shape[] = {2, 2, 3, 4}; test_num_elements(ZDNN_4DS, shape, 48, 768); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(get_num_elements_nhwc); RUN_TEST_ALL_DATATYPES(get_num_elements_4d); RUN_TEST_ALL_DATATYPES(get_num_elements_3ds); RUN_TEST_ALL_DATATYPES(get_num_elements_3d); RUN_TEST_ALL_DATATYPES(get_num_elements_2ds); RUN_TEST_ALL_DATATYPES(get_num_elements_2d); RUN_TEST_ALL_DATATYPES(get_num_elements_1d); RUN_TEST_ALL_DATATYPES(get_num_elements_lstm_no_vconcat_weights); RUN_TEST_ALL_DATATYPES(get_num_elements_lstm_prev_bidir_weights); RUN_TEST_ALL_DATATYPES(get_num_elements_lstm_biases); RUN_TEST_ALL_DATATYPES(get_num_elements_gru_no_vconcat_weights); RUN_TEST_ALL_DATATYPES(get_num_elements_gru_prev_bidir_weights); RUN_TEST_ALL_DATATYPES(get_num_elements_gru_biases); RUN_TEST_ALL_DATATYPES(get_num_elements_uni_output); RUN_TEST_ALL_DATATYPES(get_num_elements_bidir_output); return UNITY_END(); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_version.c���������������������������������������������������������������0000664�0000000�0000000�00000020711�14364043643�0017540�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include "version.h" #include <string.h> #define MAJOR_NEWER(x) (x + 0x00020000) #define MAJOR_OLDER(x) (x - 0x00020000) #define MINOR_NEWER(x) (x + 0x00000200) #define MINOR_OLDER(x) (x - 0x00000200) #define PATCH_NEWER(x) (x + 0x00000002) #define PATCH_OLDER(x) (x - 0x00000002) void setUp(void) { /* This is run before EACH TEST */ aiu_lib_vernum = AIU_UNKNOWN; } void tearDown(void) {} // *************************************************** // Under VERSION_C_TEST library version is always: 5.5.5 // *************************************************** void test_version_runnable(uint32_t app_vernum, uint32_t new_aiu_lib_vernum, bool exp_result) { aiu_lib_vernum = new_aiu_lib_vernum; TEST_ASSERT_MESSAGE_FORMATTED( zdnn_is_version_runnable(app_vernum) == exp_result, "zdnn_is_version_runnable() did not return %d", exp_result); } // ************************ // *** MAJOR ver tests // ************************ // --------------------------------------------------------- // | app | hw | library | runnable? // --------------------------------------------------------- // | 5.5.5 | 7.x.x | 5.5.5 | no // | 7.x.x | 5.5.5 | 5.5.5 | no // | 7.x.x | 7.x.x | 5.5.5 | no // | 5.3.x | 5.5.x | 5.5.5 | yes // --------------------------------------------------------- void hw_major_newer_fail() { test_version_runnable(ZDNN_VERNUM, MAJOR_NEWER(ZDNN_VERNUM), false); } void app_major_newer_fail() { test_version_runnable(MAJOR_NEWER(ZDNN_VERNUM), ZDNN_VERNUM, false); } void lib_major_older_fail() { test_version_runnable(MAJOR_NEWER(ZDNN_VERNUM), MAJOR_NEWER(ZDNN_VERNUM), false); } void major_all_match_pass() { test_version_runnable(MINOR_OLDER(ZDNN_VERNUM), ZDNN_VERNUM, true); } // ************************ // *** MINOR ver tests // ************************ // --------------------------------------------------------- // | app | hw | library | runnable? // --------------------------------------------------------- // | 5.7.5 | 5.5.5 | 5.5.5 | no // | 5.3.5 | 5.5.5 | 5.5.5 | yes // | 5.5.5 | 5.7.5 | 5.5.5 | yes // | 5.5.5 | 5.3.5 | 5.5.5 | no // | 5.3.5 | 5.3.5 | 5.5.5 | yes // | 5.7.5 | 5.7.5 | 5.5.5 | no // --------------------------------------------------------- // | 5.3.5 | 5.7.5 | 5.5.5 | yes // | 5.1.5 | 5.3.5 | 5.5.5 | yes // | 5.3.5 | 5.1.5 | 5.5.5 | no // --------------------------------------------------------- void app_minor_newer_fail() { test_version_runnable(MINOR_NEWER(ZDNN_VERNUM), ZDNN_VERNUM, false); } void app_minor_older_pass() { test_version_runnable(MINOR_OLDER(ZDNN_VERNUM), ZDNN_VERNUM, true); } void hw_minor_newer_pass() { test_version_runnable(ZDNN_VERNUM, MINOR_NEWER(ZDNN_VERNUM), true); } void hw_minor_older_fail() { test_version_runnable(ZDNN_VERNUM, MINOR_OLDER(ZDNN_VERNUM), false); } void lib_minor_newer_pass() { test_version_runnable(MINOR_OLDER(ZDNN_VERNUM), MINOR_OLDER(ZDNN_VERNUM), true); } void lib_minor_older_fail() { test_version_runnable(MINOR_NEWER(ZDNN_VERNUM), MINOR_NEWER(ZDNN_VERNUM), false); } void app_minor_older_hw_minor_newer_pass() { test_version_runnable(MINOR_OLDER(ZDNN_VERNUM), MINOR_NEWER(ZDNN_VERNUM), true); } void app_minor_older_hw_minor_even_older_pass() { test_version_runnable(MINOR_OLDER(ZDNN_VERNUM), MINOR_OLDER(MINOR_OLDER(ZDNN_VERNUM)), false); } // ************************ // *** Mixed MAJOR/MINOR ver tests // ************************ // all of these are the runnable = yes cases in MINOR ver tests but now with // different MAJOR ver, so they all become runnable = no // --------------------------------------------------------- // | app | hw | library | runnable? // --------------------------------------------------------- // | 7.3.5 | 5.5.5 | 5.5.5 | no // | 5.5.5 | 7.7.5 | 5.5.5 | no // | 3.3.5 | 7.3.5 | 5.5.5 | no // | 7.3.5 | 3.7.5 | 5.5.5 | no // | 5.1.5 | 3.3.5 | 5.5.5 | no // --------------------------------------------------------- void mixed_app_major_newer_fail() { test_version_runnable(MAJOR_NEWER(MINOR_OLDER(ZDNN_VERNUM)), ZDNN_VERNUM, false); } void mixed_hw_major_newer_fail() { test_version_runnable(ZDNN_VERNUM, MAJOR_NEWER(MINOR_NEWER(ZDNN_VERNUM)), false); } void mixed_app_major_older_hw_major_newer_fail() { test_version_runnable(MAJOR_OLDER(MINOR_OLDER(ZDNN_VERNUM)), MAJOR_NEWER(MINOR_OLDER(ZDNN_VERNUM)), false); } void mixed_app_major_newer_hw_major_older_fail() { test_version_runnable(MAJOR_NEWER(MINOR_OLDER(ZDNN_VERNUM)), MAJOR_OLDER(MINOR_NEWER(ZDNN_VERNUM)), false); } void mixed_hw_major_older_fail() { test_version_runnable(MINOR_OLDER(MINOR_OLDER(ZDNN_VERNUM)), MAJOR_OLDER(MINOR_OLDER(ZDNN_VERNUM)), false); } // ************************ // *** PATCH ver tests // ************************ // Everything passes void app_patch_newer_pass() { test_version_runnable(PATCH_NEWER(ZDNN_VERNUM), ZDNN_VERNUM, true); } void app_patch_older_pass() { test_version_runnable(PATCH_OLDER(ZDNN_VERNUM), ZDNN_VERNUM, true); } void hw_patch_newer_pass() { test_version_runnable(ZDNN_VERNUM, PATCH_NEWER(ZDNN_VERNUM), true); } void hw_patch_older_pass() { test_version_runnable(ZDNN_VERNUM, PATCH_OLDER(ZDNN_VERNUM), true); } void lib_patch_newer_pass() { test_version_runnable(PATCH_OLDER(ZDNN_VERNUM), PATCH_OLDER(ZDNN_VERNUM), true); } void lib_patch_older_pass() { test_version_runnable(PATCH_NEWER(ZDNN_VERNUM), PATCH_NEWER(ZDNN_VERNUM), true); } // ************************ // *** get_max_runnable tests // ************************ void test_get_max_runnable(uint32_t exp_vernum) { uint32_t vernum = zdnn_get_max_runnable_version(); TEST_ASSERT_MESSAGE_FORMATTED( vernum == exp_vernum, "zdnn_get_max_runnable_version() did not return %08x (found: %08x)", exp_vernum, vernum); } void test_max_ver_hw_major_newer() { aiu_lib_vernum = MAJOR_NEWER(ZDNN_VERNUM); test_get_max_runnable(AIU_UNKNOWN); } void test_max_ver_hw_major_older() { aiu_lib_vernum = MAJOR_OLDER(ZDNN_VERNUM); test_get_max_runnable(AIU_UNKNOWN); } void test_max_ver_hw_minor_newer() { aiu_lib_vernum = MINOR_NEWER(ZDNN_VERNUM); test_get_max_runnable(ZDNN_VERNUM | 0xFF); } void test_max_ver_hw_minor_older() { aiu_lib_vernum = MINOR_OLDER(ZDNN_VERNUM); test_get_max_runnable(MINOR_OLDER(ZDNN_VERNUM) | 0xFF); } void test_max_ver_hw_patch_newer() { aiu_lib_vernum = PATCH_OLDER(ZDNN_VERNUM); test_get_max_runnable(ZDNN_VERNUM | 0xFF); } int main(void) { UNITY_BEGIN(); #ifdef VERSION_C_TEST RUN_TEST(hw_major_newer_fail); RUN_TEST(app_major_newer_fail); RUN_TEST(lib_major_older_fail); RUN_TEST(major_all_match_pass); RUN_TEST(app_minor_newer_fail); RUN_TEST(app_minor_older_pass); RUN_TEST(hw_minor_newer_pass); RUN_TEST(hw_minor_older_fail); RUN_TEST(lib_minor_newer_pass); RUN_TEST(lib_minor_older_fail); RUN_TEST(app_minor_older_hw_minor_newer_pass); RUN_TEST(app_minor_older_hw_minor_even_older_pass); RUN_TEST(mixed_app_major_newer_fail); RUN_TEST(mixed_hw_major_newer_fail); RUN_TEST(mixed_app_major_older_hw_major_newer_fail); RUN_TEST(mixed_app_major_newer_hw_major_older_fail); RUN_TEST(mixed_hw_major_older_fail); RUN_TEST(app_patch_newer_pass); RUN_TEST(app_patch_older_pass); RUN_TEST(hw_patch_newer_pass); RUN_TEST(hw_patch_older_pass); RUN_TEST(lib_patch_newer_pass); RUN_TEST(lib_patch_older_pass); RUN_TEST(test_max_ver_hw_major_newer); RUN_TEST(test_max_ver_hw_major_older); RUN_TEST(test_max_ver_hw_minor_newer); RUN_TEST(test_max_ver_hw_minor_older); RUN_TEST(test_max_ver_hw_patch_newer); #endif return UNITY_END(); } �������������������������������������������������������zDNN-1.0.1/tests/testDriver_version_detect.c��������������������������������������������������������0000664�0000000�0000000�00000017451�14364043643�0021077�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include "version.h" #include <string.h> // magic-numbering these to check against what's in version.h #define LIB_VERNUM_Z16 0x00010000 #define LIB_VERNUM_NEWER_MAJOR LIB_VERNUM(7, 5, 5) #define LIB_VERNUM_NEWER_MINOR LIB_VERNUM(5, 7, 5) #define LIB_VERNUM_BASELINE LIB_VERNUM(5, 5, 5) #define LIB_VERNUM_OLDER_MINOR LIB_VERNUM(5, 3, 5) #define LIB_VERNUM_OLDER_MAJOR LIB_VERNUM(3, 5, 5) // newer major: newer minor + mdis bump aiu_hwinfo aiu_hwinfo_newer_major = { {0x00, 0x11, 0x11, 0x11}, {0x00, 0x01}, 7, 5, {0x00, 0x11}, "newer major", LIB_VERNUM_NEWER_MAJOR}; // newer minor: baseline + blk1 2nd byte bit bump + blk2 2nd byte bit bump aiu_hwinfo aiu_hwinfo_newer_minor = { {0x00, 0x11, 0x11, 0x11}, {0x00, 0x01}, 5, 5, {0x00, 0x11}, "newer minor", LIB_VERNUM_NEWER_MINOR}; aiu_hwinfo aiu_hwinfo_baseline = { {0x00, 0x01, 0x11, 0x11}, {0x00, 0x00}, 5, 5, {0x00, 0x11}, "baseline", LIB_VERNUM_BASELINE}; // older minor: baseline - blk3 2nd byte bit nerf aiu_hwinfo aiu_hwinfo_older_minor = { {0x00, 0x01, 0x11, 0x11}, {0x00, 0x00}, 5, 5, {0x00, 0x10}, "older minor", LIB_VERNUM_OLDER_MINOR}; // older major: older minor - blk1 3rd byte bit nerf - mts nerf aiu_hwinfo aiu_hwinfo_older_major = { {0x00, 0x01, 0x10, 0x11}, {0x00, 0x00}, 5, 3, {0x00, 0x10}, "older major", LIB_VERNUM_OLDER_MAJOR}; void reset_qaf_result() { // QAF now has the information of the baseline machine memset(&nnpa_query_result, 0, sizeof(nnpa_qaf_parameter_block)); memcpy(QAF_BLK1_PTR, &aiu_hwinfo_baseline.blk1, HWINFO_BLK1_LEN); memcpy(QAF_BLK2_PTR, &aiu_hwinfo_baseline.blk2, HWINFO_BLK2_LEN); QAF_VAL1 = aiu_hwinfo_baseline.val1; QAF_VAL2 = aiu_hwinfo_baseline.val2; memcpy(QAF_BLK3_PTR, &aiu_hwinfo_baseline.blk3, HWINFO_BLK3_LEN); } void setUp(void) { /* This is run before EACH TEST */ } void tearDown(void) {} // ************************ // *** LIB_VERNUM tests // ************************ void test_lib_vernum_nnpa() { VERIFY_HW_ENV; // verify required HW env is available. refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE(aiu_lib_vernum == 0x00010000, // "aiu_lib_vernum is not detected as 0x00010000 (nnpa)"); } // ************************************************** // *** LIB_VERNUM detection tests - Fake machines // ************************************************** void test_baseline_exact() { reset_qaf_result(); refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == LIB_VERNUM_BASELINE, "aiu_lib_vernum is not detected as %08x (found: %08x)", LIB_VERNUM_BASELINE, aiu_lib_vernum); } void test_newer_minor_exact() { reset_qaf_result(); *((char *)QAF_BLK1_PTR + 1) = 0x11; *((char *)QAF_BLK2_PTR + 1) = 0x01; refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == LIB_VERNUM_NEWER_MINOR, "aiu_lib_vernum is not detected as %08x (found: %08x)", LIB_VERNUM_NEWER_MINOR, aiu_lib_vernum); } void test_newer_major_exact() { reset_qaf_result(); *((char *)QAF_BLK1_PTR + 1) = 0x11; *((char *)QAF_BLK2_PTR + 1) = 0x01; QAF_VAL1 = 7; refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == LIB_VERNUM_NEWER_MAJOR, "aiu_lib_vernum is not detected as %08x (found: %08x)", LIB_VERNUM_NEWER_MAJOR, aiu_lib_vernum); } void test_older_minor_exact() { reset_qaf_result(); *((char *)QAF_BLK3_PTR + 1) = 0x10; refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == LIB_VERNUM_OLDER_MINOR, "aiu_lib_vernum is not detected as %08x (found: %08x)", LIB_VERNUM_OLDER_MINOR, aiu_lib_vernum); } void test_older_major_exact() { reset_qaf_result(); *((char *)QAF_BLK1_PTR + 2) = 0x10; *((char *)QAF_BLK3_PTR + 1) = 0x10; QAF_VAL2 = 3; refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == LIB_VERNUM_OLDER_MAJOR, "aiu_lib_vernum is not detected as %08x (found: %08x)", LIB_VERNUM_OLDER_MAJOR, aiu_lib_vernum); } void test_exceeds_newer_minor_but_not_newer_major() { // turn on all bits, leave val1 and val2 at 5 and 5 memset(&nnpa_query_result, 0xff, sizeof(nnpa_qaf_parameter_block)); QAF_VAL1 = 5; QAF_VAL2 = 5; refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == LIB_VERNUM_NEWER_MINOR, "aiu_lib_vernum is not detected as %08x (found: %08x)", LIB_VERNUM_NEWER_MINOR, aiu_lib_vernum); } void test_older_minor_enough_but_not_baseline() { reset_qaf_result(); *((char *)QAF_BLK1_PTR) = 0xFF; // better blk1 than baseline *((char *)QAF_BLK3_PTR + 1) = 0x10; // worse blk3 than baseline refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == LIB_VERNUM_OLDER_MINOR, "aiu_lib_vernum is not detected as %08x (found: %08x)", LIB_VERNUM_OLDER_MINOR, aiu_lib_vernum); } void test_all_flags_on_but_older_vals() { // turn on all bits, set val1 and val2 at 3 and 3 so they are worse than older // major memset(&nnpa_query_result, 0xff, sizeof(nnpa_qaf_parameter_block)); QAF_VAL1 = 3; QAF_VAL2 = 3; refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == AIU_UNKNOWN, "aiu_lib_vernum is not detected as %08x (found: %08x)", AIU_UNKNOWN, aiu_lib_vernum); } void test_super_mythical() { // turn on all bits, set val1 and val2 at 100, 100 so it exceeds newer major memset(&nnpa_query_result, 0xff, sizeof(nnpa_qaf_parameter_block)); QAF_VAL1 = 100; QAF_VAL2 = 100; refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == LIB_VERNUM_NEWER_MAJOR, "aiu_lib_vernum is not detected as %08x (found: %08x)", LIB_VERNUM_NEWER_MAJOR, aiu_lib_vernum); } void test_super_old1() { // even fewer bits on than older major memset(&nnpa_query_result, 0x00, sizeof(nnpa_qaf_parameter_block)); *((char *)QAF_BLK3_PTR + 1) = 18; QAF_VAL1 = aiu_hwinfo_baseline.val1; QAF_VAL2 = aiu_hwinfo_baseline.val2; refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == AIU_UNKNOWN, "aiu_lib_vernum is not detected as %08x (found: %08x)", AIU_UNKNOWN, aiu_lib_vernum); } void test_super_old2() { // even lower val1 than older major reset_qaf_result(); QAF_VAL1 = 2; refresh_aiu_lib_vernum(); TEST_ASSERT_MESSAGE_FORMATTED( aiu_lib_vernum == AIU_UNKNOWN, "aiu_lib_vernum is not detected as %08x (found: %08x)", AIU_UNKNOWN, aiu_lib_vernum); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_lib_vernum_nnpa); // only tests with fake machines this point forward aiu_hwinfo_list[0] = &aiu_hwinfo_newer_major; aiu_hwinfo_list[1] = &aiu_hwinfo_newer_minor; aiu_hwinfo_list[2] = &aiu_hwinfo_baseline; aiu_hwinfo_list[3] = &aiu_hwinfo_older_minor; aiu_hwinfo_list[4] = &aiu_hwinfo_older_major; RUN_TEST(test_baseline_exact); RUN_TEST(test_newer_minor_exact); RUN_TEST(test_newer_major_exact); RUN_TEST(test_older_minor_exact); RUN_TEST(test_older_major_exact); RUN_TEST(test_exceeds_newer_minor_but_not_newer_major); RUN_TEST(test_older_minor_enough_but_not_baseline); RUN_TEST(test_all_flags_on_but_older_vals); RUN_TEST(test_super_mythical); RUN_TEST(test_super_old1); RUN_TEST(test_super_old2); return UNITY_END(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_add_elwise.c�������������������������������������������������������0000664�0000000�0000000�00000014720�14364043643�0021207�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_elwise.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} /* * Simple test to drive a full add api. */ void api_add_basic() { // Input and outputs expect the same shape so just define it once uint32_t shape[] = {1, 2, 2, 2}; /* Input 1 values as NHWC [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ float input1_values[] = {1, 10, 2, 20, 4, 40, 5, 50}; /* Input 2 values as NHWC [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ float input2_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Expected values as NHWC (test method will generate this array) [[ [[4, 40], [8, 80]], [[12, 120], [14, 140]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_ADD, ZDNN_OK); } // test to drive input tensors with 320 values in their buffer void api_add_med_dims() { // Input and outputs expect the same shape so just define it once uint32_t shape[] = {1, 8, 10, 4}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_ADD, ZDNN_OK); } // test to drive input tensors with 6825 values in their buffer void api_add_high_dims() { // Input and outputs expect the same shape so just define it once uint32_t shape[] = {1, 3, 33, 65}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_ADD, ZDNN_OK); } /* * Simple test to drive a full add api using the data type * and 3 dimensional tensors */ void api_add_3D() { // Input and outputs expect the same shape so just define it once uint32_t shape[] = {2, 2, 2}; /* Input 1 values as NHWC [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ float input1_values[] = {1, 10, 2, 20, 4, 40, 5, 50}; /* Input 2 values as NHWC [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ float input2_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Expected values as NHWC (test method will generate this array) [[ [[4, 40], [8, 80]], [[12, 120], [14, 140]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_3D, input1_values, input2_values, NNPA_ADD, ZDNN_OK); } /* * Simple test to drive a full add api using the data type * and 2 dimensional tensors */ void api_add_2D() { // Input and outputs expect the same shape so just define it once uint32_t shape[] = {2, 2}; /* Input 1 values as NHWC [[ [[1, 10], [2, 20]] ]] */ float input1_values[] = {1, 10, 2, 20}; /* Input 2 values as NHWC [[ [[3, 30], [6, 60]] ]] */ float input2_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Expected values as NHWC (test method will generate this array) [[ [[4, 40], [8, 80]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_2D, input1_values, input2_values, NNPA_ADD, ZDNN_OK); } /* * Simple test to drive a full add api using the data type * and 1 dimensional tensors */ void api_add_1D() { // Input and outputs expect the same shape so just define it once uint32_t shape[] = {2}; /* Input 1 values as NHWC [[ [[10000, 12000]] ]] */ float input1_values[] = {10000, 12000}; /* Input 2 values as NHWC [[ [[860, 1400]] ]] */ float input2_values[] = {860, 1400}; /* Expected values as NHWC (test method will generate this array) [[ [[10860, 13400]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_1D, input1_values, input2_values, NNPA_ADD, ZDNN_OK); } /* * Simple test to drive a full add api that hits an overflow. */ void api_add_overflow() { // Input and outputs expect the same shape so just define it once uint32_t shape[] = {1, 2, 2, 2}; /* Input 1 values as NHWC [[ [[1, 10], [MAX_DLF16 * 0.75, 20]], [[4, 40], [5, 50]] ]] */ float input1_values[] = {1, 10, MAX_DLF16 * 0.75, 20, 4, 40, 5, 50}; /* Input 2 values as NHWC [[ [[3, 30], [MAX_DLF16 * 0.75, 60]], [[8, 80], [9, 90]] ]] */ float input2_values[] = {3, 30, MAX_DLF16 * 0.75 + 1.0, 60, 8, 80, 9, 90}; /* Expected values as NHWC (test method will generate this array) [[ [[4, 40], [OVERFLOW, 80]], [[12, 120], [14, 140]] ]] */ // when overflow/underflow happens, AIU sets range violation flag test_elwise_api_2_inputs_adv(shape, ZDNN_NHWC, FP32, input1_values, input2_values, NNPA_ADD, ZDNN_ELEMENT_RANGE_VIOLATION); test_elwise_api_2_inputs_adv(shape, ZDNN_NHWC, BFLOAT, input1_values, input2_values, NNPA_ADD, ZDNN_ELEMENT_RANGE_VIOLATION); // Note: We can't create an add/sub overflow/underflow with values that // originate as FP16s, since FP16's max is way below the DLFloat max. } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(api_add_basic); RUN_TEST_ALL_DATATYPES(api_add_med_dims); RUN_TEST_ALL_DATATYPES(api_add_high_dims); RUN_TEST_ALL_DATATYPES(api_add_3D); RUN_TEST_ALL_DATATYPES(api_add_2D); RUN_TEST_ALL_DATATYPES(api_add_1D); RUN_TEST(api_add_overflow); return UNITY_END(); } ������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_avgpool2d_maxpool2d_pool.c�����������������������������������������0000664�0000000�0000000�00000076023�14364043643�0024026�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_pool.h" void setUp(void) { /* This is run before EACH TEST */ // note: maxpool2d is actually OK with default tolerance values, but avgpool2d // needs custom tolerance tol_bfloat.ulps = 64; tol_bfloat.epsilon_mult = (0.1 / EPSILON_BFLOAT) + 1; tol_fp16.ulps = 64; tol_fp16.epsilon_mult = (0.1 / EPSILON_FP16) + 1; tol_fp32.ulps = 64 * 16384; tol_fp32.epsilon_mult = (0.1 / EPSILON_FLOAT) + 1; VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } /* * Simple test of basic pool with non-zero strides and SAME_PADDING */ void maxpool2d_same_basic() { zdnn_data_layouts layout = ZDNN_NHWC; /* Visualization of input values [[ [[1, 10], [2, 20], [3, 30]], [[4, 40], [5, 50], [6, 60]], [[7, 70], [8, 80], [9, 90]] ]] */ uint32_t input_shape[] = {1, 3, 3, 2}; float input_values[] = {1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60, 7, 70, 8, 80, 9, 90}; // Input pooling arguments zdnn_pool_padding padding_type = SAME_PADDING; uint32_t kernel_height = 2; uint32_t kernel_width = 2; uint32_t stride_height = 2; uint32_t stride_width = 2; /* Visualization of expected values [[ [[5, 50], [6, 60]], [[8, 80], [9, 90]] ]] */ uint32_t output_shape[] = {1, 2, 2, 2}; float expected_values[] = {5, 50, 6, 60, 8, 80, 9, 90}; test_pool_function(NNPA_MAXPOOL2D, input_shape, layout, false, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_OK, false, expected_values); } /* * Simple test of basic pool with non-zero strides and VALID_PADDING */ void maxpool2d_valid_basic() { zdnn_data_layouts layout = ZDNN_NHWC; /* Visualization of input values [[ [[1, 10], [2, 20], [3, 30]], [[4, 40], [5, 50], [6, 60]], [[7, 70], [8, 80], [9, 90]] ]] */ uint32_t input_shape[] = {1, 3, 3, 2}; float input_values[] = {1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60, 7, 70, 8, 80, 9, 90}; // Input pooling arguments zdnn_pool_padding padding_type = VALID_PADDING; uint32_t kernel_height = 2; uint32_t kernel_width = 2; uint32_t stride_height = 2; uint32_t stride_width = 2; /* Visualization of expected values [[ [[5, 50]], ]] */ uint32_t output_shape[] = {1, 1, 1, 2}; float expected_values[] = {5.0, 50.0}; test_pool_function(NNPA_MAXPOOL2D, input_shape, layout, false, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_OK, false, expected_values); } /* * Simple test of basic pool with non-zero strides and SAME_PADDING */ void avgpool2d_same_basic() { zdnn_data_layouts layout = ZDNN_NHWC; /* Visualization of input values [[ [[1, 10], [2, 20], [3, 30]], [[4, 40], [5, 50], [6, 60]], [[7, 70], [8, 80], [9, 90]] ]] */ uint32_t input_shape[] = {1, 3, 3, 2}; float input_values[] = {1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60, 7, 70, 8, 80, 9, 90}; // Input pooling arguments zdnn_pool_padding padding_type = SAME_PADDING; uint32_t kernel_height = 2; uint32_t kernel_width = 2; uint32_t stride_height = 2; uint32_t stride_width = 2; /* Visualization of expected values [[ [[ 3, 30], [ 4.5, 45]], [[ 7.5, 75], [ 9, 90]] ]] */ uint32_t output_shape[] = {1, 2, 2, 2}; float expected_values[] = {3.0, 30.0, 4.5, 45, 7.5, 75, 9, 90}; test_pool_function(NNPA_AVGPOOL2D, input_shape, layout, false, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_OK, false, expected_values); } /* * Simple test of basic pool with non-zero strides and VALID_PADDING */ void avgpool2d_valid_basic() { zdnn_data_layouts layout = ZDNN_NHWC; /* Visualization of input values [[ [[1, 10], [2, 20], [3, 30]], [[4, 40], [5, 50], [6, 60]], [[7, 70], [8, 80], [9, 90]] ]] */ uint32_t input_shape[] = {1, 3, 3, 2}; float input_values[] = {1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60, 7, 70, 8, 80, 9, 90}; // Input pooling arguments zdnn_pool_padding padding_type = VALID_PADDING; uint32_t kernel_height = 2; uint32_t kernel_width = 2; uint32_t stride_height = 2; uint32_t stride_width = 2; /* Visualization of expected values [[ [[3, 30]], ]] */ uint32_t output_shape[] = {1, 1, 1, 2}; float expected_values[] = {3.0, 30.0}; test_pool_function(NNPA_AVGPOOL2D, input_shape, layout, false, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_OK, false, expected_values); } /* * Simple test of basic pool with zero strides */ void zero_strides(nnpa_function_code function_code) { zdnn_data_layouts layout = ZDNN_NHWC; /* Visualization of input values [[ [[1, 10], [2, 20], [3, 30]], [[4, 40], [5, 50], [6, 60]], [[7, 70], [8, 80], [9, 90]] ]] */ uint32_t input_shape[] = {1, 3, 3, 2}; float input_values[] = {1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60, 7, 70, 8, 80, 9, 90}; // Input pooling arguments zdnn_pool_padding padding_type = VALID_PADDING; uint32_t kernel_height = 3; uint32_t kernel_width = 3; uint32_t stride_height = 0; uint32_t stride_width = 0; /* Visualization of expected values [[ [[9, 90]] ]] */ uint32_t output_shape[] = {1, 1, 1, 2}; /* Visualization of MAXPOOL2D expected values [[ [[9, 90]] ]] */ /* Visualization of AVGPOOL2D expected values [[ [[5, 50]] ]] */ float expected_values[] = {0, 0}; if (function_code == NNPA_MAXPOOL2D) { expected_values[0] = 9; expected_values[1] = 90; } else { expected_values[0] = 5; expected_values[1] = 50; } test_pool_function(function_code, input_shape, layout, false, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_OK, false, expected_values); } void maxpool2d_zero_strides() { zero_strides(NNPA_MAXPOOL2D); } void avgpool2d_zero_strides() { zero_strides(NNPA_AVGPOOL2D); } /* * Check that we don't hit a condition code when using an unexpected padding * type. */ void unexpected_padding_fail(nnpa_function_code function_code) { zdnn_data_layouts layout = ZDNN_NHWC; uint32_t input_shape[] = {1, 3, 3, 2}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments // Set this to the first unused padding type. Then if a new one is // supported, this should fail and we remember to update our code and // documentation. zdnn_pool_padding padding_type = 2; uint32_t kernel_height = 1; uint32_t kernel_width = 1; uint32_t stride_height = 1; uint32_t stride_width = 1; // kernel and strides of 1 should basically copy the input (if the padding // type was valid) uint32_t *output_shape = input_shape; float *expected_values = input_values; test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_FUNC_RC_F000, true, expected_values); } void maxpool2d_unexpected_padding_fail() { unexpected_padding_fail(NNPA_MAXPOOL2D); } void avgpool2d_unexpected_padding_fail() { unexpected_padding_fail(NNPA_AVGPOOL2D); } /* * Check that we don't hit a condition code when using 0 strides and the * largest kernel size. */ void zero_strides_max_kernel_dims_pass(nnpa_function_code function_code) { zdnn_data_layouts layout = ZDNN_NHWC; uint32_t input_shape[] = {1, MAXIMUM_POOL_ZERO_STRIDES_KERNEL_SIZE, MAXIMUM_POOL_ZERO_STRIDES_KERNEL_SIZE, 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments zdnn_pool_padding padding_type = VALID_PADDING; uint32_t kernel_height = input_shape[1]; uint32_t kernel_width = input_shape[2]; uint32_t stride_height = 0; uint32_t stride_width = 0; uint32_t output_shape[] = {1, 1, 1, 1}; // Since all input values are the same, they should average to the same. float *expected_values = input_values; test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_OK, true, expected_values); } void maxpool2d_zero_strides_max_kernel_dims_pass() { zero_strides_max_kernel_dims_pass(NNPA_MAXPOOL2D); } void avgpool2d_zero_strides_max_kernel_dims_pass() { zero_strides_max_kernel_dims_pass(NNPA_AVGPOOL2D); } /* * Check that we hit the expected condition code when using 0 strides and the * over the largest kernel size. */ void zero_strides_max_kernel_height_fail(nnpa_function_code function_code) { zdnn_data_layouts layout = ZDNN_NHWC; // over_kernel_max is a valid tensor dimension size but is too large for a // kernel. This should lead to a condition code from the NNPA. If not, // update the test constant and the API documentation to the new value. uint32_t over_kernel_max = MAXIMUM_POOL_ZERO_STRIDES_KERNEL_SIZE + 1; uint32_t input_shape[] = {1, over_kernel_max, 5, 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments zdnn_pool_padding padding_type = VALID_PADDING; uint32_t kernel_height = input_shape[1]; uint32_t kernel_width = input_shape[2]; uint32_t stride_height = 0; uint32_t stride_width = 0; uint32_t output_shape[] = {1, 1, 1, 1}; // Output values don't really matter as we expect failure status. float *expected_values = input_values; test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_FUNC_RC_F001, true, expected_values); } void maxpool2d_zero_strides_max_kernel_height_fail() { zero_strides_max_kernel_height_fail(NNPA_MAXPOOL2D); } void avgpool2d_zero_strides_max_kernel_height_fail() { zero_strides_max_kernel_height_fail(NNPA_AVGPOOL2D); } /* * Check that we hit the expected condition code when using 0 strides and the * over the largest kernel size. */ void zero_strides_max_kernel_width_fail(nnpa_function_code function_code) { zdnn_data_layouts layout = ZDNN_NHWC; // over_kernel_max is a valid tensor dimension size but is too large for a // kernel. This should lead to a condition code from the NNPA. If not, // update the test constant and the API documentation to the new value. uint32_t over_kernel_max = MAXIMUM_POOL_ZERO_STRIDES_KERNEL_SIZE + 1; uint32_t input_shape[] = {1, 8, over_kernel_max, 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments zdnn_pool_padding padding_type = VALID_PADDING; uint32_t kernel_height = input_shape[1]; uint32_t kernel_width = input_shape[2]; uint32_t stride_height = 0; uint32_t stride_width = 0; uint32_t output_shape[] = {1, 1, 1, 1}; // Output values don't really matter as we expect failure status. float *expected_values = input_values; test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_FUNC_RC_F001, true, expected_values); } void maxpool2d_zero_strides_max_kernel_width_fail() { zero_strides_max_kernel_width_fail(NNPA_MAXPOOL2D); } void avgpool2d_zero_strides_max_kernel_width_fail() { zero_strides_max_kernel_width_fail(NNPA_AVGPOOL2D); } /* * Check that we don't hit a condition code when using nonzero strides and the * largest kernel size. */ void max_kernel_pass(nnpa_function_code function_code, zdnn_pool_padding padding_type) { zdnn_data_layouts layout = ZDNN_NHWC; uint32_t input_shape[] = {1, MAXIMUM_POOL_NONZERO_STRIDES_KERNEL_SIZE, MAXIMUM_POOL_NONZERO_STRIDES_KERNEL_SIZE, 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments uint32_t kernel_height = input_shape[1]; uint32_t kernel_width = input_shape[2]; uint32_t stride_height = 1; uint32_t stride_width = 1; uint32_t output_shape[] = {1, 1, 1, 1}; // Since all input values are the same, they should average to the same. float *expected_values = input_values; // use input_shape[] as output shape if SAME_PADDING since stride // height/width are 1 test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, padding_type == SAME_PADDING ? input_shape : output_shape, layout, ZDNN_OK, true, expected_values); } void maxpool2d_max_kernel_valid_padding_pass() { max_kernel_pass(NNPA_MAXPOOL2D, VALID_PADDING); } void maxpool2d_max_kernel_same_padding_pass() { max_kernel_pass(NNPA_MAXPOOL2D, SAME_PADDING); } void avgpool2d_max_kernel_valid_padding_pass() { max_kernel_pass(NNPA_AVGPOOL2D, VALID_PADDING); } void avgpool2d_max_kernel_same_padding_pass() { max_kernel_pass(NNPA_AVGPOOL2D, SAME_PADDING); } /* * Check that we hit the expected condition code when using 0 strides and the * over the largest kernel size. */ void max_kernel_height_fail(nnpa_function_code function_code, zdnn_pool_padding padding_type) { zdnn_data_layouts layout = ZDNN_NHWC; // over_kernel_max is a valid tensor dimension size but is too large for a // kernel. This should lead to a condition code from the NNPA. If not, // update the test constant and the API documentation to the new value. uint32_t over_kernel_max = MAXIMUM_POOL_NONZERO_STRIDES_KERNEL_SIZE + 1; uint32_t input_shape[] = {1, over_kernel_max, 5, 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments uint32_t kernel_height = input_shape[1]; uint32_t kernel_width = input_shape[2]; uint32_t stride_height = 1; uint32_t stride_width = 1; uint32_t output_shape[] = {1, 1, 1, 1}; // Output values don't really matter as we expect failure status. float *expected_values = input_values; // use input_shape[] as output shape if SAME_PADDING since stride // height/width are 1 test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, padding_type == SAME_PADDING ? input_shape : output_shape, layout, ZDNN_FUNC_RC_F002, true, expected_values); } void maxpool2d_max_kernel_valid_padding_height_fail() { max_kernel_height_fail(NNPA_MAXPOOL2D, VALID_PADDING); } void maxpool2d_max_kernel_same_padding_height_fail() { max_kernel_height_fail(NNPA_MAXPOOL2D, SAME_PADDING); } void avgpool2d_max_kernel_valid_padding_height_fail() { max_kernel_height_fail(NNPA_AVGPOOL2D, VALID_PADDING); } void avgpool2d_max_kernel_same_padding_height_fail() { max_kernel_height_fail(NNPA_AVGPOOL2D, SAME_PADDING); } /* * Check that we hit the expected condition code when using 0 strides and the * over the largest kernel size. */ void max_kernel_width_fail(nnpa_function_code function_code, zdnn_pool_padding padding_type) { zdnn_data_layouts layout = ZDNN_NHWC; // over_kernel_max is a valid tensor dimension size but is too large for a // kernel. This should lead to a condition code from the NNPA. If not, // update the test constant and the API documentation to the new value. uint32_t over_kernel_max = MAXIMUM_POOL_NONZERO_STRIDES_KERNEL_SIZE + 1; uint32_t input_shape[] = {1, 8, over_kernel_max, 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments uint32_t kernel_height = input_shape[1]; uint32_t kernel_width = input_shape[2]; uint32_t stride_height = 1; uint32_t stride_width = 1; uint32_t output_shape[] = {1, 1, 1, 1}; // Output values don't really matter as we expect failure status. float *expected_values = input_values; // use input_shape[] as output shape if SAME_PADDING since stride // height/width are 1 test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, padding_type == SAME_PADDING ? input_shape : output_shape, layout, ZDNN_FUNC_RC_F002, true, expected_values); } void maxpool2d_max_kernel_valid_padding_width_fail() { max_kernel_width_fail(NNPA_MAXPOOL2D, VALID_PADDING); } void maxpool2d_max_kernel_same_padding_width_fail() { max_kernel_width_fail(NNPA_MAXPOOL2D, SAME_PADDING); } void avgpool2d_max_kernel_valid_padding_width_fail() { max_kernel_width_fail(NNPA_AVGPOOL2D, VALID_PADDING); } void avgpool2d_max_kernel_same_padding_width_fail() { max_kernel_width_fail(NNPA_AVGPOOL2D, SAME_PADDING); } /* * Check that we don't hit a condition code when using nonzero strides and the * largest stride size. */ void max_stride_pass(nnpa_function_code function_code, zdnn_pool_padding padding_type) { zdnn_data_layouts layout = ZDNN_NHWC; uint32_t input_shape[] = {1, 2 * MAXIMUM_POOL_NONZERO_STRIDES_STRIDE_SIZE, 2 * MAXIMUM_POOL_NONZERO_STRIDES_STRIDE_SIZE, 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments uint32_t kernel_height = input_shape[1] / 2; uint32_t kernel_width = input_shape[2] / 2; uint32_t stride_height = input_shape[1] / 2; uint32_t stride_width = input_shape[2] / 2; // With stride and kernel set to exactly 1/2 of input, we'd expect output to // end with a height and width of exactly 2. // These dimensions work for both VALID_PADDING and VALID_PADDING uint32_t output_shape[] = {1, 2, 2, 1}; // Since all input values are the same, they should average to the same. float expected_values[] = {input_values[0], input_values[0], input_values[0], input_values[0]}; test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_OK, true, expected_values); } void maxpool2d_max_stride_valid_padding_pass() { max_stride_pass(NNPA_MAXPOOL2D, VALID_PADDING); } void maxpool2d_max_stride_same_padding_pass() { max_stride_pass(NNPA_MAXPOOL2D, SAME_PADDING); } void avgpool2d_max_stride_valid_padding_pass() { max_stride_pass(NNPA_AVGPOOL2D, VALID_PADDING); } void avgpool2d_max_stride_same_padding_pass() { max_stride_pass(NNPA_AVGPOOL2D, SAME_PADDING); } /* * Check that we hit the expected condition code when using just over the * largest nonzero strides allowed */ void max_stride_height_fail(nnpa_function_code function_code, zdnn_pool_padding padding_type) { zdnn_data_layouts layout = ZDNN_NHWC; // over_stride_max is a valid tensor dimension size but is too large for a // stride. This should lead to a condition code from the AIU. If not, update // the test constant and the API documentation to the new value. uint32_t over_stride_max = MAXIMUM_POOL_NONZERO_STRIDES_STRIDE_SIZE + 1; // Use 2 * X here to make determining exected shape and values easier. uint32_t input_shape[] = {1, 2 * over_stride_max, 2 * MAXIMUM_POOL_NONZERO_STRIDES_STRIDE_SIZE, 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments uint32_t kernel_height = input_shape[1] / 2; uint32_t kernel_width = input_shape[2] / 2; uint32_t stride_height = input_shape[1] / 2; uint32_t stride_width = input_shape[2] / 2; // With stride and kernel set to exactly 1/2 of input, we'd expect output to // end with a height and width of exactly 2. uint32_t output_shape[] = {1, 2, 2, 1}; // Output values don't really matter as we expect failure status. float expected_values[] = {input_values[0], input_values[0], input_values[0], input_values[0]}; test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_FUNC_RC_F003, true, expected_values); } void maxpool2d_max_stride_valid_padding_height_fail() { max_stride_height_fail(NNPA_MAXPOOL2D, VALID_PADDING); } void maxpool2d_max_stride_same_padding_height_fail() { max_stride_height_fail(NNPA_MAXPOOL2D, SAME_PADDING); } void avgpool2d_max_stride_valid_padding_height_fail() { max_stride_height_fail(NNPA_AVGPOOL2D, VALID_PADDING); } void avgpool2d_max_stride_same_padding_height_fail() { max_stride_height_fail(NNPA_AVGPOOL2D, SAME_PADDING); } /* * Check that we hit the expected condition code when using just over the * largest nonzero strides allowed */ void max_stride_width_fail(nnpa_function_code function_code, zdnn_pool_padding padding_type) { zdnn_data_layouts layout = ZDNN_NHWC; // over_stride_max is a valid tensor dimension size but is too large for a // stride. This should lead to a condition code from the AIU. If not, update // the test constant and the API documentation to the new value. uint32_t over_stride_max = MAXIMUM_POOL_NONZERO_STRIDES_STRIDE_SIZE + 1; // Use 2 * X here to make determining exected shape and values easier. uint32_t input_shape[] = {1, 2 * MAXIMUM_POOL_NONZERO_STRIDES_STRIDE_SIZE, 2 * over_stride_max, 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; // Input pooling arguments uint32_t kernel_height = input_shape[1] / 2; uint32_t kernel_width = input_shape[2] / 2; uint32_t stride_height = input_shape[1] / 2; uint32_t stride_width = input_shape[2] / 2; // With stride and kernel set to exactly 1/2 of input, we'd expect output to // end with a height and width of exactly 2. uint32_t output_shape[] = {1, 2, 2, 1}; // Output values don't really matter as we expect failure status. float expected_values[] = {input_values[0], input_values[0], input_values[0], input_values[0]}; test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, output_shape, layout, ZDNN_FUNC_RC_F003, true, expected_values); } void maxpool2d_max_stride_valid_padding_width_fail() { max_stride_width_fail(NNPA_MAXPOOL2D, VALID_PADDING); } void maxpool2d_max_stride_same_padding_width_fail() { max_stride_width_fail(NNPA_MAXPOOL2D, SAME_PADDING); } void avgpool2d_max_stride_valid_padding_width_fail() { max_stride_width_fail(NNPA_AVGPOOL2D, VALID_PADDING); } void avgpool2d_max_stride_same_padding_width_fail() { max_stride_width_fail(NNPA_AVGPOOL2D, SAME_PADDING); } /* * Check that we hit the expected condition code when using just over the * largest input height/width allowed when strides are non-zero */ void nonzero_strides_bad_height_or_width_fail(nnpa_function_code function_code, bool bad_height, bool bad_width, zdnn_pool_padding padding_type) { zdnn_data_layouts layout = ZDNN_NHWC; uint32_t input_shape[] = { 1, MAXIMUM_POOL_NONZERO_STRIDES_HEIGHT_WIDTH + (bad_height ? 1 : 0), MAXIMUM_POOL_NONZERO_STRIDES_HEIGHT_WIDTH + (bad_width ? 1 : 0), 1}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; uint32_t kernel_height = 1; uint32_t kernel_width = 1; uint32_t stride_height = 1; uint32_t stride_width = 1; // when kernel height/width and stride height/width are all 1, output shape is // same as input's // Output values don't really matter as we expect failure status. test_pool_function(function_code, input_shape, layout, true, input_values, padding_type, kernel_height, kernel_width, stride_height, stride_width, input_shape, layout, ZDNN_FUNC_RC_F004, true, ZERO_ARRAY); } void maxpool2d_non_zero_strides_valid_padding_height_fail() { nonzero_strides_bad_height_or_width_fail(NNPA_MAXPOOL2D, true, false, VALID_PADDING); } void maxpool2d_non_zero_strides_same_padding_height_fail() { nonzero_strides_bad_height_or_width_fail(NNPA_MAXPOOL2D, true, false, SAME_PADDING); } void avgpool2d_non_zero_strides_valid_padding_height_fail() { nonzero_strides_bad_height_or_width_fail(NNPA_AVGPOOL2D, true, false, VALID_PADDING); } void avgpool2d_non_zero_strides_same_padding_height_fail() { nonzero_strides_bad_height_or_width_fail(NNPA_AVGPOOL2D, true, false, SAME_PADDING); } void maxpool2d_non_zero_strides_valid_padding_width_fail() { nonzero_strides_bad_height_or_width_fail(NNPA_MAXPOOL2D, false, true, VALID_PADDING); } void maxpool2d_non_zero_strides_same_padding_width_fail() { nonzero_strides_bad_height_or_width_fail(NNPA_MAXPOOL2D, false, true, SAME_PADDING); } void avgpool2d_non_zero_strides_valid_padding_width_fail() { nonzero_strides_bad_height_or_width_fail(NNPA_AVGPOOL2D, false, true, VALID_PADDING); } void avgpool2d_non_zero_strides_same_padding_width_fail() { nonzero_strides_bad_height_or_width_fail(NNPA_AVGPOOL2D, false, true, SAME_PADDING); } int main(int argc, char *argv[]) { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(maxpool2d_same_basic); RUN_TEST_ALL_DATATYPES(maxpool2d_valid_basic); RUN_TEST_ALL_DATATYPES(avgpool2d_same_basic); RUN_TEST_ALL_DATATYPES(avgpool2d_valid_basic); RUN_TEST_ALL_DATATYPES(maxpool2d_zero_strides); RUN_TEST_ALL_DATATYPES(avgpool2d_zero_strides); // Tests to confirm we get the expected condition codes from the NNPA. // Technically these don't test our library. However we document these // in our API. These tests should fail if hardware changes the underlying // conditions meaning we need to update our documentation (and tests). { RUN_TEST_ALL_DATATYPES(maxpool2d_unexpected_padding_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_unexpected_padding_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_zero_strides_max_kernel_dims_pass); RUN_TEST_ALL_DATATYPES(maxpool2d_zero_strides_max_kernel_height_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_zero_strides_max_kernel_width_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_zero_strides_max_kernel_dims_pass); RUN_TEST_ALL_DATATYPES(avgpool2d_zero_strides_max_kernel_height_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_zero_strides_max_kernel_width_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_max_kernel_valid_padding_pass); RUN_TEST_ALL_DATATYPES(maxpool2d_max_kernel_same_padding_pass); RUN_TEST_ALL_DATATYPES(avgpool2d_max_kernel_valid_padding_pass); RUN_TEST_ALL_DATATYPES(avgpool2d_max_kernel_same_padding_pass); RUN_TEST_ALL_DATATYPES(maxpool2d_max_kernel_valid_padding_height_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_max_kernel_same_padding_height_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_max_kernel_valid_padding_height_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_max_kernel_same_padding_height_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_max_kernel_valid_padding_width_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_max_kernel_same_padding_width_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_max_kernel_valid_padding_width_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_max_kernel_same_padding_width_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_max_stride_valid_padding_pass); RUN_TEST_ALL_DATATYPES(maxpool2d_max_stride_same_padding_pass); RUN_TEST_ALL_DATATYPES(avgpool2d_max_stride_valid_padding_pass); RUN_TEST_ALL_DATATYPES(avgpool2d_max_stride_same_padding_pass); RUN_TEST_ALL_DATATYPES(maxpool2d_max_stride_valid_padding_height_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_max_stride_same_padding_height_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_max_stride_valid_padding_height_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_max_stride_same_padding_height_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_max_stride_valid_padding_width_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_max_stride_same_padding_width_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_max_stride_valid_padding_width_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_max_stride_same_padding_width_fail); RUN_TEST_ALL_DATATYPES( maxpool2d_non_zero_strides_valid_padding_height_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_non_zero_strides_same_padding_height_fail); RUN_TEST_ALL_DATATYPES( avgpool2d_non_zero_strides_valid_padding_height_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_non_zero_strides_same_padding_height_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_non_zero_strides_valid_padding_width_fail); RUN_TEST_ALL_DATATYPES(maxpool2d_non_zero_strides_same_padding_width_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_non_zero_strides_valid_padding_width_fail); RUN_TEST_ALL_DATATYPES(avgpool2d_non_zero_strides_same_padding_width_fail); } return UNITY_END(); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_batchnorm.c��������������������������������������������������������0000664�0000000�0000000�00000016275�14364043643�0021073�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <stdlib.h> #include <string.h> #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ tol_bfloat.ulps = 64; tol_bfloat.epsilon_mult = (0.1 / EPSILON_BFLOAT) + 1; tol_fp16.ulps = 64; tol_fp16.epsilon_mult = (0.1 / EPSILON_FP16) + 1; tol_fp32.ulps = 64 * 16384; tol_fp32.epsilon_mult = (0.1 / EPSILON_FLOAT) + 1; VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } /** * Helper function to compute expected output tensor from randomly generated * test input arrays. * * | input_a | input_b | input_c | result | * | (n, h, w, c) | (c) | (c) | (n, h, w, c) | * * formula: output(*, *, *, c) = input_a(*, *, *, c) * input_b(c) + input_c(c) * */ void gen_test_expected_fp32_array(uint32_t *shape, zdnn_data_types type, float *input_a, float *input_b, float *input_c, float *result) { uint32_t c = shape[3]; for (uint64_t i = 0; i < (uint64_t)shape[0] * shape[1] * shape[2] * c; i++) { float cleansed_input_a = 0; float cleansed_input_b = 0; float cleansed_input_c = 0; switch (type) { case (BFLOAT): cleansed_input_a = CLEANSE_BFLOAT(input_a[i]); cleansed_input_b = CLEANSE_BFLOAT(input_b[i % c]); cleansed_input_c = CLEANSE_BFLOAT(input_c[i % c]); break; case (FP16): cleansed_input_a = CLEANSE_FP16(input_a[i]); cleansed_input_b = CLEANSE_FP16(input_b[i % c]); cleansed_input_c = CLEANSE_FP16(input_c[i % c]); break; case (FP32): cleansed_input_a = CLEANSE_FP32(input_a[i]); cleansed_input_b = CLEANSE_FP32(input_b[i % c]); cleansed_input_c = CLEANSE_FP32(input_c[i % c]); break; default: break; } result[i] = cleansed_input_a * cleansed_input_b + cleansed_input_c; } } void do_test(uint32_t *input_a_shape, uint32_t *input_b_shape, uint32_t *input_c_shape, uint32_t *output_shape, zdnn_data_types dtype, float *input_a_values, float *input_b_values, float *input_c_values, zdnn_status expected_status, float *expected_values) { zdnn_ztensor *input_a_ztensor = alloc_ztensor_with_values( input_a_shape, ZDNN_NHWC, dtype, NO_CONCAT, false, input_a_values); zdnn_ztensor *input_b_ztensor = alloc_ztensor_with_values( input_b_shape, ZDNN_1D, dtype, NO_CONCAT, false, input_b_values); zdnn_ztensor *input_c_ztensor = alloc_ztensor_with_values( input_c_shape, ZDNN_1D, dtype, NO_CONCAT, false, input_c_values); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_shape, ZDNN_NHWC, dtype, NO_CONCAT, true, ZERO_ARRAY); // Test requires AIU #ifdef TEST_AIU // Call public NNPA method zdnn_status status = zdnn_batchnorm(input_a_ztensor, input_b_ztensor, input_c_ztensor, output_ztensor); // Assert returned status matches expected TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to zdnn_batchnorm to returned status %08x but expected " "%08x\n", status, expected_status); fp_tolerance *tol = NULL; switch (output_ztensor->pre_transformed_desc->type) { case BFLOAT: tol = &tol_bfloat; break; case FP16: tol = &tol_fp16; break; case FP32: tol = &tol_fp32; break; default: break; // should never get here } // If expected status is ZDNN_OK, assert output values matches expected if (expected_status == ZDNN_OK) { assert_ztensor_values_adv(output_ztensor, false, expected_values, *tol); } #endif // Cleanup test ztensors free_ztensor_buffers(4, input_a_ztensor, input_b_ztensor, input_c_ztensor, output_ztensor); } void zdnn_batchnorm_small_values() { uint32_t shape[] = {1, 3, 3, 2}; float input_a_values[] = {0.1, 1, 0.2, 2, 0.3, 3, 0.4, 4, 0.5, 5, 0.6, 6, 0.7, 7, 0.8, 8, 0.9, 9}; uint32_t input_b_shape[] = {2}; float input_b_values[] = {0.45, 0.55}; uint32_t input_c_shape[] = {2}; float input_c_values[] = {0.75, 0.45}; float output_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; gen_test_expected_fp32_array(shape, test_datatype, input_a_values, input_b_values, input_c_values, output_values); do_test(shape, input_b_shape, input_c_shape, shape, test_datatype, input_a_values, input_b_values, input_c_values, ZDNN_OK, output_values); } void zdnn_batchnorm_high_values() { uint32_t shape[] = {1, 3, 3, 2}; float input_a_values[] = {1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60, 7, 70, 8, 80, 9, 90}; uint32_t input_b_shape[] = {2}; float input_b_values[] = {4.5, 5.5}; uint32_t input_c_shape[] = {2}; float input_c_values[] = {7.5, 4.5}; float output_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; gen_test_expected_fp32_array(shape, test_datatype, input_a_values, input_b_values, input_c_values, output_values); do_test(shape, input_b_shape, input_c_shape, shape, test_datatype, input_a_values, input_b_values, input_c_values, ZDNN_OK, output_values); } void test_batchnorm_random_values(uint32_t n, uint32_t h, uint32_t w, uint32_t c) { uint32_t shape[] = {n, h, w, c}; uint64_t num_values = (uint64_t)n * h * w * c; float input_a_values[num_values]; gen_random_float_array_pos_neg(num_values, input_a_values); uint32_t input_b_shape[] = {c}; float input_b_values[c]; gen_random_float_array_pos_neg(c, input_b_values); uint32_t input_c_shape[] = {c}; float input_c_values[c]; gen_random_float_array_pos_neg(c, input_c_values); float output_values[num_values]; gen_test_expected_fp32_array(shape, test_datatype, input_a_values, input_b_values, input_c_values, output_values); do_test(shape, input_b_shape, input_c_shape, shape, test_datatype, input_a_values, input_b_values, input_c_values, ZDNN_OK, output_values); } void zdnn_batchnorm_random_values_low_dims() { test_batchnorm_random_values(2, 3, 4, 5); } void zdnn_batchnorm_random_values_high_dims() { test_batchnorm_random_values(2, 3, 4, 100); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(zdnn_batchnorm_small_values); RUN_TEST_ALL_DATATYPES(zdnn_batchnorm_high_values); RUN_TEST_ALL_DATATYPES(zdnn_batchnorm_random_values_low_dims); RUN_TEST_ALL_DATATYPES(zdnn_batchnorm_random_values_high_dims); return UNITY_END(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_conv2d.c�����������������������������������������������������������0000664�0000000�0000000�00001510327�14364043643�0020307�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <stdlib.h> #include <string.h> #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ tol_bfloat.ulps = 64; tol_bfloat.epsilon_mult = (0.1 / EPSILON_BFLOAT) + 1; tol_fp16.ulps = 64; tol_fp16.epsilon_mult = (0.1 / EPSILON_FP16) + 1; tol_fp32.ulps = 64 * 16384; tol_fp32.epsilon_mult = (0.1 / EPSILON_FLOAT) + 1; VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } // convenience debug macro #define PRINT_DIMS(x) \ printf(#x " pre: %u %u %u %u\n", (x)->pre_transformed_desc->dim4, \ (x)->pre_transformed_desc->dim3, (x)->pre_transformed_desc->dim2, \ (x)->pre_transformed_desc->dim1); \ printf(#x ": %u %u %u %u\n", (x)->transformed_desc->dim4, \ (x)->transformed_desc->dim3, (x)->transformed_desc->dim2, \ (x)->transformed_desc->dim1); typedef struct input_set { uint32_t n; uint32_t height_in; uint32_t width_in; uint32_t channel_in; uint32_t kernel_size[2]; uint32_t channel_out; } input_set; typedef struct strides_input_set { uint32_t height; uint32_t width; } strides_input_set; void test_conv2d(input_set *set, strides_input_set *strides, void *input_vals, void *kernel_vals, void *bias_vals, void *output_exp_vals, void *output_relu_exp_vals, zdnn_pool_padding padding, void *clipping_value) { zdnn_status status; /**************************************************************************** ZDNN dims requirements if stride_height > 0, stride_width > 0, padding = SAME input: (n, x, y, z) kernel: (i, j, z, a) bias: (a) output: (n, e, f, a) (e = ceil(x/stride_height), f = ceil(y/stride_width)) if stride_height > 0, stride_width > 0, padding = VALID input: (n, x, y, z) (x > i, y > j) kernel: (i, j, z, a) bias: (a) output: (n, e, f, a) (e = ceil((x - i + 1)/stride_height), f = ceil((y - j + 1)/stride_width)) if stride_height = 0, stride_width = 0, padding = VALID input: (n, x, y, z) kernel: (x, y, z, a) bias: (a) output: (n, 1, 1, a) n = n x = height_in y = width_in z = channel_in (i, j) = kernel_size a = channel_out (stride_height, stride_width) = strides ****************************************************************************/ uint32_t input_dims[4] = {set->n, set->height_in, set->width_in, set->channel_in}; uint32_t kernel_dims[4] = {0, 0, // 0s are placeholders set->channel_in, set->channel_out}; uint32_t bias_dims[1] = {set->channel_out}; uint32_t output_dims[4] = {set->n, 0, 0, set->channel_out}; // 0s are placeholders // zero-strides + VALID_PADDING is special case, so ignore kernel_size[0] & // [1] and set kernel_dims[0] & [1] to what AIU wants if (padding == VALID_PADDING && strides->height == 0 && strides->width == 0) { kernel_dims[0] = set->height_in; kernel_dims[1] = set->width_in; } else { kernel_dims[0] = set->kernel_size[0]; kernel_dims[1] = set->kernel_size[1]; } // output_dims[1] & [2] are exactly what the AIU wants if (padding == VALID_PADDING) { // output dim3 output_dims[1] = (strides->height == 0 && strides->width == 0) ? 1 : CEIL((set->height_in - kernel_dims[0] + 1), strides->height); // output dim2 output_dims[2] = (strides->height == 0 && strides->width == 0) ? 1 : CEIL((set->width_in - kernel_dims[1] + 1), strides->width); } else { // not bother a switch statement, gotta be SAME_PADDING output_dims[1] = CEIL(set->height_in, strides->height); // output dim3 output_dims[2] = CEIL(set->width_in, strides->width); // output dim2 } zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, false, input_vals); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values( kernel_dims, ZDNN_HWCK, test_datatype, NO_CONCAT, false, kernel_vals); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values( bias_dims, ZDNN_1D, test_datatype, NO_CONCAT, false, bias_vals); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_relu_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); BEGIN_BLOCK_IF_LOGLEVEL_TRACE { PRINT_DIMS(input_ztensor); PRINT_DIMS(kernel_ztensor); PRINT_DIMS(bias_ztensor); PRINT_DIMS(output_ztensor); PRINT_DIMS(output_relu_ztensor); printf("strides = height %u width %u\n", strides->height, strides->width); } status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, CONV2D_ACT_NONE, clipping_value, output_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_conv2d() (CONV2D_ACT_NONE) failed, status = %08x", status); status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, CONV2D_ACT_RELU, clipping_value, output_relu_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_conv2d() (CONV2D_ACT_RELU) failed, status = %08x", status); BEGIN_BLOCK_IF_LOGLEVEL_TRACE { dumpdata_ztensor(input_ztensor, AS_FLOAT, true); dumpdata_ztensor(kernel_ztensor, AS_FLOAT, true); dumpdata_ztensor(bias_ztensor, AS_FLOAT, true); dumpdata_ztensor(output_ztensor, AS_FLOAT, true); dumpdata_ztensor(output_relu_ztensor, AS_FLOAT, true); } switch (output_ztensor->pre_transformed_desc->type) { case (BFLOAT): assert_ztensor_values_adv(output_ztensor, false, output_exp_vals, tol_bfloat); assert_ztensor_values_adv(output_relu_ztensor, false, output_relu_exp_vals, tol_bfloat); break; case (FP16): assert_ztensor_values_adv(output_ztensor, false, output_exp_vals, tol_fp16); assert_ztensor_values_adv(output_relu_ztensor, false, output_relu_exp_vals, tol_fp16); break; case (FP32): assert_ztensor_values_adv(output_ztensor, false, output_exp_vals, tol_fp32); assert_ztensor_values_adv(output_relu_ztensor, false, output_relu_exp_vals, tol_fp32); break; default: break; } free_ztensor_buffers(5, input_ztensor, kernel_ztensor, bias_ztensor, output_ztensor, output_relu_ztensor); } /******************************************************************* small: n = 1 height_in = 4 width_in = 3 channel_in = 5 kernel_size = (2, 2) channel_out = 2 medium: n = 3 height_in = 10 width_in = 8 channel_in = 5 kernel_size = (2, 3) channel_out = 5 large: n = 4 height_in = 15 width_in = 10 channel_in = 6 kernel_size = (4, 6) channel_out = 7 non-zero strides: small: (1, 1) medium: (2, 3) large: (3, 4) *******************************************************************/ input_set small_input = {1, 4, 3, 5, {2, 2}, 2}; input_set medium_input = {3, 10, 8, 5, {2, 3}, 5}; input_set large_input = {4, 15, 10, 6, {4, 6}, 7}; strides_input_set small_non0_strides = {1, 1}; strides_input_set medium_non0_strides = {2, 3}; strides_input_set large_non0_strides = {3, 4}; strides_input_set zero_strides = {0, 0}; void test_valid_padding_non_zero_strides_small() { input_set *set = &small_input; strides_input_set *strides = &small_non0_strides; // 1,4,3,5 uint32_t input_vals[] = { 0x3f15a7d8, 0x3f55d27f, 0x3f04e322, 0x3f0bc669, 0x3f2eec77, 0x3d07cb10, 0x3e528880, 0x3f1da880, 0x3e3fb0a8, 0x3f40bb0b, 0x3e0e0bcc, 0x3f17da1f, 0x3f4f6880, 0x3d0b5ba0, 0x3f5ba1ae, 0x3e780c74, 0x3de61650, 0x3f7ae7a4, 0x3f71ba1f, 0x3f2fdc52, 0x3f50c293, 0x3e1d23d0, 0x3deae1a8, 0x3f615378, 0x3ba82d80, 0x3f4b0c93, 0x3e77825c, 0x3ea22f0a, 0x3aa20200, 0x3e33de00, 0x3e8e771c, 0x3f39eaa3, 0x3f324e26, 0x3f17f541, 0x3f3fe98e, 0x3ef6c34e, 0x3f3379fe, 0x3f6a0de8, 0x3ed4dfce, 0x3f1aca63, 0x3f51dd20, 0x3e50b72c, 0x3f6f62f4, 0x3ed5df52, 0x3de131a8, 0x3f7f3fc1, 0x3f26ab72, 0x3f70f111, 0x3e8ad072, 0x3e592e30, 0x3f32cd09, 0x3f4644b7, 0x3f19794f, 0x3f313923, 0x3f786a79, 0x3f114ab9, 0x3edfb038, 0x3d858c20, 0x3e50bd98, 0x3f563faa, }; // 2,2,5,2 uint32_t kernel_vals[] = { 0xbadb6d80, 0x3da65588, 0xbdb06154, 0xbd13a074, 0xbca28f68, 0xbe1025bd, 0xbe5abfd6, 0xbe146a76, 0x3db50ae0, 0xbe05a938, 0x3df5a9a0, 0x3e3e2300, 0x3d759a80, 0x3cc1d430, 0x3d725b60, 0xbd67df54, 0xbe17a51c, 0xbdd2ced4, 0x3e0963a4, 0x3e44d336, 0xbe3c7496, 0xbd3c7db4, 0xbb912ca0, 0x3e4f5476, 0xbd8a65c2, 0xbdb281f2, 0xbdbcc6b6, 0xbe1ff856, 0xbe1b3afe, 0x3dcc5820, 0xbe2882ac, 0x3e2b57ec, 0x3e358cf2, 0xbe54696c, 0xbd340870, 0x3e45d54a, 0x3c07b640, 0xbe567290, 0xbdc76b34, 0x3dddf448, }; // 2 uint32_t bias_vals[] = { 0x3c40ac50, 0xbdeac81f, }; // 1,3,2,2 uint32_t output_exp_vals[] = { 0xbed199d0, 0xbee4ca5f, 0xbe0febf4, 0xbe2b0406, 0xbefd7c85, 0xbe846eb2, 0xbef1750b, 0x3e52c1ce, 0xbeb43421, 0xbe83d2bf, 0xbeeeaca6, 0xbe243821, }; // 1,3,2,2 uint32_t output_relu_exp_vals[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e52c1ce, 0x0, 0x0, 0x0, 0x0, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, VALID_PADDING, NULL); } void test_valid_padding_non_zero_strides_small_with_clip() { input_set *set = &small_input; strides_input_set *strides = &small_non0_strides; // 1,4,3,5 uint32_t input_vals[] = { 0x3f15a7d8, 0x3f55d27f, 0x3f04e322, 0x3f0bc669, 0x3f2eec77, 0x3d07cb10, 0x3e528880, 0x3f1da880, 0x3e3fb0a8, 0x3f40bb0b, 0x3e0e0bcc, 0x3f17da1f, 0x3f4f6880, 0x3d0b5ba0, 0x3f5ba1ae, 0x3e780c74, 0x3de61650, 0x3f7ae7a4, 0x3f71ba1f, 0x3f2fdc52, 0x3f50c293, 0x3e1d23d0, 0x3deae1a8, 0x3f615378, 0x3ba82d80, 0x3f4b0c93, 0x3e77825c, 0x3ea22f0a, 0x3aa20200, 0x3e33de00, 0x3e8e771c, 0x3f39eaa3, 0x3f324e26, 0x3f17f541, 0x3f3fe98e, 0x3ef6c34e, 0x3f3379fe, 0x3f6a0de8, 0x3ed4dfce, 0x3f1aca63, 0x3f51dd20, 0x3e50b72c, 0x3f6f62f4, 0x3ed5df52, 0x3de131a8, 0x3f7f3fc1, 0x3f26ab72, 0x3f70f111, 0x3e8ad072, 0x3e592e30, 0x3f32cd09, 0x3f4644b7, 0x3f19794f, 0x3f313923, 0x3f786a79, 0x3f114ab9, 0x3edfb038, 0x3d858c20, 0x3e50bd98, 0x3f563faa, }; // 2,2,5,2 uint32_t kernel_vals[] = { 0xbadb6d80, 0x3da65588, 0xbdb06154, 0xbd13a074, 0xbca28f68, 0xbe1025bd, 0xbe5abfd6, 0xbe146a76, 0x3db50ae0, 0xbe05a938, 0x3df5a9a0, 0x3e3e2300, 0x3d759a80, 0x3cc1d430, 0x3d725b60, 0xbd67df54, 0xbe17a51c, 0xbdd2ced4, 0x3e0963a4, 0x3e44d336, 0xbe3c7496, 0xbd3c7db4, 0xbb912ca0, 0x3e4f5476, 0xbd8a65c2, 0xbdb281f2, 0xbdbcc6b6, 0xbe1ff856, 0xbe1b3afe, 0x3dcc5820, 0xbe2882ac, 0x3e2b57ec, 0x3e358cf2, 0xbe54696c, 0xbd340870, 0x3e45d54a, 0x3c07b640, 0xbe567290, 0xbdc76b34, 0x3dddf448, }; // 2 uint32_t bias_vals[] = { 0x3c40ac50, 0xbdeac81f, }; // 1,3,2,2 uint32_t output_exp_vals[] = { 0xbed199d0, 0xbee4ca5f, 0xbe0febf4, 0xbe2b0406, 0xbefd7c85, 0xbe846eb2, 0xbef1750b, 0x3e52c1ce, 0xbeb43421, 0xbe83d2bf, 0xbeeeaca6, 0xbe243821, }; uint32_t clip_value = 0x3e4ccccd; // 1,3,2,2 uint32_t output_relu_exp_vals[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e4ccccd, 0x0, 0x0, 0x0, 0x0, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, VALID_PADDING, (void *)&clip_value); } void test_valid_padding_zero_strides_small() { input_set *set = &small_input; strides_input_set *strides = &zero_strides; // 1,4,3,5 uint32_t input_vals[] = { 0x3e83171a, 0x3f5ba100, 0x3f5727e7, 0x3ec9e104, 0x3f7090d1, 0x3f3c9175, 0x3ee5aee2, 0x3efe572a, 0x3e9832f2, 0x3e979464, 0x3ca6eaa0, 0x3f038eb2, 0x3e80c192, 0x3eceb0c4, 0x3f73959b, 0x3e5088c0, 0x3ee9ea48, 0x3def4bf8, 0x3ecdbc7c, 0x3f2e5b0e, 0x3ebfea62, 0x3f19e7a2, 0x3d036000, 0x3d523a30, 0x3d47c290, 0x3e834c8a, 0x3f516330, 0x3d9fbc50, 0x3d8bd6f0, 0x3f50fc3a, 0x3ea67152, 0x3f793f5d, 0x3ecc12e4, 0x3ed7f0f6, 0x3ee27582, 0x3db8b518, 0x3f514983, 0x3f46322b, 0x3f01a7c3, 0x3e8db848, 0x3ec98b80, 0x3f798662, 0x3f4533ba, 0x3e8bb4a4, 0x3f665b0a, 0x3f1b5c5f, 0x3eed7c54, 0x3c91afe0, 0x3f3037ae, 0x3dc482b0, 0x3e327314, 0x3d503cd0, 0x3f4fd817, 0x3d4cae30, 0x3f0dbc2b, 0x3ef2dcbc, 0x3e86a2e0, 0x3ddeb5d8, 0x3eeeb928, 0x3eca66d0, }; // 4,3,5,2 uint32_t kernel_vals[] = { 0xba7d6000, 0x3d6f4388, 0xbdfc970a, 0x3d4fd1fc, 0xbcaa76f8, 0x3cc5f330, 0xbd9a56a4, 0x3d840448, 0xbd6a842e, 0xbbe916f0, 0x3d8dd556, 0x3d54a8b0, 0xbdaf1ac2, 0x3ddb109a, 0x3c5fd070, 0xbcb22910, 0x3de34624, 0x3cdd5a80, 0xbb98a3f0, 0x3c9eca70, 0xbdd99c0c, 0xbd9c9d8d, 0xbd59fae2, 0x3de6143c, 0x3def676c, 0xbcae097c, 0x3d6bf4d8, 0xbdce4036, 0x3da918da, 0xbd588e5a, 0xbdc2943f, 0x3d1fc068, 0x3b9cb4e0, 0x3de94a92, 0xbdf545a3, 0xbd720ed0, 0x3d802534, 0xbd983e82, 0x3e036c17, 0x3d9ce2f0, 0xbd4baa92, 0x3d912554, 0x3d510cc0, 0x3cd27970, 0xbda67275, 0x3d4b5998, 0x3bde7ac0, 0x3df8bae2, 0x3d51de2c, 0xbda0e525, 0x3d0dcca0, 0xbc857c3c, 0x3d9ea4b8, 0xbde5e9f4, 0xbd05df20, 0xbd9c9a3c, 0xbd878d22, 0x3db2278e, 0x3c8edf30, 0x3defe79c, 0xbb27a200, 0x3ba18540, 0xbdb33ea4, 0x3c429450, 0xbd4e1f72, 0x3d41d9b0, 0x3cb2ed40, 0xbd6690fa, 0x3db14610, 0x3db530b8, 0x3dd1a2f4, 0x3cf50c00, 0xbd6644da, 0xbda56848, 0x3de47024, 0x3d85b500, 0xbdf6dd66, 0xbd0516b6, 0xbd9bad42, 0xbddef5da, 0xbc3bb558, 0x3da4065e, 0x3d4010e8, 0xbdf66796, 0xbdab603a, 0x3dbd45fa, 0xbdbf0b1b, 0xbdfbdce1, 0x3cc51300, 0xbd039b9e, 0x3d0becc0, 0x3dfddf06, 0x3ddb8d0c, 0x3deae9de, 0xbd736b86, 0x3d45b890, 0xbd884dcc, 0xbb1812c0, 0xbdccfcc7, 0x3bbee240, 0xbd1fcec2, 0xbdcbbfe1, 0xbcd9a694, 0x3dc9092c, 0xbdb8b7ae, 0xbe02d742, 0x3da6d138, 0xbdc71b02, 0xbdb73fbc, 0x3c9a4d70, 0xbccfe258, 0xbd41c938, 0x3dc5d9b2, 0xbe03defc, 0xbdf79f67, 0xbdab833c, 0x3d9b0552, 0xbdcbf180, 0xbd88951c, 0x3cfad4d8, }; // 2 uint32_t bias_vals[] = { 0x3d4f8340, 0x3bfd65c0, }; // 1,1,1,2 uint32_t output_exp_vals[] = { 0xbd56b2c9, 0x3dd5aea1, }; // 1,1,1,2 uint32_t output_relu_exp_vals[] = { 0x0, 0x3dd5aea1, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, VALID_PADDING, NULL); } void test_same_padding_non_zero_strides_small() { input_set *set = &small_input; strides_input_set *strides = &small_non0_strides; // 1,4,3,5 uint32_t input_vals[] = { 0x3f15a7d8, 0x3f55d27f, 0x3f04e322, 0x3f0bc669, 0x3f2eec77, 0x3d07cb10, 0x3e528880, 0x3f1da880, 0x3e3fb0a8, 0x3f40bb0b, 0x3e0e0bcc, 0x3f17da1f, 0x3f4f6880, 0x3d0b5ba0, 0x3f5ba1ae, 0x3e780c74, 0x3de61650, 0x3f7ae7a4, 0x3f71ba1f, 0x3f2fdc52, 0x3f50c293, 0x3e1d23d0, 0x3deae1a8, 0x3f615378, 0x3ba82d80, 0x3f4b0c93, 0x3e77825c, 0x3ea22f0a, 0x3aa20200, 0x3e33de00, 0x3e8e771c, 0x3f39eaa3, 0x3f324e26, 0x3f17f541, 0x3f3fe98e, 0x3ef6c34e, 0x3f3379fe, 0x3f6a0de8, 0x3ed4dfce, 0x3f1aca63, 0x3f51dd20, 0x3e50b72c, 0x3f6f62f4, 0x3ed5df52, 0x3de131a8, 0x3f7f3fc1, 0x3f26ab72, 0x3f70f111, 0x3e8ad072, 0x3e592e30, 0x3f32cd09, 0x3f4644b7, 0x3f19794f, 0x3f313923, 0x3f786a79, 0x3f114ab9, 0x3edfb038, 0x3d858c20, 0x3e50bd98, 0x3f563faa, }; // 2,2,5,2 uint32_t kernel_vals[] = { 0xbadb6d80, 0x3da65588, 0xbdb06154, 0xbd13a074, 0xbca28f68, 0xbe1025bd, 0xbe5abfd6, 0xbe146a76, 0x3db50ae0, 0xbe05a938, 0x3df5a9a0, 0x3e3e2300, 0x3d759a80, 0x3cc1d430, 0x3d725b60, 0xbd67df54, 0xbe17a51c, 0xbdd2ced4, 0x3e0963a4, 0x3e44d336, 0xbe3c7496, 0xbd3c7db4, 0xbb912ca0, 0x3e4f5476, 0xbd8a65c2, 0xbdb281f2, 0xbdbcc6b6, 0xbe1ff856, 0xbe1b3afe, 0x3dcc5820, 0xbe2882ac, 0x3e2b57ec, 0x3e358cf2, 0xbe54696c, 0xbd340870, 0x3e45d54a, 0x3c07b640, 0xbe567290, 0xbdc76b34, 0x3dddf448, }; // 2 uint32_t bias_vals[] = { 0x3c40ac50, 0xbdeac81f, }; // 1,4,3,2 uint32_t output_exp_vals[] = { 0xbed199d0, 0xbee4ca5f, 0xbe0febf4, 0xbe2b0406, 0xbe3aa069, 0xbeb5053e, 0xbefd7c85, 0xbe846eb2, 0xbef1750b, 0x3e52c1ce, 0xbe8b07f1, 0xbe848b7f, 0xbeb43421, 0xbe83d2bf, 0xbeeeaca6, 0xbe243821, 0xbeb92f25, 0xbe1d4e2d, 0x3db760f2, 0xbcdf50da, 0x3d4d4b44, 0xbe14cbd2, 0x3b1861e5, 0xbe6dd479, }; // 1,4,3,2 uint32_t output_relu_exp_vals[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e52c1ce, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3db760f2, 0x0, 0x3d4d4b44, 0x0, 0x3b1861e5, 0x0, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, SAME_PADDING, NULL); } void test_valid_padding_non_zero_strides_medium() { input_set *set = &medium_input; strides_input_set *strides = &medium_non0_strides; // 3,10,8,5 uint32_t input_vals[] = { 0x3f1c5cd1, 0x3f791683, 0x3f2c91ac, 0x3f4e9dfc, 0x3f7ea33e, 0x3ec54b8e, 0x3f1e4b8c, 0x3d5833b0, 0x3f0d60ae, 0x3f19e648, 0x3e83f3a8, 0x3c473900, 0x3f1d2739, 0x3f07625d, 0x3eeef18e, 0x3f1195d9, 0x3eb71e74, 0x3e3b6ac8, 0x3e6479c8, 0x3f7dff2d, 0x3f693fc2, 0x3e233e04, 0x3ee4515a, 0x3e949d42, 0x3e92990a, 0x3e25d8f0, 0x3f703971, 0x3f1076e9, 0x3eb52618, 0x3eeb7c5e, 0x3f05f190, 0x3ed5b900, 0x3f6d0c84, 0x3c53b800, 0x3e8fe576, 0x3ea19870, 0x3d353270, 0x3e85db72, 0x3f06a6e9, 0x3edca954, 0x3f7d9b72, 0x3eefe830, 0x3f52005d, 0x3f16a350, 0x3f1bd1c3, 0x3cd1dda0, 0x3f5062ba, 0x3edf7ab6, 0x3effc884, 0x3f11188a, 0x3ca952e0, 0x3f214124, 0x3e866b22, 0x3f2955c8, 0x3ecfa5e4, 0x3f7e2118, 0x3f287963, 0x3d844d18, 0x3f7973f3, 0x38a72000, 0x3e3c1010, 0x3f0be345, 0x3d28ec20, 0x3f22087d, 0x3f068ddb, 0x3f188a64, 0x3f2fb886, 0x3f7d0194, 0x3ea24914, 0x3ef86ab2, 0x3ee9e7d8, 0x3ec1a006, 0x3ec0275a, 0x3e96a4e0, 0x3f134183, 0x3eca1262, 0x3e9a29c4, 0x3f0664b9, 0x3e386b68, 0x3f62147d, 0x3ec6d2ae, 0x3d05b790, 0x3f22b3cf, 0x3e1d126c, 0x3f7c6ace, 0x3f51561e, 0x3dfc9540, 0x3f570177, 0x3ed6c570, 0x3e503d48, 0x3f061e36, 0x3f3779bc, 0x3f6d3ea4, 0x3ed2b8f0, 0x3ef0098a, 0x3c582640, 0x3e50d684, 0x3f67cf69, 0x3f38f141, 0x3e996d74, 0x3e51bc50, 0x3f125d1c, 0x3e04aaf8, 0x3e929380, 0x3d207840, 0x3ea8bac2, 0x3f28db44, 0x3ed6fc08, 0x3f660ac5, 0x3e0b7044, 0x3f406965, 0x3f09101a, 0x3e5107c4, 0x3e18bd60, 0x3f7822c5, 0x3e34aae4, 0x3e340b80, 0x3e5b77c8, 0x3f005d22, 0x3f4aa1bf, 0x3f78b197, 0x3f7a68f8, 0x3f1e5ccd, 0x3f730fcf, 0x3f44c15e, 0x3ec6fb36, 0x3e5645b4, 0x3f78259e, 0x3f7f4803, 0x3f472298, 0x3ed2083a, 0x3f6947b3, 0x3dcbab68, 0x3e576af0, 0x3dd27418, 0x3f644ba1, 0x3dd16648, 0x3f4d7757, 0x3f16ccee, 0x3f0d7145, 0x3f405573, 0x3ec26b6a, 0x3e768b88, 0x3f0f1ea5, 0x3f7721a8, 0x3f6c8f35, 0x3f45a0c5, 0x3ece2346, 0x3e87f956, 0x3e624290, 0x3f4a0a77, 0x3e976742, 0x3f659a49, 0x3ea78da6, 0x3f71de3a, 0x3eb25766, 0x3f6b8687, 0x3ec619b4, 0x3f22ab58, 0x3f21a4b1, 0x3e2c4d58, 0x3e1fa9f4, 0x3f0ba7b7, 0x3e1bf918, 0x3f5a0db7, 0x3eecf3ec, 0x3da412f0, 0x3e1a1868, 0x3f151e94, 0x3e925530, 0x3f69f007, 0x3e8c9090, 0x3f6cf576, 0x3f376386, 0x3f3b02a1, 0x3eaa14d2, 0x3f14b0f6, 0x3edee82c, 0x3e9b1e38, 0x3d687920, 0x3d14bf10, 0x3f75db54, 0x3e098730, 0x3f6a5273, 0x3eefbec2, 0x3f347889, 0x3e85c90e, 0x3f257acf, 0x3eef270c, 0x3f2ab1ce, 0x3f7c9ab6, 0x3f2dc6c3, 0x3e13f588, 0x3f3a1342, 0x3f2662f1, 0x3eb71f00, 0x3ebfd1aa, 0x3dd372d0, 0x3f7ec25c, 0x3f6b1c87, 0x3db01a98, 0x3ec87bb6, 0x3f07cc33, 0x3eb1bfb8, 0x3f7dc7b5, 0x3d3e5780, 0x3f5e1e6c, 0x3f657be6, 0x3f458e66, 0x3f7472eb, 0x3f2013a4, 0x3de66a18, 0x3eb78e5c, 0x3eb6c6ca, 0x3f55f02e, 0x3eec9da2, 0x3f0d9866, 0x3f3c3ed0, 0x3eda9af6, 0x3f59fdf0, 0x3e7d7250, 0x3f785f54, 0x3f6dfe3d, 0x3ed49d8a, 0x3edef7e8, 0x3f19df75, 0x3edcd28e, 0x3f54e5bc, 0x3efe68da, 0x3de553f8, 0x3f309bf0, 0x3f636253, 0x3e736cbc, 0x3e9f4a92, 0x3ea0f742, 0x3f65cd03, 0x3eb129be, 0x3ee3eff4, 0x3f1e0064, 0x3ee342a2, 0x3f63607e, 0x3f670900, 0x3eaf70d0, 0x3f04d2b6, 0x3e6b5274, 0x3ed9ae54, 0x3c85d0a0, 0x3dc89400, 0x3f51234d, 0x3f416e0c, 0x3d722410, 0x3edb1ab6, 0x3f000d8a, 0x3ecc2f2a, 0x3f2cee76, 0x3d456140, 0x3ed308d6, 0x3f604fcb, 0x3f0cd5fb, 0x3f14a72e, 0x3f778324, 0x3f297b9e, 0x3f6bd78d, 0x3ea0c53e, 0x3f1eeb76, 0x3f389544, 0x3f3237c9, 0x3f0bf147, 0x3da67288, 0x3f707120, 0x3f37cbd0, 0x3f6247d3, 0x3f1d125e, 0x3f33cc23, 0x3f2e9f22, 0x3d8a0380, 0x3ed9dc0e, 0x3e912c0c, 0x3f1060ed, 0x3d7c0730, 0x3f7687af, 0x3ef5d92a, 0x3f609ead, 0x3e9979e6, 0x3e0c595c, 0x3f79428a, 0x3f57a7e5, 0x3e9579ea, 0x3ea971f4, 0x3f386a7c, 0x3f7390ed, 0x3ebabbb8, 0x3e1c5678, 0x3f217988, 0x3f117199, 0x3da02b40, 0x3f703588, 0x3f13b60f, 0x3ed1b5fc, 0x3f3e6cae, 0x3e9f67bc, 0x3e2b1aac, 0x3f4cb8a9, 0x3f53a519, 0x3a27c800, 0x3e1fdd6c, 0x3ee44c5c, 0x3d498a60, 0x3f074015, 0x3d1df6b0, 0x3f79362b, 0x3ef24000, 0x3f73b535, 0x3f3059ad, 0x3f4e7e34, 0x3e92007e, 0x3f391d68, 0x3f2e0bab, 0x3f37c4e5, 0x3f51dfe9, 0x3e8b1f3e, 0x3f5782b3, 0x3e194948, 0x3ec12fac, 0x3d4326e0, 0x3f430f94, 0x3ed76c4c, 0x3ec8db0e, 0x3f376190, 0x3f309640, 0x3e89938c, 0x3dafa2c8, 0x3f6f0cdc, 0x3f5e7499, 0x3de06a60, 0x3e81ea12, 0x3f3f6c4a, 0x3dee5a08, 0x3f05e3ee, 0x3f60ef76, 0x3ee99b78, 0x3f2649f3, 0x3eb52d52, 0x3f190c77, 0x3f282a49, 0x3ee764b6, 0x3f336ae2, 0x3f29fb42, 0x3f04a6a5, 0x3f7e9092, 0x3de25378, 0x3e4429ec, 0x3d7dc720, 0x3f589f7f, 0x3be58200, 0x3f6ab5a3, 0x3f526157, 0x3f462b5c, 0x3e93eb02, 0x3c98e0e0, 0x3e8f12a6, 0x3f793c60, 0x3f42a14e, 0x3e6fd614, 0x3f568a83, 0x3f2d674c, 0x3f0b1b53, 0x3f4f62e5, 0x3f37c6c6, 0x3f71a430, 0x3f6f5512, 0x3d0711a0, 0x3e39936c, 0x3d84cc60, 0x3f4e6c4c, 0x3f408d71, 0x3f59dace, 0x3f7f7cf6, 0x3f020d5a, 0x3f551925, 0x3f121f4a, 0x3e046080, 0x3e508190, 0x3e8a4494, 0x3da183a0, 0x3f6ce8e2, 0x3f1d6c73, 0x3f7fc99f, 0x3f547bfb, 0x3f5ca5ed, 0x3f1134e1, 0x3f1299c6, 0x3ca51ba0, 0x3d0d3b60, 0x3ce4c600, 0x3e898f56, 0x3e882ec2, 0x3d5f4b20, 0x3f4d9c4e, 0x3f1c986d, 0x3e309f48, 0x3e4020c8, 0x3eccd314, 0x3e98f244, 0x3f0d6465, 0x3e9a5166, 0x3e56e3c8, 0x3f64e98c, 0x3f676a36, 0x3f6d4529, 0x3f16aa31, 0x3f389366, 0x3f5e765d, 0x3c59d440, 0x3e0b9e44, 0x3e9b588e, 0x3eee1028, 0x3e24fd00, 0x3e396a8c, 0x3f29ffd0, 0x3ed77eb4, 0x3ce35560, 0x3f3b759d, 0x3dbee238, 0x3f388f70, 0x3cd5b620, 0x3e58c9d8, 0x3ddccad0, 0x3ed136da, 0x3f218c2b, 0x3ce9fdc0, 0x3f33e880, 0x3d983f38, 0x3f63bf3b, 0x3f7f446e, 0x3f31951d, 0x3ea92bc8, 0x3f272096, 0x3f703270, 0x3f68cdc5, 0x3e93a406, 0x3f58596d, 0x3f01e193, 0x3d848d28, 0x3f6dd176, 0x3e488128, 0x3f653069, 0x3e88930a, 0x3ef4e888, 0x3ee01726, 0x3e9afca8, 0x3f129ec2, 0x3c916480, 0x3f4b21b5, 0x3f6b5aef, 0x3dbacf50, 0x3eebc1c2, 0x3e9ce4a6, 0x3f386c0d, 0x3d0b7160, 0x3dcd6a08, 0x3eaebd18, 0x3f2ac07f, 0x3f68d865, 0x3e6bb5b4, 0x3f4c9777, 0x3ef30e1e, 0x3d185e40, 0x3ef8e626, 0x3ec93f16, 0x3f410e14, 0x3f174c76, 0x3c69c140, 0x3e27fdac, 0x3eb3f416, 0x3f110cd0, 0x3df1d108, 0x3f103d5c, 0x3f54ad08, 0x3f763ba1, 0x3e6850a8, 0x3ec2d12e, 0x3e0f2730, 0x3ea836c0, 0x3f3c5f87, 0x3f2a95f2, 0x3dac3c60, 0x3d7dc9a0, 0x3f4246d1, 0x3f526877, 0x3f05c01c, 0x3f4e8f85, 0x3e9d5de2, 0x3ec0e98a, 0x3f57111a, 0x3e121668, 0x3e39f098, 0x3ed6c8a6, 0x3f36697c, 0x3e0188c0, 0x3f1b8b57, 0x3f74ef01, 0x3d3af8c0, 0x3f732064, 0x3ee2598e, 0x3f748cb4, 0x3ebe0214, 0x3e2a1f98, 0x3f770581, 0x3f12b0ef, 0x3c064c00, 0x3e5ab018, 0x3f086487, 0x3d382fd0, 0x3f214ab6, 0x3b37c200, 0x3f3d7f7d, 0x3ce99680, 0x3e2d5274, 0x3f41d260, 0x3f106666, 0x3f131506, 0x3edc04a0, 0x3e96270a, 0x3e9a22c8, 0x3f606309, 0x3f58a266, 0x3e356674, 0x3e397f40, 0x3eb2cea4, 0x3e487408, 0x3f356fa6, 0x3e1d1000, 0x3f7ad0e6, 0x3f6b1a57, 0x3f1c2d74, 0x3c962960, 0x3f324ed7, 0x3ee963f0, 0x3ebb4b2a, 0x3f59fb6c, 0x3f50f572, 0x3debd678, 0x3e2c5ea0, 0x3e1c57f8, 0x3f2776e9, 0x3ecfcaaa, 0x3df7fa50, 0x3e8e152c, 0x3f56ca02, 0x3f1bb359, 0x3e8edafc, 0x3f48fefc, 0x3e653078, 0x3f56ad08, 0x3f7fb57c, 0x3f514972, 0x3f17ee83, 0x3f3438ff, 0x3eafba14, 0x3f536375, 0x3f5d5ab2, 0x3f74923d, 0x3d82d098, 0x3eccd20a, 0x3e600990, 0x3d77f330, 0x3ebb9286, 0x3d0a7040, 0x3e063498, 0x3f0b105a, 0x3ee8da04, 0x3e845920, 0x3be94a00, 0x3da8dd30, 0x3f416444, 0x3f691d4c, 0x3ee84ee0, 0x3f371b6a, 0x3f302264, 0x3f70e269, 0x3f31929d, 0x3f00a5c9, 0x3f3f4a4a, 0x3e92a382, 0x3b260a00, 0x3f6bd609, 0x3f619e54, 0x3e4201ec, 0x3f65e675, 0x3f45500c, 0x3ea844e6, 0x3b007400, 0x3f1fbdc3, 0x3dcc11d8, 0x3eb5acd0, 0x3e658f20, 0x3eedc5ca, 0x3f5e7cd6, 0x3edc9d48, 0x3c2a3840, 0x3f6e1185, 0x3f389eff, 0x3f12993c, 0x3f02c385, 0x3f1c69a5, 0x3f355a74, 0x3e660ce0, 0x3ec9d5ca, 0x3f41c905, 0x3e69429c, 0x3f7ae0b5, 0x3e7bd4f8, 0x3f0974fa, 0x3f679826, 0x3f1223a0, 0x3e9511d6, 0x3f3ddbb8, 0x3ee48cba, 0x3f56aea3, 0x3e3395e8, 0x3e374304, 0x3cab4600, 0x3f4072a9, 0x3f385858, 0x3dfd6908, 0x3ee1fe56, 0x3f1e5491, 0x3e2458a0, 0x3e8a7f62, 0x3eea4734, 0x3cef49e0, 0x3de73ba8, 0x3f40e8bc, 0x3e125b3c, 0x3eaa00c6, 0x3f322c3e, 0x3f3f9fb9, 0x3f4824d1, 0x3d57d540, 0x3f4adcd9, 0x3f5e694c, 0x3d947048, 0x3e49cacc, 0x3f065972, 0x3f0b0932, 0x3f1eba2f, 0x3f4eb1ec, 0x3f688528, 0x3f7c2509, 0x3f63e958, 0x3ee6b498, 0x3cda97c0, 0x3f7db83b, 0x3ecf5fee, 0x3f17fcd2, 0x3f3f7695, 0x3da34278, 0x3e9b13d4, 0x3ef53908, 0x3eadae28, 0x3e3b01e0, 0x3f01e2e6, 0x3eb84bbc, 0x3e0beec4, 0x3f56b2de, 0x3f7d3712, 0x3f64dcce, 0x3f3fca1d, 0x3f274c18, 0x3f06fe9c, 0x3b395900, 0x3d930d08, 0x3dddc708, 0x3f51265e, 0x3f180648, 0x3cac41a0, 0x3e8dcf08, 0x3f329e5e, 0x3be6c100, 0x3eadaa24, 0x3ec381bc, 0x3f706b90, 0x3f1ddcee, 0x3e177d4c, 0x3f007599, 0x3f688e5c, 0x3ed511c8, 0x3f50aea5, 0x3f5ecf83, 0x3ecec730, 0x3f0cd0ec, 0x3f350747, 0x3d868bf0, 0x3f1e4e4d, 0x3eea3c4e, 0x3f312869, 0x3c9ba7c0, 0x3dad46c0, 0x3ef00a16, 0x3de16750, 0x3e08b354, 0x3eaf7e2e, 0x3f397d10, 0x3f16e18d, 0x3efe6cf6, 0x3f2eae06, 0x3e7bfd6c, 0x3f2e1b63, 0x3ed913c8, 0x3dae08e0, 0x3ee364c8, 0x3f6be96e, 0x3d0dca70, 0x3e1a2144, 0x3ec8ed30, 0x3f334e30, 0x3f352007, 0x3e627a74, 0x3d0649a0, 0x3f4a2e92, 0x3f5a6628, 0x3e0a67f4, 0x3d2e1fc0, 0x3f542fc6, 0x3e1bfb0c, 0x3f37a39a, 0x3f14a316, 0x3e113104, 0x3ee18d5e, 0x3e26e2b0, 0x3eea393c, 0x3efd0ec4, 0x3e8c7e2e, 0x3ea0ecc4, 0x3ec17da6, 0x3ef03b0a, 0x3e96d13c, 0x3f69ecc8, 0x3ebdec2a, 0x3eb9d25a, 0x3e3ee23c, 0x3e5b9bd8, 0x3ecd0b00, 0x3e68be50, 0x3f15ab36, 0x3ea3677e, 0x3eab0ca0, 0x3f498457, 0x3eb42d54, 0x3f154000, 0x3f532de5, 0x3f64e49b, 0x3f798f25, 0x3d90fbd0, 0x3f40e88a, 0x3e99584a, 0x3e10f8bc, 0x3f3a556f, 0x3f5fc9b9, 0x3e1f4b0c, 0x3f4f7e3b, 0x3e1347bc, 0x3d569bf0, 0x3f344491, 0x3eedef0c, 0x3e9a7ce2, 0x3eb104e4, 0x3f40699a, 0x3e7dc994, 0x3f4796db, 0x3ec460be, 0x3f023a0b, 0x3f30d2d9, 0x3ea89fb2, 0x3f6eb763, 0x3f02b960, 0x3f22d7d7, 0x3f633559, 0x3f396cf4, 0x3eed5372, 0x3d289f00, 0x3f03d74e, 0x3bde4300, 0x3ea133aa, 0x3e57bf18, 0x3efd71a0, 0x3ec25fce, 0x3f4eb8d8, 0x3f21c0b7, 0x3f24cb93, 0x3ee63240, 0x3e498c78, 0x3f68c5f7, 0x3f233e64, 0x3f48e4a2, 0x3ee9007c, 0x3ed210b4, 0x3d0e9cf0, 0x3e3db310, 0x3f20106f, 0x3ddc15d8, 0x3ddf9fd8, 0x3f172511, 0x3e343374, 0x3f07d4e2, 0x3e8eb102, 0x3f2c11d2, 0x3df2d818, 0x3f1c0428, 0x3f6fcb0b, 0x3e886f24, 0x3e9f92a4, 0x3f39de65, 0x3f4f3400, 0x3ea35fc4, 0x3b975a80, 0x3e944572, 0x3f2fd65e, 0x3eadc1a8, 0x3ebe30c2, 0x3f0c351c, 0x3eca9b2c, 0x3edfe3ae, 0x3f3de46d, 0x3f6e48ee, 0x3f5741c0, 0x3ea13e1e, 0x3db148e8, 0x3e42e970, 0x3dbbcc98, 0x3f33f355, 0x3f46238f, 0x3f333266, 0x3f7a7ccd, 0x3f093f70, 0x3e865db0, 0x3ecf5c38, 0x3f53867b, 0x3f5b34a5, 0x3f7b540b, 0x3d276490, 0x3f610d47, 0x3ed3393c, 0x3f17f9af, 0x3e8d37c2, 0x3dc5dc40, 0x3f1d351b, 0x3f3c54cb, 0x3f38f23d, 0x3f7ab619, 0x3f025fd2, 0x3ed871b0, 0x3f2f71c2, 0x3f2c9067, 0x3f719461, 0x3f580d8b, 0x3e5844e4, 0x3e999bba, 0x3e51dec8, 0x3f77155f, 0x3e9853b8, 0x3d2cb3a0, 0x3eee3a78, 0x3efdc488, 0x3ee7925a, 0x3e6965d4, 0x3eb551b0, 0x3f7f6a87, 0x3f2221ee, 0x3f73cb06, 0x3e6edecc, 0x3d177cc0, 0x3f009ab3, 0x3ec63798, 0x3e9074b2, 0x3ee9d6a2, 0x3ed0921a, 0x3dd0c7a0, 0x3f7abeb9, 0x3ea85eb0, 0x3cce36e0, 0x3f021792, 0x3eed5492, 0x3e9d46ee, 0x3f3069ed, 0x3d70c0f0, 0x3eef809c, 0x3f3fadd7, 0x3d5afe50, 0x3f1b0a26, 0x3f7e0083, 0x3e823f9c, 0x3eac6f80, 0x3e861fe0, 0x3f469033, 0x3e85e8d4, 0x3f58d714, 0x3e73dfc0, 0x3d134840, 0x3f79a410, 0x3ed1d3b0, 0x3f481647, 0x3f697191, 0x3f697a69, 0x3e3f7e5c, 0x3ebb81aa, 0x3ec0ed6e, 0x3f43b6a8, 0x3e8d1448, 0x3f43eeda, 0x3d78d1c0, 0x3e9ada58, 0x3ed481e6, 0x3e17c540, 0x3f2ad303, 0x3ed2de74, 0x3f5078eb, 0x3f068a15, 0x3ee453a4, 0x3f43875a, 0x3f272ed5, 0x3f6f5cf5, 0x3ee4ecbc, 0x3e270294, 0x3f3cb1ae, 0x3e980c9c, 0x3d2cc5b0, 0x3f1db79a, 0x3e748b78, 0x3ea03cf4, 0x3ef516de, 0x3ec8b058, 0x3f048c8f, 0x3f414175, 0x3dd6ace8, 0x3efec682, 0x3ee83e1e, 0x3e4a2bc0, 0x3dff2f70, 0x3f667302, 0x3b134c00, 0x3ea34ffa, 0x3f17b711, 0x3f3c5d23, 0x3e5c0a14, 0x3f5d050b, 0x3f6d4657, 0x3f03590a, 0x3f5d57b0, 0x3f51d579, 0x3f676519, 0x3eda2f96, 0x3f084691, 0x3eff6d00, 0x3cc1f8e0, 0x3f574567, 0x3f6c864d, 0x3e9e7106, 0x3f38d631, 0x3ed3b61e, 0x3eabee16, 0x3f00a1fe, 0x3f20cbe7, 0x3e6132e4, 0x3f015b4e, 0x3f42e35a, 0x3ee43b3a, 0x3dc3f248, 0x3f63d109, 0x3f1625a3, 0x3d012ed0, 0x3e55597c, 0x3f26431d, 0x3f7c5832, 0x3f0a58b4, 0x3ec0ab44, 0x3eaae0dc, 0x3f455cc3, 0x3f1e6ae1, 0x3f285567, 0x3ecbef02, 0x3f293ed2, 0x3ee3d38e, 0x3f74a4b0, 0x3ee37eec, 0x3ea597fc, 0x3f389e84, 0x3de48e80, 0x3b5ff100, 0x3f1f5907, 0x3f35c290, 0x3ef6e438, 0x3eff11c4, 0x3ee3e418, 0x3f7eaab3, 0x3e8b5a02, 0x3f79f6c1, 0x3f002e84, 0x3f196ec6, 0x3e34b598, 0x3ee25420, 0x3e1da0c4, 0x3d8b0de8, 0x3d85f3e0, 0x3ef205f2, 0x3eb61442, 0x3f3113b1, 0x3e15dd68, 0x3f3e49f3, 0x3e9e4766, 0x3cf98420, 0x3f734957, 0x3f766464, 0x3e9e6f48, 0x3f704f9d, 0x3ed5b958, 0x3ed37c72, 0x3f5fb886, 0x3ea368c6, 0x3f6d92b7, 0x3d9c2f30, 0x3f659ed0, 0x3f46f020, 0x3dd38b30, 0x3ef904e2, 0x3f4aa328, 0x3f021c29, 0x3f58ac51, 0x3f345424, 0x3ea74316, 0x3f446948, 0x3e009768, 0x3f314677, 0x3e0b7478, 0x3e43a70c, 0x3f77e8cd, 0x3e671bc0, 0x3f480976, 0x3ec9ace4, 0x3f5b96cd, 0x3eaa08d4, 0x3f2fa4c2, 0x3f54c6f5, 0x3f38dc93, 0x3eee5ef4, 0x3f068253, 0x3e91375e, 0x3ec4324a, 0x3f606da6, 0x3f788d37, 0x3f1912f2, 0x3f1ec911, 0x3edf74ee, 0x3f1cf1ac, 0x3f48fe58, 0x3f7fc5a0, 0x3f7dfc14, 0x3f5b451b, 0x3ea08046, 0x3f7009fb, 0x3f755397, 0x3f2b7aa6, 0x3effe866, 0x3e90a61c, 0x3f653cfc, 0x3e770510, 0x3ee80a80, 0x3e32d938, 0x3f47d81d, 0x3e3347e0, 0x3d98acf8, 0x3f1ffe86, 0x3de5fdd8, 0x3f17bfb3, 0x3f257744, 0x3d4a2960, 0x3e5903b0, 0x3f479656, 0x3f6bc03c, 0x3e95d8ea, 0x3e84b880, 0x3da394b0, 0x3f6a065f, 0x3f3033f8, 0x3f403973, 0x3f6b9ee5, 0x3dfe4278, 0x3f636808, 0x3f671d51, 0x3ee8fbac, 0x3f2afd1f, 0x3da4c250, 0x3f154d38, 0x3dc6da18, 0x3f0b14b9, 0x3f7b804f, 0x3f1a44a2, 0x3f585b1d, 0x3f66e71d, 0x3e1de574, 0x3f5ee053, 0x3f18eea8, 0x3d27a9c0, 0x3e8a6136, 0x3d59a660, 0x3f01db0f, 0x3e93354c, 0x3e0f1f7c, 0x3ebb7906, 0x3f30338b, 0x3e42accc, 0x3c32fd80, 0x3c9ab440, 0x3f00c421, 0x3f1dbece, 0x3f7cfdf9, 0x3f455695, 0x3f6720ba, 0x3ecffdea, 0x3f0b1e52, 0x3f66ad8c, 0x3e5d7c88, 0x3efdaefe, 0x3f1951b3, 0x3f56efd9, 0x3f376aad, 0x3ed542ea, 0x3e8a1efc, 0x3f720f76, 0x3e9519d8, 0x3e685028, 0x3da56500, 0x3f2b4fd1, 0x3e4e166c, 0x3f2d7003, 0x3f64d5f4, 0x3e5f26a8, 0x3ea02bb8, 0x3f278ce4, 0x3e660294, 0x3f0ba669, 0x3f35657f, 0x3e37a1bc, 0x3dc901c0, 0x3f1a8587, 0x3f54a350, 0x3d0bd2c0, 0x3f315e90, 0x3f141915, 0x3ec58e3a, 0x3f356c46, 0x3e5c098c, 0x3f176fc8, 0x3f6972a7, 0x3f59a44e, 0x3f43f815, 0x3f5ff729, 0x3e1158ec, 0x3f564eea, 0x3f6fef0b, 0x3d7aede0, 0x3e796be4, 0x3e2ec3dc, 0x3f6d9d4a, 0x3f6f2bc9, 0x3e641b0c, 0x3e9576ce, 0x3f3c03ec, 0x3f454a1d, 0x3f05c20b, 0x3f4cc550, 0x3eb81f36, 0x3f615407, 0x3eead1e2, 0x3f4b7b10, 0x3ecaaa80, 0x3f36b6fb, 0x3f0a6b8c, 0x3f216b9d, 0x39e1e000, 0x3d852408, 0x3e3024c0, 0x3e7ed480, 0x3e95077a, 0x3e53a9ec, 0x3f746732, 0x3f0cd57f, 0x3f3dced4, 0x3f6ca63a, 0x3f16e067, 0x3efa76c0, 0x3f34468a, 0x3f1652eb, 0x3f401718, 0x3f00b6bf, 0x3f67416b, 0x3eed6a88, 0x3d7f04b0, 0x3e0941c8, }; // 2,3,5,5 uint32_t kernel_vals[] = { 0x3dc1ef2c, 0xbd4afe40, 0xbd9592c5, 0xbe1fade9, 0x3d6c2508, 0xbdd2c720, 0x3c195110, 0x3e39d55a, 0xbe19fe5a, 0xbd4f7cb8, 0xbdd860aa, 0xbd9f8af7, 0xbe15e820, 0x3bc06080, 0x3dd8b200, 0x3d98e864, 0xbdf9352c, 0x3d6e6124, 0x3e1ce872, 0xbddbdef8, 0xbdd473e1, 0xbe33b833, 0x3da421b8, 0xbe2d2c6b, 0x3e3aa2e4, 0x3de87114, 0xbd1046d8, 0x3d5b0694, 0x3dae7864, 0x3d990464, 0xbdd1cee5, 0x3db34934, 0x3dbce7a4, 0x3dc31f58, 0xbd8b648c, 0x3e107fd2, 0x3d86b7ce, 0xbd57180c, 0xbd6735f0, 0xbc94cfe0, 0xbe0ded40, 0xbd85f78e, 0x3dc8b7ec, 0xbca29f38, 0xbdbdcb4e, 0xbcea63b0, 0xbe35a862, 0x3e3869a6, 0x3e03dc16, 0x3e369824, 0xbd82ddc2, 0x3c8f2268, 0x3c086970, 0xbdd3ca16, 0xbd5cfa1c, 0xbe0fdbe9, 0x3db979b0, 0xbdf6cec4, 0xbc986630, 0x3d3c4390, 0x3def1cd0, 0xbe04c359, 0xbe379160, 0xbd2299c0, 0x3d639694, 0x3e32eeae, 0x3d234c44, 0x3cd05b90, 0xbe1ca8af, 0x3e2bd088, 0x3e1ebe9a, 0xbd17b4c0, 0x3dd7029c, 0x3dbb63b0, 0xbe0cffec, 0x3db369c8, 0x3e2ce704, 0xbe2894ee, 0x3db3e32c, 0x3d7a42f8, 0x3dfb04b8, 0xbe2addc3, 0x3e1c07c8, 0x3e0fe1ac, 0x3d849fca, 0x3c5e5ae0, 0x3d8afe3c, 0xbd91a2ca, 0x3cc6c5c0, 0xbd345d88, 0x3e0df82e, 0xbe0e8518, 0xbdfa2da2, 0xbdca4ed7, 0xbd493a3c, 0x3bf73200, 0x3dfb6e40, 0xbca86c80, 0x3ddd534c, 0xbe178f40, 0x3cabdc18, 0x3c2027b0, 0x3e1b0c4a, 0xbe03fa6d, 0xbd5728b0, 0x3e04e9ae, 0xbd05d144, 0x3c20c3f0, 0x3de76758, 0xbdb6aeca, 0xbdb0897a, 0x3e1eaf24, 0x3d215434, 0x3db95a08, 0x3d830e56, 0xbd884998, 0x3db9c368, 0xbe10f35d, 0x3e256c04, 0xba02ad00, 0xbe0437fa, 0xbe30f32c, 0x3d831984, 0x3e1e4382, 0xbe0db618, 0xbd3297e4, 0xbde6de41, 0x3dc95498, 0xbdb933e1, 0x3de72ce0, 0xbcaa3940, 0xbe0aef70, 0x3db150b0, 0x3dcee6c0, 0x3c843678, 0x3e2bd24c, 0x3c4431b0, 0xbe12ca69, 0xbe02fabe, 0xbe076e08, 0x3dd23240, 0xbe29bb4c, 0xbd66b750, 0x3e2af9f0, 0xbdb5289e, 0xbd79f286, 0x3e1b6538, 0xbe376a62, 0xbdc9851c, 0xba66d200, }; // 5 uint32_t bias_vals[] = { 0xbd3e9f8c, 0xbdf4be10, 0xbd861c9e, 0x3d0d4978, 0xbdc35d93, }; // 3,5,2,5 uint32_t output_exp_vals[] = { 0x3e3eb29f, 0xbf2431cf, 0xbd3c2cb9, 0x3ec9941a, 0xbe019504, 0x3ed55520, 0xbf268f78, 0xbeb25c44, 0xbbc1b02b, 0x3d9680fc, 0x3e5a57a9, 0xbf0861e9, 0xbe980c59, 0x3ec9af1f, 0x3e057cc4, 0x3c397765, 0xbec5d321, 0xbe7106e9, 0x3e6b25bf, 0xbe162702, 0x3d285bae, 0xbee24ed1, 0xbe5f61c6, 0x3e6d9bf1, 0xbe21e5ce, 0x3e2257db, 0xbeae2fd2, 0x3d2453d3, 0x3ec62915, 0xbee4c828, 0x3e58d564, 0xbf232884, 0x3e1c46c1, 0x3e3baa73, 0xbded1d5b, 0x3e09ce53, 0xbeebf081, 0x3dae4215, 0x3f12fb01, 0xbd9626b6, 0x3de73a84, 0xbec044c7, 0x3e517516, 0x3e892149, 0xbd851637, 0x3eb5d71c, 0xbf076e93, 0x3c6657e7, 0x3d81414f, 0xbe3d5ca7, 0x3c279fa2, 0xbf1065b3, 0xbe00250d, 0x3efef655, 0xbe071035, 0x3e3a4085, 0xbf0e87c2, 0x3db127ea, 0x3e4d846b, 0x3e1ecce4, 0x3e3107ba, 0xbf23824b, 0x3e269cf3, 0x3e95ad70, 0xbe098bb7, 0x3dec94ee, 0xbe65fde6, 0x3db798b1, 0x3db34030, 0xbe7429ad, 0xbbee7768, 0xbf19b3e7, 0xbe166291, 0x3d948b67, 0xbe4f7ce2, 0x3e108942, 0xbeea1e35, 0xbe3bb4b7, 0x3e84725a, 0xbea914ea, 0x3e041cec, 0xbed55994, 0x3e31f984, 0xbd3233e6, 0xbe1658bb, 0x3e09a5ee, 0xbee9f260, 0xbde464c0, 0x3de69ade, 0xbd79033a, 0x3d9a3ba7, 0xbef017f5, 0x3df0f795, 0x3d436760, 0xbcb32c93, 0x3ec1bc0a, 0xbec3a50b, 0xbe3b3a62, 0x3e0529ee, 0xbe5c712e, 0x3eab528d, 0xbe7880c5, 0xbe7cc267, 0x3e9789ef, 0xbe1f75ee, 0x3dfd3bff, 0xbf0529de, 0xbdb2af09, 0x3ebbc0cb, 0xbe1f469c, 0x3e29a963, 0xbe893841, 0xbec59110, 0x3e03a680, 0xbe0fe3fc, 0x3e4ab203, 0xbf1040a7, 0xbd4d9423, 0x3de26c26, 0xbd11f7e5, 0x3ec20296, 0xbf17732c, 0x3e541b46, 0x3eb4273c, 0xbe80ea72, 0x3e6f3363, 0xbf060cb4, 0xbe42defb, 0x3e723a44, 0x3d6ffd66, 0x3e162cfb, 0xbf6b8da8, 0x3d56a599, 0x3eb102a0, 0xbe420cb5, 0x3eb0a5be, 0xbef142c6, 0x3d937133, 0x3ea7bcdf, 0xbeb35b92, 0x3d8e0431, 0xbed46437, 0x3e651ef5, 0x3eae0d1e, 0xbdd41583, 0x3e4231b1, 0xbe3b758c, 0xbe89c7f5, 0xbd5ab5c6, 0xbe467e60, }; // 3,5,2,5 uint32_t output_relu_exp_vals[] = { 0x3e3eb29f, 0x0, 0x0, 0x3ec9941a, 0x0, 0x3ed55520, 0x0, 0x0, 0x0, 0x3d9680fc, 0x3e5a57a9, 0x0, 0x0, 0x3ec9af1f, 0x3e057cc4, 0x3c397765, 0x0, 0x0, 0x3e6b25bf, 0x0, 0x3d285bae, 0x0, 0x0, 0x3e6d9bf1, 0x0, 0x3e2257db, 0x0, 0x3d2453d3, 0x3ec62915, 0x0, 0x3e58d564, 0x0, 0x3e1c46c1, 0x3e3baa73, 0x0, 0x3e09ce53, 0x0, 0x3dae4215, 0x3f12fb01, 0x0, 0x3de73a84, 0x0, 0x3e517516, 0x3e892149, 0x0, 0x3eb5d71c, 0x0, 0x3c6657e7, 0x3d81414f, 0x0, 0x3c279fa2, 0x0, 0x0, 0x3efef655, 0x0, 0x3e3a4085, 0x0, 0x3db127ea, 0x3e4d846b, 0x3e1ecce4, 0x3e3107ba, 0x0, 0x3e269cf3, 0x3e95ad70, 0x0, 0x3dec94ee, 0x0, 0x3db798b1, 0x3db34030, 0x0, 0x0, 0x0, 0x0, 0x3d948b67, 0x0, 0x3e108942, 0x0, 0x0, 0x3e84725a, 0x0, 0x3e041cec, 0x0, 0x3e31f984, 0x0, 0x0, 0x3e09a5ee, 0x0, 0x0, 0x3de69ade, 0x0, 0x3d9a3ba7, 0x0, 0x3df0f795, 0x3d436760, 0x0, 0x3ec1bc0a, 0x0, 0x0, 0x3e0529ee, 0x0, 0x3eab528d, 0x0, 0x0, 0x3e9789ef, 0x0, 0x3dfd3bff, 0x0, 0x0, 0x3ebbc0cb, 0x0, 0x3e29a963, 0x0, 0x0, 0x3e03a680, 0x0, 0x3e4ab203, 0x0, 0x0, 0x3de26c26, 0x0, 0x3ec20296, 0x0, 0x3e541b46, 0x3eb4273c, 0x0, 0x3e6f3363, 0x0, 0x0, 0x3e723a44, 0x3d6ffd66, 0x3e162cfb, 0x0, 0x3d56a599, 0x3eb102a0, 0x0, 0x3eb0a5be, 0x0, 0x3d937133, 0x3ea7bcdf, 0x0, 0x3d8e0431, 0x0, 0x3e651ef5, 0x3eae0d1e, 0x0, 0x3e4231b1, 0x0, 0x0, 0x0, 0x0, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, VALID_PADDING, NULL); } void test_valid_padding_zero_strides_medium() { input_set *set = &medium_input; strides_input_set *strides = &zero_strides; // 3,10,8,5 uint32_t input_vals[] = { 0x3f36b631, 0x3b9ca600, 0x3f76ac7f, 0x3d3f3570, 0x3e70e1b4, 0x3e3830f8, 0x3f3f9678, 0x3e1fb9dc, 0x3dd55dd0, 0x3aef4000, 0x3f433347, 0x3df08b90, 0x3eb33e84, 0x3dc553c8, 0x3ee7a2f2, 0x3e377d78, 0x3f3e7fdb, 0x3f1236d7, 0x3ea73b60, 0x3e0cc410, 0x3f57cffe, 0x3f1253af, 0x3eeea1d6, 0x3f116d9b, 0x3de6adb0, 0x3f335bd0, 0x3f459139, 0x3f221418, 0x3e089dac, 0x3f208980, 0x3ec148ac, 0x3dfe44a8, 0x3f434e54, 0x3f207099, 0x3f6d610b, 0x3f4929fb, 0x3f6fef6c, 0x3e96ad46, 0x3f4d17d4, 0x3e9b4166, 0x3eabb14a, 0x3b020c00, 0x3f09f77a, 0x3f68586f, 0x3ef184c6, 0x3f1b4509, 0x3df6bf78, 0x3f73cdae, 0x3f71564c, 0x3e0d0f10, 0x3f25afae, 0x3f4cc291, 0x3e5e4880, 0x3f544618, 0x3f165f1a, 0x3f0d128c, 0x3f0459a7, 0x3e24cc88, 0x3eb49e0a, 0x3f247e0f, 0x3f19b458, 0x3e607e7c, 0x3deeb150, 0x3ee86844, 0x3ed8b3e2, 0x3efaeafa, 0x3eca4cde, 0x3f4c835c, 0x3f71404c, 0x3f6162dc, 0x3eb60aea, 0x3d6169d0, 0x3d298250, 0x3f3facbb, 0x3dc7db50, 0x3f476996, 0x3d84cdb8, 0x3e8381c8, 0x3ebc1c56, 0x3edda720, 0x3f327cb8, 0x3ec91382, 0x3f567352, 0x3f60a3cf, 0x3e63cdd0, 0x3f2fbe4e, 0x3f61a525, 0x3e4d10dc, 0x3d8119d8, 0x3f706446, 0x3f566a2d, 0x3f263a00, 0x3f68176a, 0x3f6d8d15, 0x3f6c6af8, 0x3e741c84, 0x3f182317, 0x3e885446, 0x3f479de4, 0x3f7de85f, 0x3ec4857c, 0x3ebc271a, 0x3f143fe7, 0x3e0877c4, 0x3f75c402, 0x3ef8b408, 0x3f748088, 0x3f10c163, 0x3dbccff0, 0x3f32b1fc, 0x3f674b45, 0x3f0139d4, 0x3ef9b882, 0x3f64196c, 0x3defe888, 0x3dd093e8, 0x3f2b3835, 0x3f4fb95d, 0x3f7e460c, 0x3e24b3c8, 0x3e5a5130, 0x3f0208d2, 0x3f6cb694, 0x3f0b2b70, 0x3f1eaf41, 0x3ec30552, 0x3f13f950, 0x3e405394, 0x3e9bf8c4, 0x3d5b8a00, 0x3d954c60, 0x3f2aaf0d, 0x3f47c963, 0x3f48e285, 0x3f5108e1, 0x3dd6f800, 0x3f623988, 0x3f22332e, 0x3f39bf14, 0x3f37a5a6, 0x3f57aec5, 0x3f49ad86, 0x3efb3ac4, 0x3ee00cf8, 0x3f1e8a44, 0x3f05f896, 0x3f10619b, 0x3e1a016c, 0x3f667a9f, 0x3d823af0, 0x3dc83748, 0x3f332ca5, 0x3f25f83e, 0x3f52f762, 0x3f5d1d04, 0x3ed5bac2, 0x3eb30346, 0x3f5ce83e, 0x3f1fe917, 0x3ee4e7f6, 0x3ef79562, 0x3f577e28, 0x3d910f88, 0x3f427613, 0x3e94929e, 0x3ea4fce6, 0x3f23ee9a, 0x3d1c8fb0, 0x3d01a550, 0x3f42d47f, 0x3da77a08, 0x3f60995e, 0x3c0a9380, 0x3e88165e, 0x3f0ad115, 0x3f45a98a, 0x3ed80798, 0x3f1d936a, 0x3f0e07fa, 0x3e8e1ef2, 0x3ee0618c, 0x3dbbedc8, 0x3eb6713c, 0x3f22cf06, 0x3f1df573, 0x3f7cf87a, 0x3f19492d, 0x3eb07ab6, 0x3edd0088, 0x3e2a9198, 0x3defc080, 0x3f340f50, 0x3f773033, 0x3f3054c9, 0x3f76f70a, 0x3e66eb1c, 0x3f676d3a, 0x3ebeb408, 0x3f26fe18, 0x3f703110, 0x3ef2b336, 0x3f319c97, 0x3e3adb10, 0x3d1b3af0, 0x3f3b0802, 0x3e1b7498, 0x3f2f4afe, 0x3f0b8386, 0x3f285fa0, 0x3f43b72e, 0x3f5d486b, 0x3f65dcf2, 0x3e66fba4, 0x3eeb2f94, 0x3b42bd00, 0x3f62fc54, 0x3ea805d4, 0x3eb4fe52, 0x3e1fab68, 0x3e6362b8, 0x3f73f5a9, 0x3f7103c8, 0x3f439d03, 0x3f0451db, 0x3c9a8dc0, 0x3e3ccb48, 0x3f419ff7, 0x3f1d8aa7, 0x3ec10a20, 0x3e752480, 0x3f5b1273, 0x3f557bf6, 0x3e20a7b0, 0x3e701b88, 0x3daf0738, 0x3f58dfea, 0x3f5b49d0, 0x3f79dc64, 0x3d35c960, 0x3f5e3797, 0x3e9a238c, 0x3dbb67a8, 0x3f56999b, 0x3f6b147d, 0x3f450ebd, 0x3f0e0ba6, 0x3f42ab7d, 0x3e22fa34, 0x3e491070, 0x3f4b6181, 0x3f3cfea2, 0x3f773612, 0x3f37c12c, 0x3f11311c, 0x3e8e5a48, 0x3f5b9871, 0x3e184f28, 0x3f349900, 0x3f668a71, 0x3f618f59, 0x3d072ca0, 0x3eea0f1e, 0x3e109d28, 0x3edfbf9c, 0x3edb0210, 0x3f7f6eff, 0x3e478798, 0x3e182b74, 0x3e306d94, 0x3ebdac5e, 0x3ebfa2ce, 0x3ec22efa, 0x3db01a70, 0x3c854b20, 0x3f44eb5b, 0x3f342728, 0x3f131358, 0x3f390480, 0x3f154485, 0x3f54c400, 0x3e4200a0, 0x3f4477e4, 0x3f164d00, 0x3e7f1908, 0x3e10028c, 0x3debfcd8, 0x3eb5adde, 0x3f361860, 0x3f0955a3, 0x3f79dc1a, 0x3e254178, 0x3cd96800, 0x3e8f8ee8, 0x3f28e2cb, 0x3ee6297c, 0x3f4b6ffb, 0x3f451d83, 0x3f603f0b, 0x3eb77766, 0x3f22176f, 0x3e81b948, 0x3f47cfda, 0x3f10581d, 0x3f56ca4d, 0x3b0bb400, 0x3f4a6862, 0x3ed19728, 0x3dceec28, 0x3edeafc6, 0x3f0e3fea, 0x3f26b23b, 0x3f6d93ef, 0x3ebf908a, 0x3e99d570, 0x3e814d2c, 0x3f32ea59, 0x3f62acaf, 0x3f4152b9, 0x3e2d777c, 0x3e3f6a7c, 0x3ec70f36, 0x3ec7937c, 0x3f1c251e, 0x3f26d5de, 0x3e951d02, 0x3eaf0570, 0x3f04f161, 0x3ed8d624, 0x3e437414, 0x3efeceba, 0x3e8838fe, 0x3f168c18, 0x3e1a49a8, 0x3f1ae81d, 0x3eb71206, 0x3e61cee8, 0x3ecdd5a4, 0x3e418040, 0x3edfb0b6, 0x3e38040c, 0x3f76051f, 0x3ec0ee50, 0x3f6e6777, 0x3f57f7f9, 0x3f5ba562, 0x3ef21660, 0x3e8c7112, 0x3e5ab544, 0x3e827f6a, 0x3f261474, 0x3e9237d6, 0x3e5cd520, 0x3f5ab4cb, 0x3e81e382, 0x3d0e0a40, 0x3d0e87e0, 0x3f3fecc7, 0x3eaa5012, 0x3edeea7a, 0x3f1ad9aa, 0x3f059183, 0x3eb3fbb8, 0x3f014789, 0x3e4747a0, 0x3f1f716e, 0x3b714000, 0x3e852fde, 0x3c56b680, 0x3f30cc9a, 0x3f04b414, 0x3efcfc4a, 0x3f70c129, 0x3eacc898, 0x3ea23a38, 0x3f1f14e9, 0x3f50d1f7, 0x3f147713, 0x3f6be6c0, 0x3f3483e7, 0x3eea910a, 0x3e591a9c, 0x3f5c5ad6, 0x3d514e70, 0x3f4a49a7, 0x3f37fad8, 0x3f46540c, 0x3f74a543, 0x3f40679c, 0x3f4abe61, 0x3e178ffc, 0x3eae56a8, 0x3edbefee, 0x3da237b0, 0x3ed100d2, 0x3e92d8a6, 0x3dec6e58, 0x3f1317ce, 0x3f12ab4d, 0x3f45daaf, 0x3f5fe2b6, 0x3e42cb94, 0x3f7a260c, 0x3f0d94d4, 0x3e2f4678, 0x3f5da986, 0x3f3ecd03, 0x3f6e32c6, 0x3eb08d0e, 0x3ea099be, 0x3e11011c, 0x3f766f53, 0x3e6611c4, 0x3f5d2b28, 0x3ee70ede, 0x3f658ee8, 0x3d2f4970, 0x3f1d4a31, 0x3d9109c0, 0x3ce695e0, 0x3f7f63bf, 0x3e8fd860, 0x3e3e820c, 0x3f0d6155, 0x3f032f81, 0x3f10d55d, 0x3f6d3b5e, 0x3f02d3a0, 0x3f56b825, 0x3f146fa0, 0x3de117f0, 0x3ef0853c, 0x3f6a0c73, 0x3de4ad70, 0x3e9a66fc, 0x3f18cfc5, 0x3f1944d9, 0x3f3f06b1, 0x3ef8a9a6, 0x3f298468, 0x3ecc4c4c, 0x3f123787, 0x3d1cee30, 0x3f3b25da, 0x3f6fd971, 0x3f5c07c3, 0x3f34bfaa, 0x3e91d31a, 0x3f33a6b7, 0x3ed4457e, 0x3ca0a0e0, 0x3e968518, 0x3da00258, 0x3f0f0d86, 0x3e6f51dc, 0x3f20c172, 0x3f109e04, 0x3f3c4c11, 0x3f33be00, 0x3d69d2d0, 0x3efcff56, 0x3f5730f0, 0x3edf8088, 0x3e1b1620, 0x3e0a22dc, 0x3f0a1397, 0x3eea6736, 0x3e09b75c, 0x3f6a9bfc, 0x3e64d1b8, 0x3f580cd8, 0x3d290cc0, 0x3eae325e, 0x3f02dad5, 0x3e057dd8, 0x3f024ff2, 0x3f2c3e6f, 0x3f2a014a, 0x3f52bd7b, 0x3e9b5a80, 0x3dc798e8, 0x3ebea594, 0x3f0bd9a6, 0x3f1c50ef, 0x3f468365, 0x3e5554cc, 0x3ec9fdf8, 0x3f781a74, 0x3ee3854a, 0x3f280dd5, 0x3e997f22, 0x3f42c1ab, 0x3efc99ea, 0x3f36d3c3, 0x3f735e96, 0x3f0da6b8, 0x3f166eb5, 0x3f284366, 0x3f7982ae, 0x3f7f159b, 0x3f31652b, 0x3e4a43b8, 0x3eb27360, 0x3f7e42e8, 0x3ea3d00a, 0x3ed03742, 0x3e89dd14, 0x3f0f4624, 0x3da20d48, 0x3e9bbeda, 0x3e9af660, 0x3ed915e6, 0x3f0495dd, 0x3f07c35c, 0x3f118423, 0x3f382ace, 0x3ec0c056, 0x3f6df319, 0x3e1030fc, 0x3dd09b68, 0x3c62da80, 0x3ec9ce0c, 0x3f35a223, 0x3f4a9439, 0x3f459f23, 0x3f5971aa, 0x3e220b1c, 0x3e5c371c, 0x3f5be3f7, 0x3ed1ecf8, 0x3ee23da0, 0x3f5cba00, 0x3d643c00, 0x3e187990, 0x3da69340, 0x3f5910ef, 0x3f426233, 0x3cc6e800, 0x3ef1344e, 0x3dfae618, 0x3f60b7f5, 0x3f1942a2, 0x3ea30810, 0x3f5892c1, 0x3e1f3270, 0x3f0dac81, 0x3f1cfb60, 0x3f108bc3, 0x3f54a5b3, 0x3f232e5b, 0x3f287d6a, 0x3f0efc17, 0x3f786b06, 0x3dfe15e8, 0x3f621efb, 0x3e5e68d4, 0x3f5fb5c0, 0x3ee6d8ca, 0x3f55f16d, 0x3f656889, 0x3f5bb5c0, 0x3f1cf6c7, 0x3f320bfc, 0x3ed2ad8a, 0x3eb98256, 0x3f4aeaf3, 0x3f137f9e, 0x3f410d87, 0x3d991dd0, 0x3e569a0c, 0x3ed7cafe, 0x3e668c48, 0x3def9d98, 0x3f197f5b, 0x3e8e60d6, 0x3f31e438, 0x3f2ab320, 0x3db0ee68, 0x3f3ba15f, 0x3e223e2c, 0x3ef1a91e, 0x3d040020, 0x3f308052, 0x3f4cc3a8, 0x3ebdff66, 0x3f640150, 0x3f285ea6, 0x3f3ba978, 0x3e23e124, 0x3d465d60, 0x3f34b0c8, 0x3d886860, 0x3e88cc22, 0x3e0d2ad4, 0x3f446a6a, 0x3f5d5169, 0x3e960c80, 0x3f140f03, 0x3e27fde0, 0x3cf0dd40, 0x3d3a6940, 0x3f43937e, 0x3c2b1f80, 0x3f488a07, 0x3e418210, 0x3f7cb6bd, 0x3e4f0bf0, 0x3f019d08, 0x3d810b18, 0x3f55e69d, 0x3f2fb0bf, 0x3f65ec48, 0x3f1f602f, 0x3efdd75e, 0x3e0104f0, 0x3f3e3b36, 0x3e651c0c, 0x3f01362b, 0x3eb4c58a, 0x3f1e99ac, 0x3f1c85ab, 0x3f793d8d, 0x3ed75d7a, 0x3f37e2a9, 0x3f5fe002, 0x3f541199, 0x3f27737e, 0x3f354703, 0x3f19231c, 0x3f7e2bde, 0x3f788080, 0x3e910fb4, 0x3eb9a258, 0x3e7d73d8, 0x3f40c445, 0x3eea30f6, 0x3f4e1083, 0x3f5f484b, 0x3f165b7a, 0x3ebb4c5e, 0x3db7c988, 0x3d6a4e60, 0x3d8dffa8, 0x3f75cb55, 0x3f4924cc, 0x3f7589a7, 0x3e3ba718, 0x3e5b64c4, 0x3f15130b, 0x3ef78d22, 0x3eca0304, 0x3e3f3a18, 0x3da92190, 0x3e812406, 0x3eb1109e, 0x3e84898c, 0x3f10d994, 0x3d43c8a0, 0x3f044912, 0x3f006ab8, 0x3f4ecb83, 0x3f0c933a, 0x3f5ee4ab, 0x3d297a30, 0x3f1cb629, 0x3f476f1e, 0x3d8f4010, 0x3ec0a59e, 0x3e3780b8, 0x3f55d398, 0x3f11230d, 0x3f7b83d5, 0x3ddb9ed8, 0x3ed072d2, 0x3f35bad5, 0x3eefee28, 0x3effc15e, 0x3f1a8c66, 0x3e40f244, 0x3f3d1e68, 0x3ecf06e8, 0x3e6e97fc, 0x3df891f0, 0x3f6c646f, 0x3f132603, 0x3f755d4b, 0x3f030eb4, 0x3f069de3, 0x3f18d89b, 0x3ef31d78, 0x3f4dfd0b, 0x3e921c74, 0x3f3cd952, 0x3f632436, 0x3f35bf2e, 0x3f4c3a85, 0x3f23506e, 0x3ec9ddfa, 0x3ec5b4de, 0x3f1ec970, 0x3f519f70, 0x3f2e5652, 0x3f41cd3e, 0x3edc6592, 0x3cb093e0, 0x3e740a40, 0x3eb761fc, 0x3f1a4575, 0x3f204993, 0x3f14b1c6, 0x3f1ab9cd, 0x3f077650, 0x3dca4d18, 0x3eb3e18e, 0x3e8e4ffe, 0x3d8a25f0, 0x3f4c2939, 0x3f193155, 0x3ea8bc8e, 0x3e707ccc, 0x3f4a5d88, 0x3e32faac, 0x3f52839c, 0x3c1bd940, 0x3f318061, 0x3b900d80, 0x3ec6ea42, 0x3ec4a776, 0x3f606dab, 0x3f1a2caf, 0x399c3000, 0x3eda3bd4, 0x3f0c18e1, 0x3f73d7fe, 0x3f15ad0b, 0x3bbcb600, 0x3e2d4114, 0x3f105459, 0x3ba1d600, 0x3e868ece, 0x3f4eeef6, 0x3f0a6cdd, 0x3f0b01ca, 0x3eab4cdc, 0x3f3b253e, 0x3f0d522a, 0x3f04b44f, 0x3f214601, 0x3df97570, 0x3f781e88, 0x3f004a84, 0x3dc4e2c8, 0x3cae3f40, 0x3e981544, 0x3f0fa8be, 0x3f145be8, 0x3f1a41ed, 0x3f611d95, 0x3f6172a1, 0x3f349c83, 0x3e9f1dd2, 0x3f7a2bf5, 0x3f37d399, 0x3f44784a, 0x3d7b3b70, 0x3eb2431e, 0x3f441518, 0x3f0fce8a, 0x3eec22ee, 0x3f4c186b, 0x3e271ef0, 0x3e6a4590, 0x3f174a78, 0x3f36ab45, 0x3f2c7736, 0x3ec17b00, 0x3f752abc, 0x3dc62d48, 0x3f2639dc, 0x3f39aae7, 0x3e44f29c, 0x3e200de4, 0x3eb6e81a, 0x3f45e72e, 0x3f3560a9, 0x3f035e25, 0x3e7bad00, 0x3ef4dd66, 0x3dc91d00, 0x3ebcaa6c, 0x3f649206, 0x3f3875bd, 0x3f1e6d42, 0x3f2790d3, 0x3ef0a232, 0x3db17798, 0x3f65d44d, 0x3e672348, 0x3cd8b4e0, 0x3f7bcf6d, 0x3f3ef25d, 0x3e032ce8, 0x3e938888, 0x3ec79684, 0x3f2f7936, 0x3dda4f60, 0x3e95eede, 0x3f349424, 0x3d9caff0, 0x3f1c2c7e, 0x3f3398e5, 0x3f190799, 0x3e05dd44, 0x3edc72e0, 0x3f3675c1, 0x3f5e5a3c, 0x3f16064c, 0x3f662418, 0x3f3f4247, 0x3f0f3b48, 0x3f25daa2, 0x3f68f840, 0x3f6ffad9, 0x3c630280, 0x3f2b903a, 0x3f2c223d, 0x3effe77c, 0x3f2e2f6b, 0x3eecd0da, 0x3f342867, 0x3f5363b6, 0x3e9e7f68, 0x3f63ad4c, 0x3f3414bf, 0x3e6bcdb0, 0x3f578426, 0x3e962064, 0x3f4db122, 0x3e9c3af6, 0x3ef24892, 0x3f4c6ed5, 0x3f03c0b1, 0x3e9e3aaa, 0x3f0ba870, 0x3f134a31, 0x3f4793dc, 0x3e001670, 0x3d87d9c0, 0x3e9baaf2, 0x3ed92222, 0x3f22a2b0, 0x3ddd1fd0, 0x3f10d7f2, 0x3e288014, 0x3da30988, 0x3f4211a2, 0x3e92778e, 0x3f505e3f, 0x3f643df4, 0x3f0c2459, 0x3e20aef4, 0x3f0349c1, 0x3ee5cf92, 0x3e1474a0, 0x3f4e39d7, 0x3e349b04, 0x3e2639b0, 0x3f0ac524, 0x3efcffac, 0x3e6e2ee4, 0x3f226cb6, 0x3e5bbbc0, 0x3f5edf6b, 0x3f2aa1b4, 0x3f7dabe8, 0x3f13eb6d, 0x3f5b6432, 0x3f34d9a9, 0x3e61deac, 0x3f1d30f9, 0x3d778ee0, 0x3f764987, 0x3f5fb106, 0x3f3dcdc1, 0x3f367073, 0x3e0b0244, 0x3eafcfd0, 0x3f12cb91, 0x3dad9c30, 0x3e9d2594, 0x3dd0d1a0, 0x3d9178d0, 0x3f0e591f, 0x3f7a3f1c, 0x3dba5ad0, 0x3f65a922, 0x3e9dfd50, 0x3ec2c3f4, 0x3f390185, 0x3ea0ba1a, 0x3f53afab, 0x3f33a93d, 0x3ed4cce4, 0x3edbc1d0, 0x3f03e91f, 0x3e728234, 0x3f298ab0, 0x3e6fe3bc, 0x3dac3250, 0x3e8b58f8, 0x3f135011, 0x3eb0a3dc, 0x3f5593ec, 0x3f03f287, 0x3f71fe15, 0x3ec51e3e, 0x3d744960, 0x3f74be06, 0x3f2d671d, 0x3e384d84, 0x3f6f4615, 0x3eb3061c, 0x3f2f80b2, 0x3e69ed90, 0x3e2727b4, 0x3d410e20, 0x3ec6c27e, 0x3f03a310, 0x3edfc2a4, 0x3ea53202, 0x3e0a79b4, 0x3f49b5df, 0x3eab7e3c, 0x3ae05e00, 0x3f72d5e0, 0x3dab7408, 0x3e810eaa, 0x3bcf8e00, 0x391bc000, 0x3e8af156, 0x3f4a7e45, 0x3f4cd234, 0x3ed098fe, 0x3ee4327e, 0x3f766ab7, 0x3e80075e, 0x3f11c187, 0x3e14872c, 0x3f6b1a7b, 0x3f3d8346, 0x3f4c3cf2, 0x3ed51848, 0x3e060280, 0x3ef3f384, 0x3ed91a44, 0x3f2b44a6, 0x3d5edd00, 0x3ecd4ecc, 0x3f282129, 0x3f4233de, 0x3e82de7e, 0x3f7e5ec6, 0x3ecda3b2, 0x3e99ac3a, 0x3f3cda2e, 0x3ebb093e, 0x3ed259d4, 0x3f19d226, 0x3eac68c0, 0x3e7b6568, 0x3e9866b8, 0x3f508994, 0x3e0ce474, 0x3ee3dc62, 0x3ecb4bcc, 0x3f387866, 0x3e772898, 0x3f5bfd02, 0x3e7d2af0, 0x3f7bfbe4, 0x3e9955f4, 0x3c566100, 0x3d376530, 0x3f4e5334, 0x3f496291, 0x3f2b7072, 0x3dcfc480, 0x3e86c298, 0x3f4fd219, 0x3e82f6e0, 0x3f0924f0, 0x3e799b88, 0x3e9ecf24, 0x3de3f120, 0x3ebb2a18, 0x3dce3a20, 0x3eae78de, 0x3f07e440, 0x3f274293, 0x3f47be34, 0x3e3e2694, 0x3edbd970, 0x3f34e9a9, 0x3e963ec0, 0x3f40fb2f, 0x3e1cfe1c, 0x3f6ac0fb, 0x3ebc892c, 0x3e5993d4, 0x3f0a2574, 0x3f431243, 0x3d1f36f0, 0x3f13fa11, 0x3ee0c4b6, 0x3e368e9c, 0x3f1bbc36, 0x3f3fe30e, 0x3ec36554, 0x3eb09934, 0x3e065dc0, 0x3ef9902a, 0x3f6bb3ef, 0x3e9b5008, 0x3e5c78e0, 0x3ec9f760, 0x3e4f2254, 0x3f00d2e7, 0x3edc3108, 0x3f12dd38, 0x3f2f0fb7, 0x3b969c80, 0x3e40b1fc, 0x3f19c592, 0x3f490f1c, 0x3ee4b532, 0x3ea567b4, 0x3f04180f, 0x3c6ab140, 0x3ed87f5a, 0x3da7da00, 0x3df04a10, 0x3f1e5dd8, 0x3e1ba038, 0x3eee17ae, 0x3ec14278, 0x3b2edc00, 0x3f38a28e, 0x3f64000a, 0x3f09a1d2, 0x3f7fc3e6, 0x3cbd65e0, 0x3eb22f14, 0x3f39e132, 0x3e91fa0a, 0x3db1a4f0, 0x3e319080, 0x3ea825ec, 0x3ef927ba, 0x3f43c3c1, 0x3de54748, 0x3c643940, 0x3e873a08, 0x3f040ad3, 0x3f761a55, 0x3f5076ef, 0x3f27e6a1, 0x3c864a80, 0x3f11ab22, 0x3ee89a44, 0x3f7f5c64, 0x3f2fe4e3, 0x3f2cf469, 0x3f1dc003, 0x3f08b381, 0x3c9bccc0, 0x3f3397ba, 0x3df9d740, 0x3e227020, 0x3f67225d, 0x3d43b5c0, 0x3b13a000, 0x3e850468, 0x3eba37b4, 0x3f68d6ed, 0x3eaff3d4, 0x3f4f2667, 0x3efd5d96, 0x3d286520, 0x3e031f88, 0x3f7f9ed7, 0x3f18f491, 0x3f62acfc, 0x3ddaf220, 0x3e89721c, 0x3e5d693c, 0x3f417389, 0x3f71cf35, 0x3ecfd50e, 0x3c1c3a80, 0x3f0af1a6, 0x3ec114c6, 0x3e0b9774, 0x3ede32d4, 0x3f4e661e, 0x3f687d66, 0x3f3d77ac, 0x3f6f0343, 0x3f641d5d, 0x3f63e789, 0x3ea55fac, 0x3cd34ac0, 0x3f72a8f4, 0x3f160c23, 0x3ea2d36c, 0x3eb17e60, 0x3f2b9905, 0x3f67672c, 0x3ed67d9e, 0x3f290f1b, 0x3e28541c, 0x3f657fd6, 0x3f0b24da, 0x3ef8e85c, 0x3f1f0187, 0x3f04ea25, 0x3f35ce89, 0x3f66cd7c, 0x3f477cad, 0x3d8efe60, 0x3f7778f2, 0x3ceb0ec0, 0x3f3e30db, 0x3eb27386, 0x3f331d5d, 0x3f345742, 0x3eb82282, 0x3e109c08, 0x3ed02474, 0x3f3ecea4, 0x3f59f84d, 0x3ee0357a, 0x3e7222f0, 0x3ecca506, 0x3f02d0a6, 0x3eef0a28, 0x3f4310eb, 0x3f026842, 0x3dc64630, 0x3f0d205c, 0x3ed7565c, 0x3e9f210a, 0x3e1527f4, 0x3edc3884, 0x3f1dbe71, 0x3ed243ba, 0x3f1268ea, 0x3eabb42e, 0x3d1abe50, 0x3f5c3655, 0x3f490120, 0x3ea62188, 0x3f6732ed, 0x3e6cca60, 0x3f7118d7, 0x3ede6e68, 0x3ed7550e, 0x3f3b981c, 0x3e3a1adc, 0x3f1265a5, 0x3d954db8, 0x3efae76c, 0x3f6f78f9, 0x3f5f59bb, 0x3f368f94, 0x3ea61b26, 0x3e5a004c, 0x3f00fb35, 0x3d216a30, 0x3ebd061a, 0x3f3217ec, 0x3e1c9fc8, 0x3e7aee48, 0x3f7b5503, 0x3f4c506d, 0x3f7ccbec, 0x3f69ab33, 0x3f54b76f, 0x3f2ffe47, 0x3e9b4d50, 0x3ed17370, 0x3f6b8ba6, 0x3f096fbb, 0x3e25fe6c, 0x3db3ed90, 0x3d8470b0, 0x3ef83fea, 0x3f158e41, 0x3f6a0bf2, 0x3f3c0de9, 0x3e070158, 0x3f6ecaf7, }; // 10,8,5,5 uint32_t kernel_vals[] = { 0x3d3114e7, 0x3d4407ad, 0xbd35d912, 0x3ca7c94a, 0xbc56a7e8, 0x3b948e90, 0xbccbb9a0, 0x3c2b9b28, 0x3ca02e4e, 0xbcceb383, 0x3c6a04fc, 0xbd37c660, 0xb799d800, 0xbc5c8848, 0xbc4ae274, 0xbcf0a620, 0x3cb33d9e, 0x3d261659, 0x3cc7aeb6, 0x3d326067, 0x3c9c9e26, 0xbbcc0050, 0x3cd0ac2a, 0xbc893ff4, 0x3b8b1050, 0xba428000, 0xbd315ffa, 0xbd0f4ef5, 0x3bbcf490, 0xbc2ab878, 0x3bc68180, 0xbbc9bb68, 0x3cd18a86, 0x3c96670e, 0x3c22f178, 0xbca5d14a, 0xbca34e20, 0x3c69da2c, 0x3c012fc8, 0xbc4e8c78, 0x3c6c85a4, 0xbc8a1926, 0xbc54d694, 0xbd031dd0, 0xbc5f05c0, 0xbbdf5d98, 0x3cfff456, 0xbc9b11c7, 0xbd0435ce, 0xbd0479da, 0xbb11a930, 0xbd09e01a, 0xbcae6513, 0x3c897392, 0xbd33a047, 0xbc90b650, 0xbbfc8990, 0x3c8228ee, 0xbca793ea, 0xbd149155, 0xba0b0b40, 0x3cf9af0e, 0xbd20aafd, 0x3b9c4c68, 0xbd08876d, 0x3c3bf5c0, 0xbc85b67a, 0x3c955286, 0x3c4ab648, 0xbca8e4b7, 0x3c4cdf44, 0xbccb04c3, 0x3c22b794, 0xbd0e93a0, 0x3d2b04dd, 0xbc6033f4, 0xbccbc0f7, 0xbd0e3688, 0xbc4bfcd8, 0xbd37700a, 0xbd4b06a7, 0x3c0ceeec, 0xbbdb7928, 0x3c47f720, 0x3d3832a9, 0x3bd083d8, 0xbd420c63, 0xbd20b7cd, 0x3d284029, 0xbd2f3a1d, 0x3cdc94ea, 0x3cc68052, 0xbc0ab8e0, 0x394d6e00, 0xbd1fc3aa, 0x3c4e2404, 0x3d0adb4d, 0x3c6f5e74, 0x3d373d99, 0xbcd89817, 0xbc582354, 0xbb25eea0, 0xbd33a903, 0xbcc14be7, 0x3b5d7630, 0xbc550a98, 0xbd280dfd, 0xbd412b6f, 0xbcda4e57, 0xbb931290, 0xbcd13840, 0xbd378128, 0xbb4bacb0, 0xbc816b44, 0x3cc4982e, 0xbbf372f0, 0xbc1ece18, 0xbc8989d0, 0x3d2dbdf9, 0xbd2d3ab0, 0x3d4754e3, 0x3c4187f8, 0xbcbd2fdd, 0x3c945352, 0x3d080845, 0x3b240150, 0x3c131a98, 0x3b7fc8a0, 0x3d282079, 0x3c047518, 0x3c9ccfca, 0x3d252367, 0x3d14eb05, 0x3d2ee1b1, 0xbc832ce6, 0xbb9290b0, 0x3ced2af6, 0xbbcd5880, 0xbd237b88, 0xbc38d38c, 0x3cd2775a, 0x3c209b68, 0xbcc059b3, 0xbc2d7688, 0x3c3664a8, 0xbd444938, 0x3bb62998, 0x3cfce4ea, 0xbd2647d2, 0x3c4f8f54, 0xbcc7f663, 0xbc706940, 0x3cf03666, 0x3c894e02, 0x3cdd4b22, 0x3d3058e5, 0xbd178a16, 0xbd33a122, 0xbcaf84fa, 0x3d2b357f, 0xbbcc8510, 0xbcf1e24d, 0x3d1811bb, 0x3d07983b, 0x3d00c77d, 0xbd367605, 0xbd4672e3, 0x3d0419c7, 0x39b31800, 0xbd492abb, 0xbc9b6eea, 0x3be18d70, 0xbd41a34a, 0xbcfcf530, 0x3cfcab42, 0xbd3e81a2, 0xbd421e7f, 0xbcc11efd, 0xbca63d6d, 0xbd331545, 0xbd38f0bd, 0x3d496ed7, 0xbc17b734, 0x3c3b45f4, 0x3c64196c, 0xbd417f67, 0x3d15ae6f, 0x3d14b5f5, 0x3c64e8bc, 0x3b57aae0, 0x3c5c3774, 0xbcca7973, 0xbcded7b3, 0xbcb2267d, 0x3ca850b6, 0xbd09ca34, 0xbcfc9c53, 0xbc99dc4d, 0xbd2dda8b, 0xbd104bc0, 0xbcd2fcc7, 0xbbbd1f80, 0x3ba3d618, 0x3b924eb0, 0x3c0f8a6c, 0x3cc38ea2, 0xbca04520, 0x3b4b43d0, 0xbc6d4e08, 0x3c1c136c, 0x3d0ad6ab, 0x3c7f40fc, 0x3d0add39, 0x3d06e91b, 0xb8853000, 0x3d46d18b, 0x3c98251a, 0xbc107654, 0xbc49e4ec, 0xbc4a6e8c, 0xbcc6af4d, 0x3d181b39, 0xbcf100ed, 0x3bed0c00, 0xbacbcf40, 0xbc2304c0, 0x3d1b6291, 0xba2194c0, 0xbc3212ec, 0xbbecaeb0, 0xbd425452, 0xbcb6dac3, 0xbc86e604, 0x3cccd70a, 0xbcc3d7aa, 0xbba5a570, 0x3c4da1fc, 0xbcbb9c3d, 0xbcf26c8d, 0xbd38e4c7, 0xbd4ab0b3, 0xbb218ae0, 0x3cce9f6e, 0x3c6a84a4, 0x3c8fbf5a, 0x3c20d718, 0x3cd7200a, 0xbcf3275d, 0xbca6530a, 0x3cd43cfe, 0x3d1aa751, 0x3d1daee3, 0x3cbf75f2, 0xbb8c1c50, 0x3cf04506, 0xbd43d9c2, 0xbbe133c0, 0xbc95d02a, 0x3a580cc0, 0x3d433091, 0xbd310a97, 0x3d22b219, 0xbd20c68d, 0xbcf093a3, 0x3a90b0c0, 0xbcd4a277, 0xbcc4ea5d, 0x3ba52110, 0xbd4584b0, 0xbc4892e0, 0x3cf9cef2, 0xbd202d7b, 0xbcf8329d, 0xb9317b00, 0xbb02cb60, 0x3d16a987, 0x3ccd0ae2, 0xbd0e07bb, 0x3ce5afe2, 0xbcba3e53, 0xbd004140, 0x3c727284, 0xbd3100aa, 0x3ce1384a, 0xbc7980ac, 0x3d220849, 0xbd3db48b, 0xbd401a28, 0xbca574ea, 0xbc3922f4, 0x3d031b4f, 0xbd32a3f0, 0xbd2c5190, 0x3d1b5ce1, 0x3c8da5b2, 0xbd1adf65, 0xbd3eaf7f, 0xbd40fb2d, 0xbc019894, 0xba3c1140, 0xbcf569ad, 0x3bede0a8, 0x3b1b9230, 0xbd23010b, 0x3c740fcc, 0xbbd867c0, 0xbc17c908, 0x3b348ca0, 0xbc5dd360, 0x3d2a569d, 0xbcdc6527, 0x3d15f95b, 0x3c943d1a, 0x3b68f8d0, 0xbce9bb5a, 0xbc0014b4, 0x3d0229a5, 0xbd4ba5e0, 0x3d13459b, 0xbab304c0, 0x3d053451, 0xbc52e2cc, 0x3c0c96a8, 0xbd334520, 0x3cc7999a, 0xbafba400, 0x3c4b8ce8, 0x3d3f28c9, 0x3d3959cd, 0x3ca50e6e, 0x3c64cc2c, 0xbd4c667b, 0xbbba0840, 0xbcf05baa, 0xbb70df60, 0x3c910432, 0x3c84d512, 0xbd388aaa, 0x3c8acbf6, 0xbc3d9808, 0xbcda55a7, 0xbc24b518, 0xbcc722f0, 0x3cad76be, 0x3c70c6dc, 0x3d2b11e3, 0x3d080f31, 0xbc220d2c, 0xbd3703ba, 0xbd191162, 0xbc6c6f40, 0xbd1de1dd, 0x3d1235e5, 0x3d09d783, 0x3ccdc1ee, 0xbd1bc0b0, 0x3d100d91, 0x3d328b8f, 0x3c9d09ae, 0x3ccd7882, 0x3d4b1a4d, 0xbd093d0c, 0xbd4c717f, 0xbceb60ea, 0x3b2b4ea0, 0x3cf9e1ea, 0xbd493907, 0x3d3ce3f1, 0x3d195011, 0xbca6a497, 0xbcc9e50d, 0xbcc9a8b7, 0xbd2c719d, 0xbd1ed948, 0xbc243d94, 0xbcdb1f83, 0x3ca5dcfe, 0xbd4afb10, 0x38343400, 0xbc8c7d06, 0x3d1dc93f, 0x3d4ada1d, 0xbc86d956, 0xbce683e3, 0x3d0fffe1, 0x3b17b100, 0x3c475238, 0xbccf00f3, 0xbb9a41d0, 0xbd1a502d, 0x3b5ba7d0, 0x3d45967d, 0xbd119e3b, 0xbc7f0188, 0xbd0cdef0, 0x3c0efb68, 0x3d3dd0f3, 0xb7ac8000, 0xbcab8b77, 0x3cba91c6, 0xbc100de0, 0xbd4bd305, 0xbbf6a4d8, 0xbca78a53, 0x3c83d052, 0x3d393393, 0x3ccea7ae, 0x3d1e4b01, 0xbd2825a6, 0xbd18795e, 0x3c6bafd4, 0xbc644f88, 0xbd2ce9d7, 0xbc0d95d4, 0x3c083834, 0x3b0057b0, 0x3cc75282, 0x3ce1beba, 0x3c3a97ec, 0x3bd0a898, 0xbcd2478a, 0xbccdefdd, 0xbc0876a8, 0x3bfed400, 0x3cc8e346, 0xbc8e1f0a, 0xbca92707, 0x39f45d00, 0x3c270728, 0xbc208c78, 0x3b499c00, 0x3d4866f5, 0x3b1b1fb0, 0x3c9e40d2, 0xbd087ff6, 0x3ca2bef2, 0xbca468d3, 0xbca16b1a, 0x3d3addf5, 0x3d0e80bf, 0xbc78d1ac, 0xbcf4ff6d, 0x3d12995b, 0x3b26b4d0, 0xbd02b830, 0x3c2f7634, 0xbd38ff10, 0x3ca8f88e, 0xbcc0a01a, 0x3d3e36f3, 0x3ce4f236, 0xbc57488c, 0xbc873f94, 0xbd078f10, 0x3c5c97fc, 0x3d26b433, 0x3c5f45f4, 0xbcb806a7, 0xbcf658aa, 0xbd4a8470, 0x3d1ac939, 0xbbb171c0, 0xbd00ee5e, 0xbc93b7e4, 0x3c21d4a8, 0x3d1a4def, 0xbd15782e, 0xbca9c733, 0xbd0d9e3b, 0xbcfdea43, 0xbcbde660, 0x3cb42d8e, 0xbd206ac0, 0xbae99a00, 0xbc220d0c, 0xbccb22e0, 0x3d166429, 0xbd068cfd, 0x3d05072b, 0xbcfbdd43, 0xbcb96ea7, 0xbb806270, 0xbc42d22c, 0xbc99f550, 0x3d13b6ef, 0xbc7b5968, 0xbcc11cb0, 0xbcd22397, 0x3d467733, 0x3d437e0f, 0x3ce33436, 0x3d45e69f, 0xbcb4e1d3, 0xbc9d780d, 0xbd44eddb, 0xbc9f8fca, 0xbcf78a10, 0xbc667634, 0xbbc440b0, 0x3c4219ac, 0x3bfc1290, 0xbabf0aa0, 0xbd0e8156, 0xbcd89f10, 0xbd22bc6a, 0xbca2091d, 0xbd231f4b, 0xbbb9ed70, 0xbc4c8ce8, 0x3d302005, 0xbce67d5d, 0x3d3315ab, 0x3d42b557, 0xbcfb3853, 0x3cbf22fa, 0x3c12c0b8, 0x395ae800, 0xbd13572e, 0xbc916986, 0xbc828f20, 0xbd0918b5, 0xbc012328, 0x3c289e98, 0x3d3b4c3b, 0xbcc988c0, 0xbce724a7, 0xbcba939d, 0x3d081539, 0x3c1c8748, 0xbd27860b, 0xbbd36d68, 0xbd32ff08, 0x3a07c480, 0x3b68ad60, 0xbc95b244, 0xbb803750, 0x3d304595, 0xbc1a6028, 0xbca8c7c3, 0xbd2183eb, 0x3bfa09e8, 0xbcf657b7, 0x3bff8f70, 0xbc4a8ccc, 0xbd08d850, 0xbd2ac862, 0xbc7f8300, 0x3cad9fc2, 0xbcbab96d, 0xbc097d78, 0xbc7fad2c, 0x3c0f1f14, 0xbc849b46, 0xbd497d13, 0xbd00be2c, 0x3bb30530, 0xbd0d0112, 0xbc06f720, 0xbc8ddc4c, 0xbcc89d13, 0x3d202a01, 0xbbaec7d8, 0x3d29e3b7, 0xbd1a09f5, 0xbca13973, 0x3cd3cd26, 0x3cebb3f6, 0xbbe50af0, 0xbd35d98f, 0x3d1f7d17, 0x3d236eef, 0xbb822f98, 0x3b77e3b0, 0x3d406aa1, 0xbccda04d, 0x3d213933, 0xbd29efdd, 0xbb52e030, 0x3cc425a6, 0xbcad5aa3, 0xbd0edd9d, 0xbc4fd994, 0x3c731dd4, 0xbc936a74, 0x3c092048, 0x3b8cdf68, 0xbd359ca3, 0x3a916860, 0x3d16e051, 0xbc452278, 0x3cff2f52, 0xbc2aa378, 0x3b1f33e0, 0xbd1008a5, 0x3d1396bd, 0xbbcee730, 0xbd32750b, 0x3c5e0074, 0xbd1d38e3, 0x3d17c565, 0xbcc91663, 0xbc58e3a8, 0x3c7060e4, 0x3d0aa399, 0x3bf3e110, 0xbd23fdb5, 0x3cee8352, 0x3d28a7f7, 0xbc4de580, 0x3cdc852a, 0x3d0e4c21, 0xbb4875b0, 0xbbd2b018, 0xbd0cd62a, 0x3c750ec4, 0xbca804bd, 0x3b607880, 0x3cb1ab1a, 0xbb9b9640, 0x3c425e0c, 0xbab5cfa0, 0xbd3bd7c3, 0x3d4cb99d, 0xbd2adf2d, 0x399faf00, 0xbb450930, 0x3c62e114, 0xbcfb6890, 0x3d19b807, 0xbc333088, 0x3ca1ce42, 0xbca8fe90, 0x3c00c3c8, 0x3d0f85ad, 0x3c4a3528, 0xb9c2e680, 0x3b587fe0, 0xbc6fd8e0, 0x3ca98c0a, 0xbabaeb40, 0xbbb38168, 0xbcd55fda, 0x3cabf766, 0xbbf93d10, 0x3d2666ab, 0xbccbd870, 0x3cb013da, 0xbc8de3f0, 0x3c853306, 0x3ca6a16e, 0x3d439811, 0xbb590460, 0x3b920898, 0x3b85bc10, 0xbce92ce7, 0x3c6c3284, 0xbafe8960, 0x3c945cc2, 0x3c754a7c, 0xbc2abab8, 0x3c7b58dc, 0x3d08e483, 0xbd126588, 0xbc968340, 0x3d24cd49, 0x3cb3d2da, 0xbd2d76eb, 0xbc813a44, 0xbd39e80d, 0x3cc53a6a, 0x3d0ebf09, 0xbbb9a7f0, 0x3d0b9495, 0xbcee629d, 0x3ce14c82, 0x3c8c3152, 0xbbac1070, 0x3cf3a29e, 0x3cf1d7da, 0x39dc3700, 0x3d485977, 0xba38fb80, 0x3cfcefb2, 0xbcc5326d, 0xbd0244a4, 0x3ae3e240, 0x3ad2db40, 0xbd248bd0, 0x3d4c15c9, 0x3bbe53a8, 0xbcc67bc0, 0xbd080328, 0x3b610de0, 0x3c2f094c, 0xbd40ed1d, 0xbcea71b3, 0xbcf7154d, 0x3d30698f, 0x3cd21802, 0x3c18a814, 0xbcd07c67, 0x3cfa565e, 0xbcef7d00, 0x3c8ba85e, 0xbc8159b0, 0xbca6ffcd, 0xbd05df9a, 0x3c309480, 0xbd0d905e, 0x3d2f28ab, 0x3ab1e760, 0x3c6e6cc4, 0x3d0dced9, 0x3be71b70, 0xbd01b3b6, 0x3d3f7f8b, 0xbbb3e6b0, 0x3c429918, 0x3cdf0662, 0xbba3ee28, 0xbca5aaed, 0xbaa6f360, 0xbd352b5f, 0xbce29c30, 0x3bae5b50, 0xbcf5ecd3, 0xbd1b9263, 0x3c6e55fc, 0x3d095799, 0x3cfc7d6a, 0x3c90a572, 0xbab16840, 0x3cbcd04a, 0x3a97d940, 0xbd04a19c, 0xbd42e445, 0x3c595cd4, 0xbc7c71c0, 0xbd31da0d, 0xbc962a74, 0xbd0c49b0, 0xbd1443b5, 0x3a8b8060, 0x3d2a8f6d, 0xbc04f974, 0xbd1fdeb0, 0xbd3aed78, 0x3c4628e8, 0x3d2145d5, 0xbb6fd580, 0xbc8fa2da, 0xbcced14a, 0xbadfd860, 0x3ce723f6, 0xbd28aca5, 0xbca54a13, 0x3d45bed1, 0x3cd6db22, 0x3c8338ba, 0xbd45e5e7, 0xbd330b0d, 0xbce8685d, 0xbd47ad03, 0x3c0cfcc0, 0xbd2a62ba, 0x3cbd023a, 0x3d49da49, 0x3c23ee28, 0x3d2c5c47, 0xbcf8b1b0, 0xbd2c365b, 0x3c59734c, 0x3ce80486, 0x3d464e63, 0xbd2d7b1f, 0xbc804414, 0x3d463d95, 0x3ce1367a, 0xbd332f6f, 0xbc972fda, 0x3cca32e6, 0x3d23aff5, 0x3d3fb20d, 0xba892400, 0xbca38ac3, 0x3b883350, 0xbcfe11c7, 0x3d3bf377, 0x3bc73210, 0xbc61e0ac, 0xbd131c43, 0x3a0ddc80, 0xbca5ecbd, 0xbd0f1b78, 0x3c69512c, 0x3d35d1f1, 0x3cc28532, 0xbbff91c0, 0x3b51c780, 0x3c03fcc8, 0x3cb255a2, 0x3c230300, 0x3d0815e7, 0x3bacb8c0, 0xbd039c7a, 0xbb3584d0, 0x3d1bfac9, 0xbd3ae958, 0x3cefc6a2, 0x3c235ae8, 0x3ccab992, 0xbd370b4b, 0x3a732200, 0xbd461592, 0x3cc961f6, 0x3c838242, 0xbc9cced3, 0x3d27de81, 0xbc8344fc, 0xbc7faee8, 0xbd1e254b, 0x3d469e51, 0x3ce20ebe, 0x3c2f144c, 0xbc357d2c, 0xbc3620e8, 0xbc04a334, 0x3c5956a4, 0xbc8ba3c4, 0x3bca29e8, 0x3d17d1e3, 0xbba196e8, 0x3c8c295e, 0x3d2c4267, 0x3c983e9e, 0x3d09932f, 0xb9cddb00, 0xbd090ac2, 0x3c2467e0, 0x39fd2400, 0x3d0f0b43, 0x3ca1e1d6, 0xbba80d18, 0xbcc25020, 0xbcc3dcb0, 0xbbe231e8, 0xbd26d855, 0x3adee9c0, 0x3d3ef06f, 0xbd2c23e5, 0x3d2cba01, 0x3cd42aca, 0x3ac605a0, 0xbcc3951a, 0x3b32c4b0, 0x3ce38f9a, 0x3a6874c0, 0xbb147a00, 0x3c7019a4, 0x3c9e6102, 0x3b0e2d80, 0x3c7dbafc, 0xbd20fbd8, 0x3d436619, 0xbd434c55, 0x3bc58228, 0xbd3591bd, 0xbbd1a028, 0x3c163ff8, 0xba18cb80, 0xbc6d2034, 0xbbc6aaf0, 0x3d1be929, 0x3cf2d14e, 0x3d3ecf11, 0xbce0bd70, 0x3cf668b2, 0xbd304c52, 0x3d0f5a29, 0xbb3c8050, 0x3d2a76fd, 0x3cdfec42, 0xbc131ed4, 0x3c8715da, 0xbced47e0, 0x3caca7c2, 0xbb68ff00, 0xbd2bfced, 0x3c6bbf0c, 0xbd313687, 0xbba436a8, 0xbcd181d7, 0xbd37cf83, 0x3c5b8504, 0xbd082a58, 0x3c96080e, 0x3cde49b2, 0x3a8d1bc0, 0xbd32c9b7, 0xbbaeaad0, 0xbc80155c, 0xbc08e3a8, 0x3ca31582, 0xbbea7eb0, 0x3d4b33a9, 0x3cd27dda, 0xbc883e6c, 0xbc9deb03, 0x3ceda292, 0xbc9d334a, 0x3cab4f56, 0x3d46cadd, 0xbd339477, 0xb98b6900, 0x3c947fb6, 0x3d023c31, 0x3c99d8a2, 0xbd1473f8, 0x3c3642c8, 0x3d2980c5, 0x3c5b1c54, 0x3d3bb0f1, 0xbd031e18, 0xbad1c9a0, 0xbccc6d0a, 0x3c952096, 0xbcaa9d87, 0x3cf9b81e, 0x3bfe83a8, 0xbc9c417a, 0x3af637c0, 0xbca5ffc3, 0x3cf64072, 0xbc8c5214, 0xbcb6240d, 0xbd30cb48, 0xbc1c45cc, 0x3d3953f1, 0xbc29d26c, 0xbd33c0e5, 0xbd130e08, 0xbd2e02cb, 0x3acbdc60, 0x3cef5bae, 0x3d0197ed, 0xbd1cff72, 0xbd11b5a0, 0x3d1b8873, 0xbd38de4d, 0xbd476057, 0x3d239081, 0xbc05e78c, 0xbc94c6f0, 0x3d00f2b7, 0xbbeb7c68, 0x3d307db1, 0x3d2f397f, 0x3d3b5935, 0x3c114f98, 0xbcc65a4a, 0xbd34016d, 0xbd05a335, 0x3d0d3551, 0x3c59b1c4, 0xbd235a40, 0xbd0a2bea, 0x3ccc2556, 0xbbfd6258, 0x3cd81886, 0x3d41dcc5, 0x3d37ecf7, 0x3cae1086, 0x3c73a234, 0x3d1c71a9, 0xbd3ca15d, 0x3d43e907, 0x3c94baae, 0xbd4b5aca, 0x3d09daff, 0x3c53a574, 0xbcf09773, 0x3b3b13b0, 0xbd27229d, 0x3d2593df, 0xbd2c7f62, 0xbd1eca76, 0x3c0888c8, 0x3b860140, 0xbcb67bb0, 0xbcf435aa, 0xbd2e8ce2, 0x3b89b750, 0xbccdf04a, 0xbcdbd9fd, 0xbc1118c0, 0xbd4c0207, 0x3ca91bf2, 0x3d2e3cd1, 0xbc160cac, 0x3c9bfa22, 0x3c031e94, 0xbbd129b0, 0x3d25f675, 0x3cda9792, 0x3d2aedb3, 0x3d412a1f, 0xbd0a4846, 0x3cdd4c76, 0xbcc4248a, 0x3c27b0a0, 0x3a615940, 0xbc66b220, 0xbd2e8bb8, 0x3d49ae11, 0x3d4332d9, 0xbcfc2100, 0xbd2ac383, 0x3cd667c6, 0x3d0c976d, 0x3c85c5fa, 0x3ba20c28, 0x3cf6ef96, 0x3c4b5c68, 0xb9b6ba80, 0xbcbafbf7, 0x3b0a1ee0, 0x3cee6332, 0xbc404a0c, 0xbc0f05f8, 0x3d1b3bcb, 0x3d4820bf, 0x3d2c90c9, 0x3d0d3843, 0x3b7f07d0, 0xbc6e3cd4, 0xbd017f98, 0xbbe09b70, 0xbc564360, 0x3d310a81, 0xbc68efa0, 0x3aaa1800, 0xbd4b4008, 0xbb92add0, 0x3d0a26d3, 0xbb03ccb0, 0xbb88e0d8, 0xbd0d3143, 0x3cd98022, 0xbcfba76a, 0xbcb0efaa, 0xbcb783ed, 0xbd2702ea, 0x3c23e634, 0xbd368ec2, 0x3bbb2b18, 0x3d43a38b, 0x3c07f7f4, 0x3c0f2cc0, 0xbca0230a, 0xbd451f0a, 0xbc8313cc, 0x3d4670e1, 0xbd406357, 0x3cbf59fe, 0xbca8e0ed, 0xbcb9bb3d, 0x3c817452, 0x3c900d2e, 0x3bd8d158, 0xbd2977c3, 0xbc3dd788, 0x3d12260f, 0x3cff63ea, 0xbcdeb8c3, 0xbced00da, 0x3ce76e82, 0xbcc8f677, 0xbc6648b4, 0xbd449ada, 0xbc9af66d, 0xbcbf552d, 0x3cdb28da, 0x3a1a6680, 0xbd1d79c0, 0xbcef2c2a, 0xbbf520b0, 0xbabc0a00, 0x3c8d280a, 0xbc989136, 0xbd0a489a, 0x3c368168, 0x3cc19ade, 0x3d2c7f03, 0xbd322e52, 0x3cb94f62, 0x3d0b907d, 0xbcb2682a, 0x3c09f140, 0x3bd4a1e8, 0x3d2550e5, 0xbced6c9d, 0x3d1c208f, 0x3d029b61, 0x3c80bfd6, 0x3c868faa, 0xbcd907aa, 0xbd31def2, 0x3d1d9951, 0x3cd8f40a, 0xbcf5fbd0, 0x3c9fcf6e, 0x3d32e6bf, 0xbc598380, 0xbd404c47, 0x3d030313, 0x3add26a0, 0xbc23c368, 0xbcbc4ff7, 0xbcfb37d7, 0xbd0f0d1a, 0x3d2cea83, 0xbcfc20f7, 0xbc3e6fa0, 0x3d28f981, 0xbc44ed28, 0xbc5752c0, 0x3bd6f0a8, 0x3d47bcb9, 0xba1b8b80, 0x3d00db71, 0x3b4f5150, 0x3c180534, 0x3ac24e00, 0x3d23a575, 0xbcb0afaa, 0x3c3df058, 0x3bdacd10, 0xbc2f4de8, 0xbcebcbad, 0xbc044674, 0x3d2a7241, 0xbd351873, 0xbcc99800, 0x3c644aa4, 0xbc93dba0, 0x3bd56c70, 0x3c22a874, 0x3c29316c, 0xbccde2fa, 0x3d04bf69, 0xbd2b2bd2, 0x3c24f6b4, 0x3d006067, 0xbd016525, 0xba8bdcc0, 0x3c7f18dc, 0x3cfa8832, 0xbc4c5414, 0xbcdd47ca, 0xbcfd17f3, 0x3d3dfcef, 0xbc986150, 0xbc7f99f8, 0x3d47203f, 0x3c1df868, 0xbcb19b1d, 0xbcec124d, 0xbc249dac, 0x3c8d9db2, 0xbcb76dc7, 0xbc90ab9a, 0x3d2d7e8b, 0xbd0ecbfb, 0x3b9ad180, 0x3d229639, 0xbd44e212, 0x3c86b72e, 0xbc825a46, 0x3cb2e2c2, 0x3ce0e25a, 0x3ccd776a, 0xbbec5d28, 0xbb71f950, 0x3c998342, 0xbc0e10a8, 0x3d38ba4b, 0x3d1626a9, 0x3cc00aa2, 0xbd3bfb45, 0x3c43b2d8, 0xbc601b14, 0x3bae2280, 0xbb8abdd0, 0x3d3ef73d, 0xbd47cbeb, 0x3d18422b, 0xbd079f7c, 0x3adfe460, 0x3d3962e7, 0xbd1ec823, 0x3ce4f25a, 0xbc419248, 0x3d0f8593, 0x3d39e519, 0x3d279cd7, 0x3ca695e2, 0xbce8d18a, 0x3c8369fe, 0x3c7b33dc, 0x3c92c912, 0xbd02a74e, 0xbce951ea, 0x3cddb652, 0xbd438bb0, 0x3c670944, 0x3d077419, 0x3aee6d40, 0xbcccddda, 0x3cd07792, 0x3aeb1140, 0x3d00ab6d, 0x3cdab052, 0xbc83a6c0, 0x3d378b65, 0x3d18ca3f, 0x3b5e9dd0, 0xbca3cd5d, 0x3cc7db5e, 0x3cece702, 0xbcdb7367, 0x3d2e6291, 0x3d23da33, 0x3c4d13ec, 0x3c9fef32, 0xbd25bf5b, 0xb9252b00, 0x3ad8d6a0, 0x3c337420, 0xbb6c2bd0, 0x3d031713, 0xbc4f236c, 0x3c51b244, 0xbc44ad4c, 0x3c9474f2, 0x3c063458, 0x3c13228c, 0xbbbba390, 0x3b4f2c60, 0xbc20288c, 0xbc1c6ec0, 0x3d2342e9, 0x3c6b03fc, 0x3b9fd890, 0xbbe72070, 0xbc351b0c, 0xbc4d3e14, 0x3cbe837a, 0xbb30cb30, 0x3ce17856, 0xbb8c5a58, 0x3c074738, 0x3c382288, 0xbbcd2b28, 0x3c82507a, 0x3b2a0b60, 0x3d44130f, 0x3c10d9e0, 0xbabce6a0, 0xbadf8600, 0xbb739c80, 0xbc600f80, 0x3c82c276, 0xbd2226f5, 0x3d3ff37f, 0x3d4426ad, 0x3d22f737, 0xbc591d08, 0xbd24f663, 0x3bdd6390, 0xbd386275, 0xbc866100, 0x3c695014, 0x3c814c0a, 0x3d3f3311, 0xbc6bc1e0, 0x3d32ca43, 0x3cb7d7ae, 0xbba1e9d0, 0xbd4bd5fa, 0x3ba978d8, 0xbca2af5a, 0xbb2bc200, 0x3cb7bb0a, 0x3d0ba59f, 0x3d169ef1, 0x3b0a2650, 0x3d1fc229, 0x3cfa4662, 0x3c9529de, 0x3cd13772, 0x3cd6f05e, 0xbca93473, 0xbcafe123, 0xbd02a278, 0x3c3c0cd4, 0x3c894c4a, 0x3c41bd00, 0x3c5ca0a4, 0x3d1b717b, 0xbcd16950, 0xbc7de328, 0xbd3cf5ef, 0xba650800, 0xbd3e2408, 0xbb54cbb0, 0xba0f8cc0, 0x3cd82822, 0x3d3d792f, 0xbc9516b4, 0x3b1d1d50, 0x3d368979, 0x3c5e6dec, 0xbd3cf378, 0x3d3a8635, 0xbd4662e0, 0x3ca3eb6a, 0x3bd87628, 0xbd4aa05b, 0x3cc1540a, 0x3d11f57f, 0x3c6448c4, 0x3a90a600, 0xbd25e66b, 0xbd3333bf, 0xbc35e6e8, 0xbca0f943, 0x3b20bee0, 0xbd1881d8, 0x398e8580, 0xbd1f24b5, 0xbc42176c, 0x3d46a8a7, 0x3d17a7fd, 0x3ca6c69a, 0xbc153748, 0x3bb1acf0, 0xbd2a041b, 0x3caf685e, 0x3ac27160, 0x3c1830a0, 0xbc5498b8, 0x3c462634, 0x3d08fa25, 0xbd1eb5a2, 0xbc1f14d4, 0xbceeee57, 0x3ceae45a, 0x3c4c2028, 0xbca0930a, 0xbcad99ed, 0xbd01bb5a, 0xbc541b68, 0x3d47d671, 0xbc8964d0, 0xbc3b78f8, 0x3cbf18fa, 0x3d2a8f6d, 0x3bad6668, 0xbcc31657, 0xbcdf69d7, 0xbc216f8c, 0xbc76a434, 0x3d06df89, 0xbd2d9123, 0x3c8ffc22, 0x3cd98b1a, 0xbb93ef10, 0x3d4a7163, 0x3d0d6471, 0x3c02b808, 0x3b9e7940, 0xbc331560, 0x3cfa9c82, 0x3cd98a2a, 0x3ad2af00, 0x3d16e8bf, 0x3d04c911, 0xbcb0a740, 0x3d0eae19, 0x3d42eb55, 0x3c9cf206, 0x3d3a18c9, 0xbb4e7e50, 0xb9f4ad00, 0xbcf3437a, 0xbd2d651f, 0x3c2297ac, 0xbd3bb2c8, 0xbc5efd4c, 0xbc949774, 0x3cc4f6a2, 0xbd0a815a, 0x3cee9902, 0xbcbb15a0, 0x3c82e192, 0xbd1b7e8e, 0xbcf11be0, 0x3bbbe510, 0xbce9d433, 0xbd13d5bb, 0xbc6815ec, 0x3c89ceb2, 0x3cee4ede, 0x3c6b3384, 0xbd112576, 0xbcda1fa3, 0xbc8a3dca, 0x3c51d724, 0x3cf2124a, 0xbbe8eeb0, 0xbcdb7f5d, 0xbd2cc46e, 0x3d3909f3, 0x3c75b3fc, 0x3d1b4d4f, 0x3c8dcb66, 0xbbf7bad0, 0x3c82e00a, 0xbca273e7, 0xba8bc8a0, 0xbc7053f8, 0x3c9c67ae, 0xbb958c40, 0x3c20db00, 0x3c1b5a28, 0xbc9967d0, 0x3ca42a9e, 0xbce59ef3, 0xbd31c562, 0xbd01404c, 0x3d06f385, 0xbc8bcd74, 0xbb05c3b0, 0x3cbbf1f6, 0xbcf06560, 0x3d13e9e9, 0x3c083118, 0xbd183ebb, 0x3cda6dd6, 0xbd29999b, 0xbabd2ea0, 0xbce821b0, 0x3c419c60, 0xbd2b8af8, 0x3d1f3849, 0xbca0c1ca, 0x3c5a8f1c, 0x3d1ce21b, 0xbcaf98e0, 0x3d3c0893, 0x3d0a853f, 0x3cf646aa, 0x39affb00, 0xbd389690, 0xbd4b39d3, 0xbb503720, 0xbbb53590, 0xbbd704b0, 0xbc37d514, 0xbd0719dd, 0xbae6c6a0, 0xbcdbf147, 0xbc20dd08, 0xbd4c05fd, 0xbc81f7f0, 0x3bf4ba30, 0x3cd79452, 0x3d452637, 0xbc461978, 0x3beec000, 0x3d338637, 0x3c9bf462, 0xbd32ee0f, 0x3c22b3a0, 0x3d29b317, 0x3d3c7313, 0xbc376740, 0x3c8c37a2, 0x3d0ca591, 0x3b46b2a0, 0xbc4f2848, 0x3c721f2c, 0x3c8cd96e, 0xba25f740, 0xbbd8b2e8, 0xbb5a3650, 0xbc22d698, 0x3cd440fe, 0x3d1f4db9, 0x3d4323b9, 0x39689e00, 0xbd07b34e, 0xbccfa89a, 0xbb9e7b28, 0xbd494eaa, 0xbd385b07, 0xbbb5fa98, 0xbcbaf4d7, 0x3cc7dc46, 0xbcb7a5dd, 0xbb0a16b0, 0xbb51f160, 0xbd3c0b1a, 0xbc1142ec, 0xbd3f8dd5, 0xba843260, 0x3ca5cc22, 0xbd26a015, 0xbce361f0, 0xbc10a48c, 0x3c9f7b6e, 0x3c9287de, 0xbc81e2a4, 0xbd37b89b, 0x3d480471, 0xbd14a0eb, 0x3d234b61, 0xbc89835c, 0xbcbccc1d, 0xbd291efa, 0xbcf1d68d, 0xbbd96c40, 0xbcb922aa, 0x3c80bdfe, 0x3c7c8024, 0xbd105d62, 0x3d244d31, 0x3cbbe22a, 0xbcb32eb7, 0xbcd1cb73, 0x3d0e8799, 0xbb920a68, 0xbd2e2b60, 0x3cbdb9e2, 0xbcfa0777, 0xbd06be54, 0xbd24d3bb, 0x3d3683c3, 0x3ceffe3a, 0x3ccc9cca, 0x3c3e2b00, 0x3ca3238e, 0xbd37e2b0, 0x3d11c961, 0xbd4ae8a3, 0xbd486c65, 0xbb8237e8, 0x3d30f539, 0x3d14c629, 0xbd4193eb, 0x3d26de35, 0xbd25110b, 0xbd1cc35a, 0x3c810422, 0x3d3cb60d, 0x3d48e591, 0xbd044924, 0x39545e00, 0x3d09ce5f, 0x3cef5336, 0xbb5d5b50, 0xbd037c0c, 0xbcb4b237, 0x3d4a11b9, 0xbcf4825a, 0xbd168eca, 0xbd2f5fad, 0xbba23d80, 0x3ceb122e, 0x3b070ed0, 0x3c4e9b4c, 0x3c580244, 0xbd461647, 0xbbc52830, 0x3d2c6e15, 0xbc8c15cc, 0xbd0d8fd2, 0x3be4a1f0, 0xbc210068, 0x3ca9a456, 0x3cc74eba, 0xbd1a8588, 0xbc784c48, 0x3c8cfe52, 0x3d2dafa9, 0xbc666754, 0x3cbad202, 0xbbdb5b28, 0x3c49e0f8, 0xbd3035cf, 0x3cc6bd0e, 0x3d17fb77, 0x3b60c620, 0xbd34bfc3, 0x3cdd6aa6, 0xbd1da1de, 0xbd1d27b2, 0x3ba27e28, 0x3cde5c2a, 0xbd4c18b2, 0xbcbcc0fd, 0x3b6fb6e0, 0xbc227260, 0x3cc3e3e2, 0x3cda3926, 0x3c0f5880, 0x3d452a2f, 0xbcca98d0, 0xbd462d60, 0xbd0ba370, 0x3cd64fb2, 0xbd4a8e37, 0xbd05dfee, 0xbc1a9bd4, 0xbd268438, 0xbcf40b2a, 0xbd4a88bd, 0x3c603f74, 0xbba3e3f0, 0xbbd827a8, 0x3c8485b2, 0xbd3ee2c2, 0xbd466335, 0x3c846b4a, 0xbd3703c0, 0xbd0ffab3, 0xbca240fd, 0x3ceacad2, 0x3c4fbdb4, 0x3c0c45c8, 0x3d05a8d5, 0xbc5c3f28, 0xbd3ea837, 0xbd129b55, 0x3cb3689a, 0x3d26abd1, 0x3d0cf0e3, 0xbcbe0683, 0x3ce1872a, 0xbc4cca28, 0xbc85cbca, 0xbb3e8460, 0xbd0e79e3, 0x3c89b682, 0x3d382369, 0xbd0e41a0, 0x3c99454a, 0xbad781c0, 0xbc811614, 0xbd37d59f, 0xbcc4fdb3, 0x3b3baa60, 0x3d470b9b, 0xbcb15893, 0xbd2e08ef, 0xbcab4813, 0xbbdd75e8, 0x3d092ff3, 0x3d091ac5, 0xbcbe0f03, 0x3d009871, 0xbd1deac2, 0x3d47da6f, 0xbc7323f8, 0x3ce8096e, 0xbcc2410d, 0xbcffbc97, 0xbbbd9830, 0x3d459729, 0xbc136060, 0xbd0330e4, 0xbce041ed, 0x3c98ac5a, 0xbd10a4b2, 0xbd3e3037, 0xbd206468, 0x3d34e981, 0x3c389ea0, 0xbd242522, 0xbcbe9850, 0xbcd60ee7, 0xbcfb070d, 0xbb028f80, 0xbbea97e8, 0xbbaa1f28, 0x3d18b097, 0xba530cc0, 0x3d1a05c9, 0xbd17b3ba, 0x3c81adf2, 0x3d21a6a3, 0xbd302f33, 0xbd28c162, 0xbc43e194, 0x3c277c58, 0xbcd14130, 0xbb89d3a8, 0xbc3f92d8, 0x3d3b5e07, 0x3bdde368, 0xbcec6d4d, 0xbbbdede8, 0xbabb21c0, 0x3cddbbd6, 0xbd25cc2e, 0xbc6c92c8, 0xbccb1030, 0xbcdc1163, 0x3cfb8c12, 0x3d3f2e85, 0xbd3707b8, 0x3c282b20, 0x3b7145d0, 0xbd115813, 0xbbc6f800, 0xbd103956, 0x3ba25528, 0xbd2697ab, 0x3cfb773a, 0x3d38ad2f, 0x3bf5df80, 0x3c631b0c, 0x3d46ce7d, 0xbc743eec, 0xbc589f8c, 0xbd3a9070, 0xbd2e9e9b, 0xbccaef27, 0xbcf61793, 0xbcfd47a0, 0xbd048d2d, 0x3c33edc8, 0xbca6d920, 0x3d16f5a3, 0x3bd1a650, 0xbc916a34, 0x3ca1a002, 0x3b86b698, 0x3cc09626, 0x3d382fdf, 0x3cd125ba, 0xbcc69920, 0x3bd58e18, 0xbb379360, 0x3ccf4b92, 0x3d3c2fd1, 0x3be5cd10, 0x3926e600, 0x3d1a42b1, 0x3c4412cc, 0xbc251cac, 0xbcba31ea, 0x3c98b6b2, 0xbbb536b0, 0x3c8b7ca6, 0x3cb01d82, 0x3cac849a, 0x3c575ec4, 0xbc6ff768, 0xbd43457b, 0x3bc20340, 0xbcfe39ba, 0xbd2dcad5, 0x3d1c6923, 0x3d20d2a9, 0x3ccd6d42, 0x3d140969, 0xbd47ea7f, 0xbc9d1967, 0xbad11440, 0x3d3fd6b3, 0x3d0406db, 0xbcd0d390, 0x3d0117c9, 0xbb4abfd0, 0x3ca4b0a2, 0x3d3c14df, 0xbcc52653, 0x3be00400, 0xbc633560, 0x3b9ba198, 0xbca1ecad, 0xbd148732, 0xbcf05240, 0x3d3c4535, 0xbd2df2a7, 0x3bdc7bf0, 0x3d1a9d01, 0x3b04afd0, 0xbcbf7093, 0x3d10cf11, 0xbd20fecb, 0x3c5a2294, 0x3cfaa8c2, 0x3d4544a1, 0xbb778fb0, 0x3bd6c468, 0x3c533e64, 0xbb03f380, 0xba8cc760, 0xbd1b780a, 0xbc33f834, 0x3ca93136, 0xbcee5fa7, 0x3d4824bd, 0xbc8c2364, 0xbc96c32c, 0x3b5274b0, 0xbd40acb2, 0xbb0aa3b0, 0x3c5e3a04, 0x3cb05e5a, 0xbbf5a490, 0xbd469270, 0xbcb1613d, 0x3c4d4104, 0x3d29fd19, 0xbd3ca957, 0xbd367eca, 0xbcf4b8b0, 0xbd4899d8, 0x3c4ad04c, 0x3cd504aa, 0xbd292aa0, 0xbc93fb1a, 0xb8927000, 0xbcb399bd, 0xbcb1882d, 0x3cdf1e82, 0xbd154a58, 0xbba65590, 0x3d223bf5, 0xba21a2c0, 0x3c9cadfe, 0xbccd19c3, 0xbd063e1e, 0x3d2fa8af, 0xbcaad777, 0xbd493cf5, 0xba19c780, 0x3cdf4afe, 0x3cf71c46, 0xbd0e8150, 0x3d2b94df, 0x3c9890e6, 0xbc875256, 0xbb92a798, 0xb8d05400, 0x3b83e610, 0xbcf30377, 0xbc970b7a, 0x3cb85f32, 0x3d0aeb31, 0xbd100dc5, 0xbd2ec743, 0xba81f1a0, 0xbcd2f36a, 0x3c8b8912, 0x3cd213ce, 0xbcd8505a, 0x3caf84ca, 0xbd1a1f43, 0xbd22fc05, 0xbc38fb40, 0x3c29ffa8, 0x3d21e4f9, 0x3d336049, 0xbc29fb14, 0x3d4c8f65, 0x3d0156b9, 0xbc9c1a63, 0x3bf1d810, 0x3d2f3379, 0xbcc6024d, 0xbd2b784e, 0x3cc61f72, 0x3bcad3e8, 0x3d1d16c7, 0x3c493368, 0x3d4a3853, 0x3d2f9a0f, 0xbd18cc55, 0x3ca27c92, 0xbc0e0578, 0x3d2f9f6b, 0x3d25c15f, 0xbccba443, 0x3d2861f9, 0x3cdd1c26, 0xb9bba980, 0x3c215ce8, 0xbc6fe358, 0xbd436fd3, 0xbc5fa958, 0xbcfd9ef3, 0xbc2e3d88, 0x3c9630be, 0xbd019f08, 0x3c552b0c, 0x3ccead72, 0x3d3161b5, 0xbd349167, 0x3cfb291a, 0x3baf3a70, 0xbd30eaef, 0x3d36d16d, 0xbbff9db0, 0xbd05cfe5, 0xbd46d333, 0x3a5d36c0, 0xbd2f322b, 0x3c6ea574, 0x3cc23a2a, 0xbd087a4d, 0x3c9e21b6, 0x3c8b4572, 0xbcfb10fd, 0x3d256731, 0x3ca1cd0e, 0xbd4060a8, 0x3c9c80e2, 0x3d0bb7b1, 0x3caec47a, 0xbca2cfaa, 0xbcd33083, 0xbbd930f0, 0x3d2a8e01, 0x3a034b80, 0x3c964966, 0x3d2e454f, 0xbd1daa35, 0x3d42e051, 0x3cb0dc8e, 0xbd03e9f0, 0x3ce23c82, 0x3d2b9c51, 0xbad26360, 0x3cf6b6c2, 0x3c5ccecc, 0x3d0d4d23, 0xbd2023dd, 0xbd080fdd, 0x3d27cddf, 0x3d4c3a39, 0x3c8303fa, 0x3cce2002, 0xbd420ceb, 0x3ce895e2, 0x3d1dd9a3, 0xbc269ba0, 0xbcce26cd, 0x3ce6a7ea, 0x3cbdf30e, 0xbd48fe87, 0x3c5c97a4, 0x3c961dfa, 0x3c323fb4, 0x3d1aa5ef, 0xbb308e50, 0x3d0699af, 0x3cbf1eb2, 0xbd0a3460, 0x3ba9a618, 0xbcdfe007, 0xbc13b634, 0xbc5bbbe0, 0x3d2a4e3f, 0xbcd5f22a, 0x3c76f9f4, 0xbc9b65cd, 0x3cb59b36, 0xbcaa9fd0, 0x3ccb71da, 0xbd38c728, 0x3cc6f0ca, 0xbd1d5c6a, 0x3d320255, 0xbd3a9ed5, 0x3b3d4930, 0xbd3aaa4d, 0x3c9e2a82, 0x3be26210, 0x3b52f560, 0x3cbaf15a, 0xbc9efa8a, 0xbd0726e6, 0xbd2c5ebd, 0xbd0af8a2, 0x3d26a0d7, 0x3cc926b6, }; // 5 uint32_t bias_vals[] = { 0x3bded4d8, 0x3c9d39d2, 0x3ca89fd2, 0xbc5af538, 0xbcb69fcd, }; // 3,1,1,5 uint32_t output_exp_vals[] = { 0x3c0f5041, 0xbd5feb0d, 0xbe2ac302, 0x3e4629df, 0xbf31fe38, 0x3e5c01b4, 0x3e7c96f6, 0xbce63e5a, 0x3e379fba, 0xbf3027ad, 0xbdb021b6, 0xbe97d08d, 0xbef57ffa, 0xbdfbe7fc, 0xbf1bf24c, }; // 3,1,1,5 uint32_t output_relu_exp_vals[] = { 0x3c0f5041, 0x0, 0x0, 0x3e4629df, 0x0, 0x3e5c01b4, 0x3e7c96f6, 0x0, 0x3e379fba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, VALID_PADDING, NULL); } void test_valid_padding_zero_strides_medium_with_clip() { input_set *set = &medium_input; strides_input_set *strides = &zero_strides; // 3,10,8,5 uint32_t input_vals[] = { 0x3f36b631, 0x3b9ca600, 0x3f76ac7f, 0x3d3f3570, 0x3e70e1b4, 0x3e3830f8, 0x3f3f9678, 0x3e1fb9dc, 0x3dd55dd0, 0x3aef4000, 0x3f433347, 0x3df08b90, 0x3eb33e84, 0x3dc553c8, 0x3ee7a2f2, 0x3e377d78, 0x3f3e7fdb, 0x3f1236d7, 0x3ea73b60, 0x3e0cc410, 0x3f57cffe, 0x3f1253af, 0x3eeea1d6, 0x3f116d9b, 0x3de6adb0, 0x3f335bd0, 0x3f459139, 0x3f221418, 0x3e089dac, 0x3f208980, 0x3ec148ac, 0x3dfe44a8, 0x3f434e54, 0x3f207099, 0x3f6d610b, 0x3f4929fb, 0x3f6fef6c, 0x3e96ad46, 0x3f4d17d4, 0x3e9b4166, 0x3eabb14a, 0x3b020c00, 0x3f09f77a, 0x3f68586f, 0x3ef184c6, 0x3f1b4509, 0x3df6bf78, 0x3f73cdae, 0x3f71564c, 0x3e0d0f10, 0x3f25afae, 0x3f4cc291, 0x3e5e4880, 0x3f544618, 0x3f165f1a, 0x3f0d128c, 0x3f0459a7, 0x3e24cc88, 0x3eb49e0a, 0x3f247e0f, 0x3f19b458, 0x3e607e7c, 0x3deeb150, 0x3ee86844, 0x3ed8b3e2, 0x3efaeafa, 0x3eca4cde, 0x3f4c835c, 0x3f71404c, 0x3f6162dc, 0x3eb60aea, 0x3d6169d0, 0x3d298250, 0x3f3facbb, 0x3dc7db50, 0x3f476996, 0x3d84cdb8, 0x3e8381c8, 0x3ebc1c56, 0x3edda720, 0x3f327cb8, 0x3ec91382, 0x3f567352, 0x3f60a3cf, 0x3e63cdd0, 0x3f2fbe4e, 0x3f61a525, 0x3e4d10dc, 0x3d8119d8, 0x3f706446, 0x3f566a2d, 0x3f263a00, 0x3f68176a, 0x3f6d8d15, 0x3f6c6af8, 0x3e741c84, 0x3f182317, 0x3e885446, 0x3f479de4, 0x3f7de85f, 0x3ec4857c, 0x3ebc271a, 0x3f143fe7, 0x3e0877c4, 0x3f75c402, 0x3ef8b408, 0x3f748088, 0x3f10c163, 0x3dbccff0, 0x3f32b1fc, 0x3f674b45, 0x3f0139d4, 0x3ef9b882, 0x3f64196c, 0x3defe888, 0x3dd093e8, 0x3f2b3835, 0x3f4fb95d, 0x3f7e460c, 0x3e24b3c8, 0x3e5a5130, 0x3f0208d2, 0x3f6cb694, 0x3f0b2b70, 0x3f1eaf41, 0x3ec30552, 0x3f13f950, 0x3e405394, 0x3e9bf8c4, 0x3d5b8a00, 0x3d954c60, 0x3f2aaf0d, 0x3f47c963, 0x3f48e285, 0x3f5108e1, 0x3dd6f800, 0x3f623988, 0x3f22332e, 0x3f39bf14, 0x3f37a5a6, 0x3f57aec5, 0x3f49ad86, 0x3efb3ac4, 0x3ee00cf8, 0x3f1e8a44, 0x3f05f896, 0x3f10619b, 0x3e1a016c, 0x3f667a9f, 0x3d823af0, 0x3dc83748, 0x3f332ca5, 0x3f25f83e, 0x3f52f762, 0x3f5d1d04, 0x3ed5bac2, 0x3eb30346, 0x3f5ce83e, 0x3f1fe917, 0x3ee4e7f6, 0x3ef79562, 0x3f577e28, 0x3d910f88, 0x3f427613, 0x3e94929e, 0x3ea4fce6, 0x3f23ee9a, 0x3d1c8fb0, 0x3d01a550, 0x3f42d47f, 0x3da77a08, 0x3f60995e, 0x3c0a9380, 0x3e88165e, 0x3f0ad115, 0x3f45a98a, 0x3ed80798, 0x3f1d936a, 0x3f0e07fa, 0x3e8e1ef2, 0x3ee0618c, 0x3dbbedc8, 0x3eb6713c, 0x3f22cf06, 0x3f1df573, 0x3f7cf87a, 0x3f19492d, 0x3eb07ab6, 0x3edd0088, 0x3e2a9198, 0x3defc080, 0x3f340f50, 0x3f773033, 0x3f3054c9, 0x3f76f70a, 0x3e66eb1c, 0x3f676d3a, 0x3ebeb408, 0x3f26fe18, 0x3f703110, 0x3ef2b336, 0x3f319c97, 0x3e3adb10, 0x3d1b3af0, 0x3f3b0802, 0x3e1b7498, 0x3f2f4afe, 0x3f0b8386, 0x3f285fa0, 0x3f43b72e, 0x3f5d486b, 0x3f65dcf2, 0x3e66fba4, 0x3eeb2f94, 0x3b42bd00, 0x3f62fc54, 0x3ea805d4, 0x3eb4fe52, 0x3e1fab68, 0x3e6362b8, 0x3f73f5a9, 0x3f7103c8, 0x3f439d03, 0x3f0451db, 0x3c9a8dc0, 0x3e3ccb48, 0x3f419ff7, 0x3f1d8aa7, 0x3ec10a20, 0x3e752480, 0x3f5b1273, 0x3f557bf6, 0x3e20a7b0, 0x3e701b88, 0x3daf0738, 0x3f58dfea, 0x3f5b49d0, 0x3f79dc64, 0x3d35c960, 0x3f5e3797, 0x3e9a238c, 0x3dbb67a8, 0x3f56999b, 0x3f6b147d, 0x3f450ebd, 0x3f0e0ba6, 0x3f42ab7d, 0x3e22fa34, 0x3e491070, 0x3f4b6181, 0x3f3cfea2, 0x3f773612, 0x3f37c12c, 0x3f11311c, 0x3e8e5a48, 0x3f5b9871, 0x3e184f28, 0x3f349900, 0x3f668a71, 0x3f618f59, 0x3d072ca0, 0x3eea0f1e, 0x3e109d28, 0x3edfbf9c, 0x3edb0210, 0x3f7f6eff, 0x3e478798, 0x3e182b74, 0x3e306d94, 0x3ebdac5e, 0x3ebfa2ce, 0x3ec22efa, 0x3db01a70, 0x3c854b20, 0x3f44eb5b, 0x3f342728, 0x3f131358, 0x3f390480, 0x3f154485, 0x3f54c400, 0x3e4200a0, 0x3f4477e4, 0x3f164d00, 0x3e7f1908, 0x3e10028c, 0x3debfcd8, 0x3eb5adde, 0x3f361860, 0x3f0955a3, 0x3f79dc1a, 0x3e254178, 0x3cd96800, 0x3e8f8ee8, 0x3f28e2cb, 0x3ee6297c, 0x3f4b6ffb, 0x3f451d83, 0x3f603f0b, 0x3eb77766, 0x3f22176f, 0x3e81b948, 0x3f47cfda, 0x3f10581d, 0x3f56ca4d, 0x3b0bb400, 0x3f4a6862, 0x3ed19728, 0x3dceec28, 0x3edeafc6, 0x3f0e3fea, 0x3f26b23b, 0x3f6d93ef, 0x3ebf908a, 0x3e99d570, 0x3e814d2c, 0x3f32ea59, 0x3f62acaf, 0x3f4152b9, 0x3e2d777c, 0x3e3f6a7c, 0x3ec70f36, 0x3ec7937c, 0x3f1c251e, 0x3f26d5de, 0x3e951d02, 0x3eaf0570, 0x3f04f161, 0x3ed8d624, 0x3e437414, 0x3efeceba, 0x3e8838fe, 0x3f168c18, 0x3e1a49a8, 0x3f1ae81d, 0x3eb71206, 0x3e61cee8, 0x3ecdd5a4, 0x3e418040, 0x3edfb0b6, 0x3e38040c, 0x3f76051f, 0x3ec0ee50, 0x3f6e6777, 0x3f57f7f9, 0x3f5ba562, 0x3ef21660, 0x3e8c7112, 0x3e5ab544, 0x3e827f6a, 0x3f261474, 0x3e9237d6, 0x3e5cd520, 0x3f5ab4cb, 0x3e81e382, 0x3d0e0a40, 0x3d0e87e0, 0x3f3fecc7, 0x3eaa5012, 0x3edeea7a, 0x3f1ad9aa, 0x3f059183, 0x3eb3fbb8, 0x3f014789, 0x3e4747a0, 0x3f1f716e, 0x3b714000, 0x3e852fde, 0x3c56b680, 0x3f30cc9a, 0x3f04b414, 0x3efcfc4a, 0x3f70c129, 0x3eacc898, 0x3ea23a38, 0x3f1f14e9, 0x3f50d1f7, 0x3f147713, 0x3f6be6c0, 0x3f3483e7, 0x3eea910a, 0x3e591a9c, 0x3f5c5ad6, 0x3d514e70, 0x3f4a49a7, 0x3f37fad8, 0x3f46540c, 0x3f74a543, 0x3f40679c, 0x3f4abe61, 0x3e178ffc, 0x3eae56a8, 0x3edbefee, 0x3da237b0, 0x3ed100d2, 0x3e92d8a6, 0x3dec6e58, 0x3f1317ce, 0x3f12ab4d, 0x3f45daaf, 0x3f5fe2b6, 0x3e42cb94, 0x3f7a260c, 0x3f0d94d4, 0x3e2f4678, 0x3f5da986, 0x3f3ecd03, 0x3f6e32c6, 0x3eb08d0e, 0x3ea099be, 0x3e11011c, 0x3f766f53, 0x3e6611c4, 0x3f5d2b28, 0x3ee70ede, 0x3f658ee8, 0x3d2f4970, 0x3f1d4a31, 0x3d9109c0, 0x3ce695e0, 0x3f7f63bf, 0x3e8fd860, 0x3e3e820c, 0x3f0d6155, 0x3f032f81, 0x3f10d55d, 0x3f6d3b5e, 0x3f02d3a0, 0x3f56b825, 0x3f146fa0, 0x3de117f0, 0x3ef0853c, 0x3f6a0c73, 0x3de4ad70, 0x3e9a66fc, 0x3f18cfc5, 0x3f1944d9, 0x3f3f06b1, 0x3ef8a9a6, 0x3f298468, 0x3ecc4c4c, 0x3f123787, 0x3d1cee30, 0x3f3b25da, 0x3f6fd971, 0x3f5c07c3, 0x3f34bfaa, 0x3e91d31a, 0x3f33a6b7, 0x3ed4457e, 0x3ca0a0e0, 0x3e968518, 0x3da00258, 0x3f0f0d86, 0x3e6f51dc, 0x3f20c172, 0x3f109e04, 0x3f3c4c11, 0x3f33be00, 0x3d69d2d0, 0x3efcff56, 0x3f5730f0, 0x3edf8088, 0x3e1b1620, 0x3e0a22dc, 0x3f0a1397, 0x3eea6736, 0x3e09b75c, 0x3f6a9bfc, 0x3e64d1b8, 0x3f580cd8, 0x3d290cc0, 0x3eae325e, 0x3f02dad5, 0x3e057dd8, 0x3f024ff2, 0x3f2c3e6f, 0x3f2a014a, 0x3f52bd7b, 0x3e9b5a80, 0x3dc798e8, 0x3ebea594, 0x3f0bd9a6, 0x3f1c50ef, 0x3f468365, 0x3e5554cc, 0x3ec9fdf8, 0x3f781a74, 0x3ee3854a, 0x3f280dd5, 0x3e997f22, 0x3f42c1ab, 0x3efc99ea, 0x3f36d3c3, 0x3f735e96, 0x3f0da6b8, 0x3f166eb5, 0x3f284366, 0x3f7982ae, 0x3f7f159b, 0x3f31652b, 0x3e4a43b8, 0x3eb27360, 0x3f7e42e8, 0x3ea3d00a, 0x3ed03742, 0x3e89dd14, 0x3f0f4624, 0x3da20d48, 0x3e9bbeda, 0x3e9af660, 0x3ed915e6, 0x3f0495dd, 0x3f07c35c, 0x3f118423, 0x3f382ace, 0x3ec0c056, 0x3f6df319, 0x3e1030fc, 0x3dd09b68, 0x3c62da80, 0x3ec9ce0c, 0x3f35a223, 0x3f4a9439, 0x3f459f23, 0x3f5971aa, 0x3e220b1c, 0x3e5c371c, 0x3f5be3f7, 0x3ed1ecf8, 0x3ee23da0, 0x3f5cba00, 0x3d643c00, 0x3e187990, 0x3da69340, 0x3f5910ef, 0x3f426233, 0x3cc6e800, 0x3ef1344e, 0x3dfae618, 0x3f60b7f5, 0x3f1942a2, 0x3ea30810, 0x3f5892c1, 0x3e1f3270, 0x3f0dac81, 0x3f1cfb60, 0x3f108bc3, 0x3f54a5b3, 0x3f232e5b, 0x3f287d6a, 0x3f0efc17, 0x3f786b06, 0x3dfe15e8, 0x3f621efb, 0x3e5e68d4, 0x3f5fb5c0, 0x3ee6d8ca, 0x3f55f16d, 0x3f656889, 0x3f5bb5c0, 0x3f1cf6c7, 0x3f320bfc, 0x3ed2ad8a, 0x3eb98256, 0x3f4aeaf3, 0x3f137f9e, 0x3f410d87, 0x3d991dd0, 0x3e569a0c, 0x3ed7cafe, 0x3e668c48, 0x3def9d98, 0x3f197f5b, 0x3e8e60d6, 0x3f31e438, 0x3f2ab320, 0x3db0ee68, 0x3f3ba15f, 0x3e223e2c, 0x3ef1a91e, 0x3d040020, 0x3f308052, 0x3f4cc3a8, 0x3ebdff66, 0x3f640150, 0x3f285ea6, 0x3f3ba978, 0x3e23e124, 0x3d465d60, 0x3f34b0c8, 0x3d886860, 0x3e88cc22, 0x3e0d2ad4, 0x3f446a6a, 0x3f5d5169, 0x3e960c80, 0x3f140f03, 0x3e27fde0, 0x3cf0dd40, 0x3d3a6940, 0x3f43937e, 0x3c2b1f80, 0x3f488a07, 0x3e418210, 0x3f7cb6bd, 0x3e4f0bf0, 0x3f019d08, 0x3d810b18, 0x3f55e69d, 0x3f2fb0bf, 0x3f65ec48, 0x3f1f602f, 0x3efdd75e, 0x3e0104f0, 0x3f3e3b36, 0x3e651c0c, 0x3f01362b, 0x3eb4c58a, 0x3f1e99ac, 0x3f1c85ab, 0x3f793d8d, 0x3ed75d7a, 0x3f37e2a9, 0x3f5fe002, 0x3f541199, 0x3f27737e, 0x3f354703, 0x3f19231c, 0x3f7e2bde, 0x3f788080, 0x3e910fb4, 0x3eb9a258, 0x3e7d73d8, 0x3f40c445, 0x3eea30f6, 0x3f4e1083, 0x3f5f484b, 0x3f165b7a, 0x3ebb4c5e, 0x3db7c988, 0x3d6a4e60, 0x3d8dffa8, 0x3f75cb55, 0x3f4924cc, 0x3f7589a7, 0x3e3ba718, 0x3e5b64c4, 0x3f15130b, 0x3ef78d22, 0x3eca0304, 0x3e3f3a18, 0x3da92190, 0x3e812406, 0x3eb1109e, 0x3e84898c, 0x3f10d994, 0x3d43c8a0, 0x3f044912, 0x3f006ab8, 0x3f4ecb83, 0x3f0c933a, 0x3f5ee4ab, 0x3d297a30, 0x3f1cb629, 0x3f476f1e, 0x3d8f4010, 0x3ec0a59e, 0x3e3780b8, 0x3f55d398, 0x3f11230d, 0x3f7b83d5, 0x3ddb9ed8, 0x3ed072d2, 0x3f35bad5, 0x3eefee28, 0x3effc15e, 0x3f1a8c66, 0x3e40f244, 0x3f3d1e68, 0x3ecf06e8, 0x3e6e97fc, 0x3df891f0, 0x3f6c646f, 0x3f132603, 0x3f755d4b, 0x3f030eb4, 0x3f069de3, 0x3f18d89b, 0x3ef31d78, 0x3f4dfd0b, 0x3e921c74, 0x3f3cd952, 0x3f632436, 0x3f35bf2e, 0x3f4c3a85, 0x3f23506e, 0x3ec9ddfa, 0x3ec5b4de, 0x3f1ec970, 0x3f519f70, 0x3f2e5652, 0x3f41cd3e, 0x3edc6592, 0x3cb093e0, 0x3e740a40, 0x3eb761fc, 0x3f1a4575, 0x3f204993, 0x3f14b1c6, 0x3f1ab9cd, 0x3f077650, 0x3dca4d18, 0x3eb3e18e, 0x3e8e4ffe, 0x3d8a25f0, 0x3f4c2939, 0x3f193155, 0x3ea8bc8e, 0x3e707ccc, 0x3f4a5d88, 0x3e32faac, 0x3f52839c, 0x3c1bd940, 0x3f318061, 0x3b900d80, 0x3ec6ea42, 0x3ec4a776, 0x3f606dab, 0x3f1a2caf, 0x399c3000, 0x3eda3bd4, 0x3f0c18e1, 0x3f73d7fe, 0x3f15ad0b, 0x3bbcb600, 0x3e2d4114, 0x3f105459, 0x3ba1d600, 0x3e868ece, 0x3f4eeef6, 0x3f0a6cdd, 0x3f0b01ca, 0x3eab4cdc, 0x3f3b253e, 0x3f0d522a, 0x3f04b44f, 0x3f214601, 0x3df97570, 0x3f781e88, 0x3f004a84, 0x3dc4e2c8, 0x3cae3f40, 0x3e981544, 0x3f0fa8be, 0x3f145be8, 0x3f1a41ed, 0x3f611d95, 0x3f6172a1, 0x3f349c83, 0x3e9f1dd2, 0x3f7a2bf5, 0x3f37d399, 0x3f44784a, 0x3d7b3b70, 0x3eb2431e, 0x3f441518, 0x3f0fce8a, 0x3eec22ee, 0x3f4c186b, 0x3e271ef0, 0x3e6a4590, 0x3f174a78, 0x3f36ab45, 0x3f2c7736, 0x3ec17b00, 0x3f752abc, 0x3dc62d48, 0x3f2639dc, 0x3f39aae7, 0x3e44f29c, 0x3e200de4, 0x3eb6e81a, 0x3f45e72e, 0x3f3560a9, 0x3f035e25, 0x3e7bad00, 0x3ef4dd66, 0x3dc91d00, 0x3ebcaa6c, 0x3f649206, 0x3f3875bd, 0x3f1e6d42, 0x3f2790d3, 0x3ef0a232, 0x3db17798, 0x3f65d44d, 0x3e672348, 0x3cd8b4e0, 0x3f7bcf6d, 0x3f3ef25d, 0x3e032ce8, 0x3e938888, 0x3ec79684, 0x3f2f7936, 0x3dda4f60, 0x3e95eede, 0x3f349424, 0x3d9caff0, 0x3f1c2c7e, 0x3f3398e5, 0x3f190799, 0x3e05dd44, 0x3edc72e0, 0x3f3675c1, 0x3f5e5a3c, 0x3f16064c, 0x3f662418, 0x3f3f4247, 0x3f0f3b48, 0x3f25daa2, 0x3f68f840, 0x3f6ffad9, 0x3c630280, 0x3f2b903a, 0x3f2c223d, 0x3effe77c, 0x3f2e2f6b, 0x3eecd0da, 0x3f342867, 0x3f5363b6, 0x3e9e7f68, 0x3f63ad4c, 0x3f3414bf, 0x3e6bcdb0, 0x3f578426, 0x3e962064, 0x3f4db122, 0x3e9c3af6, 0x3ef24892, 0x3f4c6ed5, 0x3f03c0b1, 0x3e9e3aaa, 0x3f0ba870, 0x3f134a31, 0x3f4793dc, 0x3e001670, 0x3d87d9c0, 0x3e9baaf2, 0x3ed92222, 0x3f22a2b0, 0x3ddd1fd0, 0x3f10d7f2, 0x3e288014, 0x3da30988, 0x3f4211a2, 0x3e92778e, 0x3f505e3f, 0x3f643df4, 0x3f0c2459, 0x3e20aef4, 0x3f0349c1, 0x3ee5cf92, 0x3e1474a0, 0x3f4e39d7, 0x3e349b04, 0x3e2639b0, 0x3f0ac524, 0x3efcffac, 0x3e6e2ee4, 0x3f226cb6, 0x3e5bbbc0, 0x3f5edf6b, 0x3f2aa1b4, 0x3f7dabe8, 0x3f13eb6d, 0x3f5b6432, 0x3f34d9a9, 0x3e61deac, 0x3f1d30f9, 0x3d778ee0, 0x3f764987, 0x3f5fb106, 0x3f3dcdc1, 0x3f367073, 0x3e0b0244, 0x3eafcfd0, 0x3f12cb91, 0x3dad9c30, 0x3e9d2594, 0x3dd0d1a0, 0x3d9178d0, 0x3f0e591f, 0x3f7a3f1c, 0x3dba5ad0, 0x3f65a922, 0x3e9dfd50, 0x3ec2c3f4, 0x3f390185, 0x3ea0ba1a, 0x3f53afab, 0x3f33a93d, 0x3ed4cce4, 0x3edbc1d0, 0x3f03e91f, 0x3e728234, 0x3f298ab0, 0x3e6fe3bc, 0x3dac3250, 0x3e8b58f8, 0x3f135011, 0x3eb0a3dc, 0x3f5593ec, 0x3f03f287, 0x3f71fe15, 0x3ec51e3e, 0x3d744960, 0x3f74be06, 0x3f2d671d, 0x3e384d84, 0x3f6f4615, 0x3eb3061c, 0x3f2f80b2, 0x3e69ed90, 0x3e2727b4, 0x3d410e20, 0x3ec6c27e, 0x3f03a310, 0x3edfc2a4, 0x3ea53202, 0x3e0a79b4, 0x3f49b5df, 0x3eab7e3c, 0x3ae05e00, 0x3f72d5e0, 0x3dab7408, 0x3e810eaa, 0x3bcf8e00, 0x391bc000, 0x3e8af156, 0x3f4a7e45, 0x3f4cd234, 0x3ed098fe, 0x3ee4327e, 0x3f766ab7, 0x3e80075e, 0x3f11c187, 0x3e14872c, 0x3f6b1a7b, 0x3f3d8346, 0x3f4c3cf2, 0x3ed51848, 0x3e060280, 0x3ef3f384, 0x3ed91a44, 0x3f2b44a6, 0x3d5edd00, 0x3ecd4ecc, 0x3f282129, 0x3f4233de, 0x3e82de7e, 0x3f7e5ec6, 0x3ecda3b2, 0x3e99ac3a, 0x3f3cda2e, 0x3ebb093e, 0x3ed259d4, 0x3f19d226, 0x3eac68c0, 0x3e7b6568, 0x3e9866b8, 0x3f508994, 0x3e0ce474, 0x3ee3dc62, 0x3ecb4bcc, 0x3f387866, 0x3e772898, 0x3f5bfd02, 0x3e7d2af0, 0x3f7bfbe4, 0x3e9955f4, 0x3c566100, 0x3d376530, 0x3f4e5334, 0x3f496291, 0x3f2b7072, 0x3dcfc480, 0x3e86c298, 0x3f4fd219, 0x3e82f6e0, 0x3f0924f0, 0x3e799b88, 0x3e9ecf24, 0x3de3f120, 0x3ebb2a18, 0x3dce3a20, 0x3eae78de, 0x3f07e440, 0x3f274293, 0x3f47be34, 0x3e3e2694, 0x3edbd970, 0x3f34e9a9, 0x3e963ec0, 0x3f40fb2f, 0x3e1cfe1c, 0x3f6ac0fb, 0x3ebc892c, 0x3e5993d4, 0x3f0a2574, 0x3f431243, 0x3d1f36f0, 0x3f13fa11, 0x3ee0c4b6, 0x3e368e9c, 0x3f1bbc36, 0x3f3fe30e, 0x3ec36554, 0x3eb09934, 0x3e065dc0, 0x3ef9902a, 0x3f6bb3ef, 0x3e9b5008, 0x3e5c78e0, 0x3ec9f760, 0x3e4f2254, 0x3f00d2e7, 0x3edc3108, 0x3f12dd38, 0x3f2f0fb7, 0x3b969c80, 0x3e40b1fc, 0x3f19c592, 0x3f490f1c, 0x3ee4b532, 0x3ea567b4, 0x3f04180f, 0x3c6ab140, 0x3ed87f5a, 0x3da7da00, 0x3df04a10, 0x3f1e5dd8, 0x3e1ba038, 0x3eee17ae, 0x3ec14278, 0x3b2edc00, 0x3f38a28e, 0x3f64000a, 0x3f09a1d2, 0x3f7fc3e6, 0x3cbd65e0, 0x3eb22f14, 0x3f39e132, 0x3e91fa0a, 0x3db1a4f0, 0x3e319080, 0x3ea825ec, 0x3ef927ba, 0x3f43c3c1, 0x3de54748, 0x3c643940, 0x3e873a08, 0x3f040ad3, 0x3f761a55, 0x3f5076ef, 0x3f27e6a1, 0x3c864a80, 0x3f11ab22, 0x3ee89a44, 0x3f7f5c64, 0x3f2fe4e3, 0x3f2cf469, 0x3f1dc003, 0x3f08b381, 0x3c9bccc0, 0x3f3397ba, 0x3df9d740, 0x3e227020, 0x3f67225d, 0x3d43b5c0, 0x3b13a000, 0x3e850468, 0x3eba37b4, 0x3f68d6ed, 0x3eaff3d4, 0x3f4f2667, 0x3efd5d96, 0x3d286520, 0x3e031f88, 0x3f7f9ed7, 0x3f18f491, 0x3f62acfc, 0x3ddaf220, 0x3e89721c, 0x3e5d693c, 0x3f417389, 0x3f71cf35, 0x3ecfd50e, 0x3c1c3a80, 0x3f0af1a6, 0x3ec114c6, 0x3e0b9774, 0x3ede32d4, 0x3f4e661e, 0x3f687d66, 0x3f3d77ac, 0x3f6f0343, 0x3f641d5d, 0x3f63e789, 0x3ea55fac, 0x3cd34ac0, 0x3f72a8f4, 0x3f160c23, 0x3ea2d36c, 0x3eb17e60, 0x3f2b9905, 0x3f67672c, 0x3ed67d9e, 0x3f290f1b, 0x3e28541c, 0x3f657fd6, 0x3f0b24da, 0x3ef8e85c, 0x3f1f0187, 0x3f04ea25, 0x3f35ce89, 0x3f66cd7c, 0x3f477cad, 0x3d8efe60, 0x3f7778f2, 0x3ceb0ec0, 0x3f3e30db, 0x3eb27386, 0x3f331d5d, 0x3f345742, 0x3eb82282, 0x3e109c08, 0x3ed02474, 0x3f3ecea4, 0x3f59f84d, 0x3ee0357a, 0x3e7222f0, 0x3ecca506, 0x3f02d0a6, 0x3eef0a28, 0x3f4310eb, 0x3f026842, 0x3dc64630, 0x3f0d205c, 0x3ed7565c, 0x3e9f210a, 0x3e1527f4, 0x3edc3884, 0x3f1dbe71, 0x3ed243ba, 0x3f1268ea, 0x3eabb42e, 0x3d1abe50, 0x3f5c3655, 0x3f490120, 0x3ea62188, 0x3f6732ed, 0x3e6cca60, 0x3f7118d7, 0x3ede6e68, 0x3ed7550e, 0x3f3b981c, 0x3e3a1adc, 0x3f1265a5, 0x3d954db8, 0x3efae76c, 0x3f6f78f9, 0x3f5f59bb, 0x3f368f94, 0x3ea61b26, 0x3e5a004c, 0x3f00fb35, 0x3d216a30, 0x3ebd061a, 0x3f3217ec, 0x3e1c9fc8, 0x3e7aee48, 0x3f7b5503, 0x3f4c506d, 0x3f7ccbec, 0x3f69ab33, 0x3f54b76f, 0x3f2ffe47, 0x3e9b4d50, 0x3ed17370, 0x3f6b8ba6, 0x3f096fbb, 0x3e25fe6c, 0x3db3ed90, 0x3d8470b0, 0x3ef83fea, 0x3f158e41, 0x3f6a0bf2, 0x3f3c0de9, 0x3e070158, 0x3f6ecaf7, }; // 10,8,5,5 uint32_t kernel_vals[] = { 0x3d3114e7, 0x3d4407ad, 0xbd35d912, 0x3ca7c94a, 0xbc56a7e8, 0x3b948e90, 0xbccbb9a0, 0x3c2b9b28, 0x3ca02e4e, 0xbcceb383, 0x3c6a04fc, 0xbd37c660, 0xb799d800, 0xbc5c8848, 0xbc4ae274, 0xbcf0a620, 0x3cb33d9e, 0x3d261659, 0x3cc7aeb6, 0x3d326067, 0x3c9c9e26, 0xbbcc0050, 0x3cd0ac2a, 0xbc893ff4, 0x3b8b1050, 0xba428000, 0xbd315ffa, 0xbd0f4ef5, 0x3bbcf490, 0xbc2ab878, 0x3bc68180, 0xbbc9bb68, 0x3cd18a86, 0x3c96670e, 0x3c22f178, 0xbca5d14a, 0xbca34e20, 0x3c69da2c, 0x3c012fc8, 0xbc4e8c78, 0x3c6c85a4, 0xbc8a1926, 0xbc54d694, 0xbd031dd0, 0xbc5f05c0, 0xbbdf5d98, 0x3cfff456, 0xbc9b11c7, 0xbd0435ce, 0xbd0479da, 0xbb11a930, 0xbd09e01a, 0xbcae6513, 0x3c897392, 0xbd33a047, 0xbc90b650, 0xbbfc8990, 0x3c8228ee, 0xbca793ea, 0xbd149155, 0xba0b0b40, 0x3cf9af0e, 0xbd20aafd, 0x3b9c4c68, 0xbd08876d, 0x3c3bf5c0, 0xbc85b67a, 0x3c955286, 0x3c4ab648, 0xbca8e4b7, 0x3c4cdf44, 0xbccb04c3, 0x3c22b794, 0xbd0e93a0, 0x3d2b04dd, 0xbc6033f4, 0xbccbc0f7, 0xbd0e3688, 0xbc4bfcd8, 0xbd37700a, 0xbd4b06a7, 0x3c0ceeec, 0xbbdb7928, 0x3c47f720, 0x3d3832a9, 0x3bd083d8, 0xbd420c63, 0xbd20b7cd, 0x3d284029, 0xbd2f3a1d, 0x3cdc94ea, 0x3cc68052, 0xbc0ab8e0, 0x394d6e00, 0xbd1fc3aa, 0x3c4e2404, 0x3d0adb4d, 0x3c6f5e74, 0x3d373d99, 0xbcd89817, 0xbc582354, 0xbb25eea0, 0xbd33a903, 0xbcc14be7, 0x3b5d7630, 0xbc550a98, 0xbd280dfd, 0xbd412b6f, 0xbcda4e57, 0xbb931290, 0xbcd13840, 0xbd378128, 0xbb4bacb0, 0xbc816b44, 0x3cc4982e, 0xbbf372f0, 0xbc1ece18, 0xbc8989d0, 0x3d2dbdf9, 0xbd2d3ab0, 0x3d4754e3, 0x3c4187f8, 0xbcbd2fdd, 0x3c945352, 0x3d080845, 0x3b240150, 0x3c131a98, 0x3b7fc8a0, 0x3d282079, 0x3c047518, 0x3c9ccfca, 0x3d252367, 0x3d14eb05, 0x3d2ee1b1, 0xbc832ce6, 0xbb9290b0, 0x3ced2af6, 0xbbcd5880, 0xbd237b88, 0xbc38d38c, 0x3cd2775a, 0x3c209b68, 0xbcc059b3, 0xbc2d7688, 0x3c3664a8, 0xbd444938, 0x3bb62998, 0x3cfce4ea, 0xbd2647d2, 0x3c4f8f54, 0xbcc7f663, 0xbc706940, 0x3cf03666, 0x3c894e02, 0x3cdd4b22, 0x3d3058e5, 0xbd178a16, 0xbd33a122, 0xbcaf84fa, 0x3d2b357f, 0xbbcc8510, 0xbcf1e24d, 0x3d1811bb, 0x3d07983b, 0x3d00c77d, 0xbd367605, 0xbd4672e3, 0x3d0419c7, 0x39b31800, 0xbd492abb, 0xbc9b6eea, 0x3be18d70, 0xbd41a34a, 0xbcfcf530, 0x3cfcab42, 0xbd3e81a2, 0xbd421e7f, 0xbcc11efd, 0xbca63d6d, 0xbd331545, 0xbd38f0bd, 0x3d496ed7, 0xbc17b734, 0x3c3b45f4, 0x3c64196c, 0xbd417f67, 0x3d15ae6f, 0x3d14b5f5, 0x3c64e8bc, 0x3b57aae0, 0x3c5c3774, 0xbcca7973, 0xbcded7b3, 0xbcb2267d, 0x3ca850b6, 0xbd09ca34, 0xbcfc9c53, 0xbc99dc4d, 0xbd2dda8b, 0xbd104bc0, 0xbcd2fcc7, 0xbbbd1f80, 0x3ba3d618, 0x3b924eb0, 0x3c0f8a6c, 0x3cc38ea2, 0xbca04520, 0x3b4b43d0, 0xbc6d4e08, 0x3c1c136c, 0x3d0ad6ab, 0x3c7f40fc, 0x3d0add39, 0x3d06e91b, 0xb8853000, 0x3d46d18b, 0x3c98251a, 0xbc107654, 0xbc49e4ec, 0xbc4a6e8c, 0xbcc6af4d, 0x3d181b39, 0xbcf100ed, 0x3bed0c00, 0xbacbcf40, 0xbc2304c0, 0x3d1b6291, 0xba2194c0, 0xbc3212ec, 0xbbecaeb0, 0xbd425452, 0xbcb6dac3, 0xbc86e604, 0x3cccd70a, 0xbcc3d7aa, 0xbba5a570, 0x3c4da1fc, 0xbcbb9c3d, 0xbcf26c8d, 0xbd38e4c7, 0xbd4ab0b3, 0xbb218ae0, 0x3cce9f6e, 0x3c6a84a4, 0x3c8fbf5a, 0x3c20d718, 0x3cd7200a, 0xbcf3275d, 0xbca6530a, 0x3cd43cfe, 0x3d1aa751, 0x3d1daee3, 0x3cbf75f2, 0xbb8c1c50, 0x3cf04506, 0xbd43d9c2, 0xbbe133c0, 0xbc95d02a, 0x3a580cc0, 0x3d433091, 0xbd310a97, 0x3d22b219, 0xbd20c68d, 0xbcf093a3, 0x3a90b0c0, 0xbcd4a277, 0xbcc4ea5d, 0x3ba52110, 0xbd4584b0, 0xbc4892e0, 0x3cf9cef2, 0xbd202d7b, 0xbcf8329d, 0xb9317b00, 0xbb02cb60, 0x3d16a987, 0x3ccd0ae2, 0xbd0e07bb, 0x3ce5afe2, 0xbcba3e53, 0xbd004140, 0x3c727284, 0xbd3100aa, 0x3ce1384a, 0xbc7980ac, 0x3d220849, 0xbd3db48b, 0xbd401a28, 0xbca574ea, 0xbc3922f4, 0x3d031b4f, 0xbd32a3f0, 0xbd2c5190, 0x3d1b5ce1, 0x3c8da5b2, 0xbd1adf65, 0xbd3eaf7f, 0xbd40fb2d, 0xbc019894, 0xba3c1140, 0xbcf569ad, 0x3bede0a8, 0x3b1b9230, 0xbd23010b, 0x3c740fcc, 0xbbd867c0, 0xbc17c908, 0x3b348ca0, 0xbc5dd360, 0x3d2a569d, 0xbcdc6527, 0x3d15f95b, 0x3c943d1a, 0x3b68f8d0, 0xbce9bb5a, 0xbc0014b4, 0x3d0229a5, 0xbd4ba5e0, 0x3d13459b, 0xbab304c0, 0x3d053451, 0xbc52e2cc, 0x3c0c96a8, 0xbd334520, 0x3cc7999a, 0xbafba400, 0x3c4b8ce8, 0x3d3f28c9, 0x3d3959cd, 0x3ca50e6e, 0x3c64cc2c, 0xbd4c667b, 0xbbba0840, 0xbcf05baa, 0xbb70df60, 0x3c910432, 0x3c84d512, 0xbd388aaa, 0x3c8acbf6, 0xbc3d9808, 0xbcda55a7, 0xbc24b518, 0xbcc722f0, 0x3cad76be, 0x3c70c6dc, 0x3d2b11e3, 0x3d080f31, 0xbc220d2c, 0xbd3703ba, 0xbd191162, 0xbc6c6f40, 0xbd1de1dd, 0x3d1235e5, 0x3d09d783, 0x3ccdc1ee, 0xbd1bc0b0, 0x3d100d91, 0x3d328b8f, 0x3c9d09ae, 0x3ccd7882, 0x3d4b1a4d, 0xbd093d0c, 0xbd4c717f, 0xbceb60ea, 0x3b2b4ea0, 0x3cf9e1ea, 0xbd493907, 0x3d3ce3f1, 0x3d195011, 0xbca6a497, 0xbcc9e50d, 0xbcc9a8b7, 0xbd2c719d, 0xbd1ed948, 0xbc243d94, 0xbcdb1f83, 0x3ca5dcfe, 0xbd4afb10, 0x38343400, 0xbc8c7d06, 0x3d1dc93f, 0x3d4ada1d, 0xbc86d956, 0xbce683e3, 0x3d0fffe1, 0x3b17b100, 0x3c475238, 0xbccf00f3, 0xbb9a41d0, 0xbd1a502d, 0x3b5ba7d0, 0x3d45967d, 0xbd119e3b, 0xbc7f0188, 0xbd0cdef0, 0x3c0efb68, 0x3d3dd0f3, 0xb7ac8000, 0xbcab8b77, 0x3cba91c6, 0xbc100de0, 0xbd4bd305, 0xbbf6a4d8, 0xbca78a53, 0x3c83d052, 0x3d393393, 0x3ccea7ae, 0x3d1e4b01, 0xbd2825a6, 0xbd18795e, 0x3c6bafd4, 0xbc644f88, 0xbd2ce9d7, 0xbc0d95d4, 0x3c083834, 0x3b0057b0, 0x3cc75282, 0x3ce1beba, 0x3c3a97ec, 0x3bd0a898, 0xbcd2478a, 0xbccdefdd, 0xbc0876a8, 0x3bfed400, 0x3cc8e346, 0xbc8e1f0a, 0xbca92707, 0x39f45d00, 0x3c270728, 0xbc208c78, 0x3b499c00, 0x3d4866f5, 0x3b1b1fb0, 0x3c9e40d2, 0xbd087ff6, 0x3ca2bef2, 0xbca468d3, 0xbca16b1a, 0x3d3addf5, 0x3d0e80bf, 0xbc78d1ac, 0xbcf4ff6d, 0x3d12995b, 0x3b26b4d0, 0xbd02b830, 0x3c2f7634, 0xbd38ff10, 0x3ca8f88e, 0xbcc0a01a, 0x3d3e36f3, 0x3ce4f236, 0xbc57488c, 0xbc873f94, 0xbd078f10, 0x3c5c97fc, 0x3d26b433, 0x3c5f45f4, 0xbcb806a7, 0xbcf658aa, 0xbd4a8470, 0x3d1ac939, 0xbbb171c0, 0xbd00ee5e, 0xbc93b7e4, 0x3c21d4a8, 0x3d1a4def, 0xbd15782e, 0xbca9c733, 0xbd0d9e3b, 0xbcfdea43, 0xbcbde660, 0x3cb42d8e, 0xbd206ac0, 0xbae99a00, 0xbc220d0c, 0xbccb22e0, 0x3d166429, 0xbd068cfd, 0x3d05072b, 0xbcfbdd43, 0xbcb96ea7, 0xbb806270, 0xbc42d22c, 0xbc99f550, 0x3d13b6ef, 0xbc7b5968, 0xbcc11cb0, 0xbcd22397, 0x3d467733, 0x3d437e0f, 0x3ce33436, 0x3d45e69f, 0xbcb4e1d3, 0xbc9d780d, 0xbd44eddb, 0xbc9f8fca, 0xbcf78a10, 0xbc667634, 0xbbc440b0, 0x3c4219ac, 0x3bfc1290, 0xbabf0aa0, 0xbd0e8156, 0xbcd89f10, 0xbd22bc6a, 0xbca2091d, 0xbd231f4b, 0xbbb9ed70, 0xbc4c8ce8, 0x3d302005, 0xbce67d5d, 0x3d3315ab, 0x3d42b557, 0xbcfb3853, 0x3cbf22fa, 0x3c12c0b8, 0x395ae800, 0xbd13572e, 0xbc916986, 0xbc828f20, 0xbd0918b5, 0xbc012328, 0x3c289e98, 0x3d3b4c3b, 0xbcc988c0, 0xbce724a7, 0xbcba939d, 0x3d081539, 0x3c1c8748, 0xbd27860b, 0xbbd36d68, 0xbd32ff08, 0x3a07c480, 0x3b68ad60, 0xbc95b244, 0xbb803750, 0x3d304595, 0xbc1a6028, 0xbca8c7c3, 0xbd2183eb, 0x3bfa09e8, 0xbcf657b7, 0x3bff8f70, 0xbc4a8ccc, 0xbd08d850, 0xbd2ac862, 0xbc7f8300, 0x3cad9fc2, 0xbcbab96d, 0xbc097d78, 0xbc7fad2c, 0x3c0f1f14, 0xbc849b46, 0xbd497d13, 0xbd00be2c, 0x3bb30530, 0xbd0d0112, 0xbc06f720, 0xbc8ddc4c, 0xbcc89d13, 0x3d202a01, 0xbbaec7d8, 0x3d29e3b7, 0xbd1a09f5, 0xbca13973, 0x3cd3cd26, 0x3cebb3f6, 0xbbe50af0, 0xbd35d98f, 0x3d1f7d17, 0x3d236eef, 0xbb822f98, 0x3b77e3b0, 0x3d406aa1, 0xbccda04d, 0x3d213933, 0xbd29efdd, 0xbb52e030, 0x3cc425a6, 0xbcad5aa3, 0xbd0edd9d, 0xbc4fd994, 0x3c731dd4, 0xbc936a74, 0x3c092048, 0x3b8cdf68, 0xbd359ca3, 0x3a916860, 0x3d16e051, 0xbc452278, 0x3cff2f52, 0xbc2aa378, 0x3b1f33e0, 0xbd1008a5, 0x3d1396bd, 0xbbcee730, 0xbd32750b, 0x3c5e0074, 0xbd1d38e3, 0x3d17c565, 0xbcc91663, 0xbc58e3a8, 0x3c7060e4, 0x3d0aa399, 0x3bf3e110, 0xbd23fdb5, 0x3cee8352, 0x3d28a7f7, 0xbc4de580, 0x3cdc852a, 0x3d0e4c21, 0xbb4875b0, 0xbbd2b018, 0xbd0cd62a, 0x3c750ec4, 0xbca804bd, 0x3b607880, 0x3cb1ab1a, 0xbb9b9640, 0x3c425e0c, 0xbab5cfa0, 0xbd3bd7c3, 0x3d4cb99d, 0xbd2adf2d, 0x399faf00, 0xbb450930, 0x3c62e114, 0xbcfb6890, 0x3d19b807, 0xbc333088, 0x3ca1ce42, 0xbca8fe90, 0x3c00c3c8, 0x3d0f85ad, 0x3c4a3528, 0xb9c2e680, 0x3b587fe0, 0xbc6fd8e0, 0x3ca98c0a, 0xbabaeb40, 0xbbb38168, 0xbcd55fda, 0x3cabf766, 0xbbf93d10, 0x3d2666ab, 0xbccbd870, 0x3cb013da, 0xbc8de3f0, 0x3c853306, 0x3ca6a16e, 0x3d439811, 0xbb590460, 0x3b920898, 0x3b85bc10, 0xbce92ce7, 0x3c6c3284, 0xbafe8960, 0x3c945cc2, 0x3c754a7c, 0xbc2abab8, 0x3c7b58dc, 0x3d08e483, 0xbd126588, 0xbc968340, 0x3d24cd49, 0x3cb3d2da, 0xbd2d76eb, 0xbc813a44, 0xbd39e80d, 0x3cc53a6a, 0x3d0ebf09, 0xbbb9a7f0, 0x3d0b9495, 0xbcee629d, 0x3ce14c82, 0x3c8c3152, 0xbbac1070, 0x3cf3a29e, 0x3cf1d7da, 0x39dc3700, 0x3d485977, 0xba38fb80, 0x3cfcefb2, 0xbcc5326d, 0xbd0244a4, 0x3ae3e240, 0x3ad2db40, 0xbd248bd0, 0x3d4c15c9, 0x3bbe53a8, 0xbcc67bc0, 0xbd080328, 0x3b610de0, 0x3c2f094c, 0xbd40ed1d, 0xbcea71b3, 0xbcf7154d, 0x3d30698f, 0x3cd21802, 0x3c18a814, 0xbcd07c67, 0x3cfa565e, 0xbcef7d00, 0x3c8ba85e, 0xbc8159b0, 0xbca6ffcd, 0xbd05df9a, 0x3c309480, 0xbd0d905e, 0x3d2f28ab, 0x3ab1e760, 0x3c6e6cc4, 0x3d0dced9, 0x3be71b70, 0xbd01b3b6, 0x3d3f7f8b, 0xbbb3e6b0, 0x3c429918, 0x3cdf0662, 0xbba3ee28, 0xbca5aaed, 0xbaa6f360, 0xbd352b5f, 0xbce29c30, 0x3bae5b50, 0xbcf5ecd3, 0xbd1b9263, 0x3c6e55fc, 0x3d095799, 0x3cfc7d6a, 0x3c90a572, 0xbab16840, 0x3cbcd04a, 0x3a97d940, 0xbd04a19c, 0xbd42e445, 0x3c595cd4, 0xbc7c71c0, 0xbd31da0d, 0xbc962a74, 0xbd0c49b0, 0xbd1443b5, 0x3a8b8060, 0x3d2a8f6d, 0xbc04f974, 0xbd1fdeb0, 0xbd3aed78, 0x3c4628e8, 0x3d2145d5, 0xbb6fd580, 0xbc8fa2da, 0xbcced14a, 0xbadfd860, 0x3ce723f6, 0xbd28aca5, 0xbca54a13, 0x3d45bed1, 0x3cd6db22, 0x3c8338ba, 0xbd45e5e7, 0xbd330b0d, 0xbce8685d, 0xbd47ad03, 0x3c0cfcc0, 0xbd2a62ba, 0x3cbd023a, 0x3d49da49, 0x3c23ee28, 0x3d2c5c47, 0xbcf8b1b0, 0xbd2c365b, 0x3c59734c, 0x3ce80486, 0x3d464e63, 0xbd2d7b1f, 0xbc804414, 0x3d463d95, 0x3ce1367a, 0xbd332f6f, 0xbc972fda, 0x3cca32e6, 0x3d23aff5, 0x3d3fb20d, 0xba892400, 0xbca38ac3, 0x3b883350, 0xbcfe11c7, 0x3d3bf377, 0x3bc73210, 0xbc61e0ac, 0xbd131c43, 0x3a0ddc80, 0xbca5ecbd, 0xbd0f1b78, 0x3c69512c, 0x3d35d1f1, 0x3cc28532, 0xbbff91c0, 0x3b51c780, 0x3c03fcc8, 0x3cb255a2, 0x3c230300, 0x3d0815e7, 0x3bacb8c0, 0xbd039c7a, 0xbb3584d0, 0x3d1bfac9, 0xbd3ae958, 0x3cefc6a2, 0x3c235ae8, 0x3ccab992, 0xbd370b4b, 0x3a732200, 0xbd461592, 0x3cc961f6, 0x3c838242, 0xbc9cced3, 0x3d27de81, 0xbc8344fc, 0xbc7faee8, 0xbd1e254b, 0x3d469e51, 0x3ce20ebe, 0x3c2f144c, 0xbc357d2c, 0xbc3620e8, 0xbc04a334, 0x3c5956a4, 0xbc8ba3c4, 0x3bca29e8, 0x3d17d1e3, 0xbba196e8, 0x3c8c295e, 0x3d2c4267, 0x3c983e9e, 0x3d09932f, 0xb9cddb00, 0xbd090ac2, 0x3c2467e0, 0x39fd2400, 0x3d0f0b43, 0x3ca1e1d6, 0xbba80d18, 0xbcc25020, 0xbcc3dcb0, 0xbbe231e8, 0xbd26d855, 0x3adee9c0, 0x3d3ef06f, 0xbd2c23e5, 0x3d2cba01, 0x3cd42aca, 0x3ac605a0, 0xbcc3951a, 0x3b32c4b0, 0x3ce38f9a, 0x3a6874c0, 0xbb147a00, 0x3c7019a4, 0x3c9e6102, 0x3b0e2d80, 0x3c7dbafc, 0xbd20fbd8, 0x3d436619, 0xbd434c55, 0x3bc58228, 0xbd3591bd, 0xbbd1a028, 0x3c163ff8, 0xba18cb80, 0xbc6d2034, 0xbbc6aaf0, 0x3d1be929, 0x3cf2d14e, 0x3d3ecf11, 0xbce0bd70, 0x3cf668b2, 0xbd304c52, 0x3d0f5a29, 0xbb3c8050, 0x3d2a76fd, 0x3cdfec42, 0xbc131ed4, 0x3c8715da, 0xbced47e0, 0x3caca7c2, 0xbb68ff00, 0xbd2bfced, 0x3c6bbf0c, 0xbd313687, 0xbba436a8, 0xbcd181d7, 0xbd37cf83, 0x3c5b8504, 0xbd082a58, 0x3c96080e, 0x3cde49b2, 0x3a8d1bc0, 0xbd32c9b7, 0xbbaeaad0, 0xbc80155c, 0xbc08e3a8, 0x3ca31582, 0xbbea7eb0, 0x3d4b33a9, 0x3cd27dda, 0xbc883e6c, 0xbc9deb03, 0x3ceda292, 0xbc9d334a, 0x3cab4f56, 0x3d46cadd, 0xbd339477, 0xb98b6900, 0x3c947fb6, 0x3d023c31, 0x3c99d8a2, 0xbd1473f8, 0x3c3642c8, 0x3d2980c5, 0x3c5b1c54, 0x3d3bb0f1, 0xbd031e18, 0xbad1c9a0, 0xbccc6d0a, 0x3c952096, 0xbcaa9d87, 0x3cf9b81e, 0x3bfe83a8, 0xbc9c417a, 0x3af637c0, 0xbca5ffc3, 0x3cf64072, 0xbc8c5214, 0xbcb6240d, 0xbd30cb48, 0xbc1c45cc, 0x3d3953f1, 0xbc29d26c, 0xbd33c0e5, 0xbd130e08, 0xbd2e02cb, 0x3acbdc60, 0x3cef5bae, 0x3d0197ed, 0xbd1cff72, 0xbd11b5a0, 0x3d1b8873, 0xbd38de4d, 0xbd476057, 0x3d239081, 0xbc05e78c, 0xbc94c6f0, 0x3d00f2b7, 0xbbeb7c68, 0x3d307db1, 0x3d2f397f, 0x3d3b5935, 0x3c114f98, 0xbcc65a4a, 0xbd34016d, 0xbd05a335, 0x3d0d3551, 0x3c59b1c4, 0xbd235a40, 0xbd0a2bea, 0x3ccc2556, 0xbbfd6258, 0x3cd81886, 0x3d41dcc5, 0x3d37ecf7, 0x3cae1086, 0x3c73a234, 0x3d1c71a9, 0xbd3ca15d, 0x3d43e907, 0x3c94baae, 0xbd4b5aca, 0x3d09daff, 0x3c53a574, 0xbcf09773, 0x3b3b13b0, 0xbd27229d, 0x3d2593df, 0xbd2c7f62, 0xbd1eca76, 0x3c0888c8, 0x3b860140, 0xbcb67bb0, 0xbcf435aa, 0xbd2e8ce2, 0x3b89b750, 0xbccdf04a, 0xbcdbd9fd, 0xbc1118c0, 0xbd4c0207, 0x3ca91bf2, 0x3d2e3cd1, 0xbc160cac, 0x3c9bfa22, 0x3c031e94, 0xbbd129b0, 0x3d25f675, 0x3cda9792, 0x3d2aedb3, 0x3d412a1f, 0xbd0a4846, 0x3cdd4c76, 0xbcc4248a, 0x3c27b0a0, 0x3a615940, 0xbc66b220, 0xbd2e8bb8, 0x3d49ae11, 0x3d4332d9, 0xbcfc2100, 0xbd2ac383, 0x3cd667c6, 0x3d0c976d, 0x3c85c5fa, 0x3ba20c28, 0x3cf6ef96, 0x3c4b5c68, 0xb9b6ba80, 0xbcbafbf7, 0x3b0a1ee0, 0x3cee6332, 0xbc404a0c, 0xbc0f05f8, 0x3d1b3bcb, 0x3d4820bf, 0x3d2c90c9, 0x3d0d3843, 0x3b7f07d0, 0xbc6e3cd4, 0xbd017f98, 0xbbe09b70, 0xbc564360, 0x3d310a81, 0xbc68efa0, 0x3aaa1800, 0xbd4b4008, 0xbb92add0, 0x3d0a26d3, 0xbb03ccb0, 0xbb88e0d8, 0xbd0d3143, 0x3cd98022, 0xbcfba76a, 0xbcb0efaa, 0xbcb783ed, 0xbd2702ea, 0x3c23e634, 0xbd368ec2, 0x3bbb2b18, 0x3d43a38b, 0x3c07f7f4, 0x3c0f2cc0, 0xbca0230a, 0xbd451f0a, 0xbc8313cc, 0x3d4670e1, 0xbd406357, 0x3cbf59fe, 0xbca8e0ed, 0xbcb9bb3d, 0x3c817452, 0x3c900d2e, 0x3bd8d158, 0xbd2977c3, 0xbc3dd788, 0x3d12260f, 0x3cff63ea, 0xbcdeb8c3, 0xbced00da, 0x3ce76e82, 0xbcc8f677, 0xbc6648b4, 0xbd449ada, 0xbc9af66d, 0xbcbf552d, 0x3cdb28da, 0x3a1a6680, 0xbd1d79c0, 0xbcef2c2a, 0xbbf520b0, 0xbabc0a00, 0x3c8d280a, 0xbc989136, 0xbd0a489a, 0x3c368168, 0x3cc19ade, 0x3d2c7f03, 0xbd322e52, 0x3cb94f62, 0x3d0b907d, 0xbcb2682a, 0x3c09f140, 0x3bd4a1e8, 0x3d2550e5, 0xbced6c9d, 0x3d1c208f, 0x3d029b61, 0x3c80bfd6, 0x3c868faa, 0xbcd907aa, 0xbd31def2, 0x3d1d9951, 0x3cd8f40a, 0xbcf5fbd0, 0x3c9fcf6e, 0x3d32e6bf, 0xbc598380, 0xbd404c47, 0x3d030313, 0x3add26a0, 0xbc23c368, 0xbcbc4ff7, 0xbcfb37d7, 0xbd0f0d1a, 0x3d2cea83, 0xbcfc20f7, 0xbc3e6fa0, 0x3d28f981, 0xbc44ed28, 0xbc5752c0, 0x3bd6f0a8, 0x3d47bcb9, 0xba1b8b80, 0x3d00db71, 0x3b4f5150, 0x3c180534, 0x3ac24e00, 0x3d23a575, 0xbcb0afaa, 0x3c3df058, 0x3bdacd10, 0xbc2f4de8, 0xbcebcbad, 0xbc044674, 0x3d2a7241, 0xbd351873, 0xbcc99800, 0x3c644aa4, 0xbc93dba0, 0x3bd56c70, 0x3c22a874, 0x3c29316c, 0xbccde2fa, 0x3d04bf69, 0xbd2b2bd2, 0x3c24f6b4, 0x3d006067, 0xbd016525, 0xba8bdcc0, 0x3c7f18dc, 0x3cfa8832, 0xbc4c5414, 0xbcdd47ca, 0xbcfd17f3, 0x3d3dfcef, 0xbc986150, 0xbc7f99f8, 0x3d47203f, 0x3c1df868, 0xbcb19b1d, 0xbcec124d, 0xbc249dac, 0x3c8d9db2, 0xbcb76dc7, 0xbc90ab9a, 0x3d2d7e8b, 0xbd0ecbfb, 0x3b9ad180, 0x3d229639, 0xbd44e212, 0x3c86b72e, 0xbc825a46, 0x3cb2e2c2, 0x3ce0e25a, 0x3ccd776a, 0xbbec5d28, 0xbb71f950, 0x3c998342, 0xbc0e10a8, 0x3d38ba4b, 0x3d1626a9, 0x3cc00aa2, 0xbd3bfb45, 0x3c43b2d8, 0xbc601b14, 0x3bae2280, 0xbb8abdd0, 0x3d3ef73d, 0xbd47cbeb, 0x3d18422b, 0xbd079f7c, 0x3adfe460, 0x3d3962e7, 0xbd1ec823, 0x3ce4f25a, 0xbc419248, 0x3d0f8593, 0x3d39e519, 0x3d279cd7, 0x3ca695e2, 0xbce8d18a, 0x3c8369fe, 0x3c7b33dc, 0x3c92c912, 0xbd02a74e, 0xbce951ea, 0x3cddb652, 0xbd438bb0, 0x3c670944, 0x3d077419, 0x3aee6d40, 0xbcccddda, 0x3cd07792, 0x3aeb1140, 0x3d00ab6d, 0x3cdab052, 0xbc83a6c0, 0x3d378b65, 0x3d18ca3f, 0x3b5e9dd0, 0xbca3cd5d, 0x3cc7db5e, 0x3cece702, 0xbcdb7367, 0x3d2e6291, 0x3d23da33, 0x3c4d13ec, 0x3c9fef32, 0xbd25bf5b, 0xb9252b00, 0x3ad8d6a0, 0x3c337420, 0xbb6c2bd0, 0x3d031713, 0xbc4f236c, 0x3c51b244, 0xbc44ad4c, 0x3c9474f2, 0x3c063458, 0x3c13228c, 0xbbbba390, 0x3b4f2c60, 0xbc20288c, 0xbc1c6ec0, 0x3d2342e9, 0x3c6b03fc, 0x3b9fd890, 0xbbe72070, 0xbc351b0c, 0xbc4d3e14, 0x3cbe837a, 0xbb30cb30, 0x3ce17856, 0xbb8c5a58, 0x3c074738, 0x3c382288, 0xbbcd2b28, 0x3c82507a, 0x3b2a0b60, 0x3d44130f, 0x3c10d9e0, 0xbabce6a0, 0xbadf8600, 0xbb739c80, 0xbc600f80, 0x3c82c276, 0xbd2226f5, 0x3d3ff37f, 0x3d4426ad, 0x3d22f737, 0xbc591d08, 0xbd24f663, 0x3bdd6390, 0xbd386275, 0xbc866100, 0x3c695014, 0x3c814c0a, 0x3d3f3311, 0xbc6bc1e0, 0x3d32ca43, 0x3cb7d7ae, 0xbba1e9d0, 0xbd4bd5fa, 0x3ba978d8, 0xbca2af5a, 0xbb2bc200, 0x3cb7bb0a, 0x3d0ba59f, 0x3d169ef1, 0x3b0a2650, 0x3d1fc229, 0x3cfa4662, 0x3c9529de, 0x3cd13772, 0x3cd6f05e, 0xbca93473, 0xbcafe123, 0xbd02a278, 0x3c3c0cd4, 0x3c894c4a, 0x3c41bd00, 0x3c5ca0a4, 0x3d1b717b, 0xbcd16950, 0xbc7de328, 0xbd3cf5ef, 0xba650800, 0xbd3e2408, 0xbb54cbb0, 0xba0f8cc0, 0x3cd82822, 0x3d3d792f, 0xbc9516b4, 0x3b1d1d50, 0x3d368979, 0x3c5e6dec, 0xbd3cf378, 0x3d3a8635, 0xbd4662e0, 0x3ca3eb6a, 0x3bd87628, 0xbd4aa05b, 0x3cc1540a, 0x3d11f57f, 0x3c6448c4, 0x3a90a600, 0xbd25e66b, 0xbd3333bf, 0xbc35e6e8, 0xbca0f943, 0x3b20bee0, 0xbd1881d8, 0x398e8580, 0xbd1f24b5, 0xbc42176c, 0x3d46a8a7, 0x3d17a7fd, 0x3ca6c69a, 0xbc153748, 0x3bb1acf0, 0xbd2a041b, 0x3caf685e, 0x3ac27160, 0x3c1830a0, 0xbc5498b8, 0x3c462634, 0x3d08fa25, 0xbd1eb5a2, 0xbc1f14d4, 0xbceeee57, 0x3ceae45a, 0x3c4c2028, 0xbca0930a, 0xbcad99ed, 0xbd01bb5a, 0xbc541b68, 0x3d47d671, 0xbc8964d0, 0xbc3b78f8, 0x3cbf18fa, 0x3d2a8f6d, 0x3bad6668, 0xbcc31657, 0xbcdf69d7, 0xbc216f8c, 0xbc76a434, 0x3d06df89, 0xbd2d9123, 0x3c8ffc22, 0x3cd98b1a, 0xbb93ef10, 0x3d4a7163, 0x3d0d6471, 0x3c02b808, 0x3b9e7940, 0xbc331560, 0x3cfa9c82, 0x3cd98a2a, 0x3ad2af00, 0x3d16e8bf, 0x3d04c911, 0xbcb0a740, 0x3d0eae19, 0x3d42eb55, 0x3c9cf206, 0x3d3a18c9, 0xbb4e7e50, 0xb9f4ad00, 0xbcf3437a, 0xbd2d651f, 0x3c2297ac, 0xbd3bb2c8, 0xbc5efd4c, 0xbc949774, 0x3cc4f6a2, 0xbd0a815a, 0x3cee9902, 0xbcbb15a0, 0x3c82e192, 0xbd1b7e8e, 0xbcf11be0, 0x3bbbe510, 0xbce9d433, 0xbd13d5bb, 0xbc6815ec, 0x3c89ceb2, 0x3cee4ede, 0x3c6b3384, 0xbd112576, 0xbcda1fa3, 0xbc8a3dca, 0x3c51d724, 0x3cf2124a, 0xbbe8eeb0, 0xbcdb7f5d, 0xbd2cc46e, 0x3d3909f3, 0x3c75b3fc, 0x3d1b4d4f, 0x3c8dcb66, 0xbbf7bad0, 0x3c82e00a, 0xbca273e7, 0xba8bc8a0, 0xbc7053f8, 0x3c9c67ae, 0xbb958c40, 0x3c20db00, 0x3c1b5a28, 0xbc9967d0, 0x3ca42a9e, 0xbce59ef3, 0xbd31c562, 0xbd01404c, 0x3d06f385, 0xbc8bcd74, 0xbb05c3b0, 0x3cbbf1f6, 0xbcf06560, 0x3d13e9e9, 0x3c083118, 0xbd183ebb, 0x3cda6dd6, 0xbd29999b, 0xbabd2ea0, 0xbce821b0, 0x3c419c60, 0xbd2b8af8, 0x3d1f3849, 0xbca0c1ca, 0x3c5a8f1c, 0x3d1ce21b, 0xbcaf98e0, 0x3d3c0893, 0x3d0a853f, 0x3cf646aa, 0x39affb00, 0xbd389690, 0xbd4b39d3, 0xbb503720, 0xbbb53590, 0xbbd704b0, 0xbc37d514, 0xbd0719dd, 0xbae6c6a0, 0xbcdbf147, 0xbc20dd08, 0xbd4c05fd, 0xbc81f7f0, 0x3bf4ba30, 0x3cd79452, 0x3d452637, 0xbc461978, 0x3beec000, 0x3d338637, 0x3c9bf462, 0xbd32ee0f, 0x3c22b3a0, 0x3d29b317, 0x3d3c7313, 0xbc376740, 0x3c8c37a2, 0x3d0ca591, 0x3b46b2a0, 0xbc4f2848, 0x3c721f2c, 0x3c8cd96e, 0xba25f740, 0xbbd8b2e8, 0xbb5a3650, 0xbc22d698, 0x3cd440fe, 0x3d1f4db9, 0x3d4323b9, 0x39689e00, 0xbd07b34e, 0xbccfa89a, 0xbb9e7b28, 0xbd494eaa, 0xbd385b07, 0xbbb5fa98, 0xbcbaf4d7, 0x3cc7dc46, 0xbcb7a5dd, 0xbb0a16b0, 0xbb51f160, 0xbd3c0b1a, 0xbc1142ec, 0xbd3f8dd5, 0xba843260, 0x3ca5cc22, 0xbd26a015, 0xbce361f0, 0xbc10a48c, 0x3c9f7b6e, 0x3c9287de, 0xbc81e2a4, 0xbd37b89b, 0x3d480471, 0xbd14a0eb, 0x3d234b61, 0xbc89835c, 0xbcbccc1d, 0xbd291efa, 0xbcf1d68d, 0xbbd96c40, 0xbcb922aa, 0x3c80bdfe, 0x3c7c8024, 0xbd105d62, 0x3d244d31, 0x3cbbe22a, 0xbcb32eb7, 0xbcd1cb73, 0x3d0e8799, 0xbb920a68, 0xbd2e2b60, 0x3cbdb9e2, 0xbcfa0777, 0xbd06be54, 0xbd24d3bb, 0x3d3683c3, 0x3ceffe3a, 0x3ccc9cca, 0x3c3e2b00, 0x3ca3238e, 0xbd37e2b0, 0x3d11c961, 0xbd4ae8a3, 0xbd486c65, 0xbb8237e8, 0x3d30f539, 0x3d14c629, 0xbd4193eb, 0x3d26de35, 0xbd25110b, 0xbd1cc35a, 0x3c810422, 0x3d3cb60d, 0x3d48e591, 0xbd044924, 0x39545e00, 0x3d09ce5f, 0x3cef5336, 0xbb5d5b50, 0xbd037c0c, 0xbcb4b237, 0x3d4a11b9, 0xbcf4825a, 0xbd168eca, 0xbd2f5fad, 0xbba23d80, 0x3ceb122e, 0x3b070ed0, 0x3c4e9b4c, 0x3c580244, 0xbd461647, 0xbbc52830, 0x3d2c6e15, 0xbc8c15cc, 0xbd0d8fd2, 0x3be4a1f0, 0xbc210068, 0x3ca9a456, 0x3cc74eba, 0xbd1a8588, 0xbc784c48, 0x3c8cfe52, 0x3d2dafa9, 0xbc666754, 0x3cbad202, 0xbbdb5b28, 0x3c49e0f8, 0xbd3035cf, 0x3cc6bd0e, 0x3d17fb77, 0x3b60c620, 0xbd34bfc3, 0x3cdd6aa6, 0xbd1da1de, 0xbd1d27b2, 0x3ba27e28, 0x3cde5c2a, 0xbd4c18b2, 0xbcbcc0fd, 0x3b6fb6e0, 0xbc227260, 0x3cc3e3e2, 0x3cda3926, 0x3c0f5880, 0x3d452a2f, 0xbcca98d0, 0xbd462d60, 0xbd0ba370, 0x3cd64fb2, 0xbd4a8e37, 0xbd05dfee, 0xbc1a9bd4, 0xbd268438, 0xbcf40b2a, 0xbd4a88bd, 0x3c603f74, 0xbba3e3f0, 0xbbd827a8, 0x3c8485b2, 0xbd3ee2c2, 0xbd466335, 0x3c846b4a, 0xbd3703c0, 0xbd0ffab3, 0xbca240fd, 0x3ceacad2, 0x3c4fbdb4, 0x3c0c45c8, 0x3d05a8d5, 0xbc5c3f28, 0xbd3ea837, 0xbd129b55, 0x3cb3689a, 0x3d26abd1, 0x3d0cf0e3, 0xbcbe0683, 0x3ce1872a, 0xbc4cca28, 0xbc85cbca, 0xbb3e8460, 0xbd0e79e3, 0x3c89b682, 0x3d382369, 0xbd0e41a0, 0x3c99454a, 0xbad781c0, 0xbc811614, 0xbd37d59f, 0xbcc4fdb3, 0x3b3baa60, 0x3d470b9b, 0xbcb15893, 0xbd2e08ef, 0xbcab4813, 0xbbdd75e8, 0x3d092ff3, 0x3d091ac5, 0xbcbe0f03, 0x3d009871, 0xbd1deac2, 0x3d47da6f, 0xbc7323f8, 0x3ce8096e, 0xbcc2410d, 0xbcffbc97, 0xbbbd9830, 0x3d459729, 0xbc136060, 0xbd0330e4, 0xbce041ed, 0x3c98ac5a, 0xbd10a4b2, 0xbd3e3037, 0xbd206468, 0x3d34e981, 0x3c389ea0, 0xbd242522, 0xbcbe9850, 0xbcd60ee7, 0xbcfb070d, 0xbb028f80, 0xbbea97e8, 0xbbaa1f28, 0x3d18b097, 0xba530cc0, 0x3d1a05c9, 0xbd17b3ba, 0x3c81adf2, 0x3d21a6a3, 0xbd302f33, 0xbd28c162, 0xbc43e194, 0x3c277c58, 0xbcd14130, 0xbb89d3a8, 0xbc3f92d8, 0x3d3b5e07, 0x3bdde368, 0xbcec6d4d, 0xbbbdede8, 0xbabb21c0, 0x3cddbbd6, 0xbd25cc2e, 0xbc6c92c8, 0xbccb1030, 0xbcdc1163, 0x3cfb8c12, 0x3d3f2e85, 0xbd3707b8, 0x3c282b20, 0x3b7145d0, 0xbd115813, 0xbbc6f800, 0xbd103956, 0x3ba25528, 0xbd2697ab, 0x3cfb773a, 0x3d38ad2f, 0x3bf5df80, 0x3c631b0c, 0x3d46ce7d, 0xbc743eec, 0xbc589f8c, 0xbd3a9070, 0xbd2e9e9b, 0xbccaef27, 0xbcf61793, 0xbcfd47a0, 0xbd048d2d, 0x3c33edc8, 0xbca6d920, 0x3d16f5a3, 0x3bd1a650, 0xbc916a34, 0x3ca1a002, 0x3b86b698, 0x3cc09626, 0x3d382fdf, 0x3cd125ba, 0xbcc69920, 0x3bd58e18, 0xbb379360, 0x3ccf4b92, 0x3d3c2fd1, 0x3be5cd10, 0x3926e600, 0x3d1a42b1, 0x3c4412cc, 0xbc251cac, 0xbcba31ea, 0x3c98b6b2, 0xbbb536b0, 0x3c8b7ca6, 0x3cb01d82, 0x3cac849a, 0x3c575ec4, 0xbc6ff768, 0xbd43457b, 0x3bc20340, 0xbcfe39ba, 0xbd2dcad5, 0x3d1c6923, 0x3d20d2a9, 0x3ccd6d42, 0x3d140969, 0xbd47ea7f, 0xbc9d1967, 0xbad11440, 0x3d3fd6b3, 0x3d0406db, 0xbcd0d390, 0x3d0117c9, 0xbb4abfd0, 0x3ca4b0a2, 0x3d3c14df, 0xbcc52653, 0x3be00400, 0xbc633560, 0x3b9ba198, 0xbca1ecad, 0xbd148732, 0xbcf05240, 0x3d3c4535, 0xbd2df2a7, 0x3bdc7bf0, 0x3d1a9d01, 0x3b04afd0, 0xbcbf7093, 0x3d10cf11, 0xbd20fecb, 0x3c5a2294, 0x3cfaa8c2, 0x3d4544a1, 0xbb778fb0, 0x3bd6c468, 0x3c533e64, 0xbb03f380, 0xba8cc760, 0xbd1b780a, 0xbc33f834, 0x3ca93136, 0xbcee5fa7, 0x3d4824bd, 0xbc8c2364, 0xbc96c32c, 0x3b5274b0, 0xbd40acb2, 0xbb0aa3b0, 0x3c5e3a04, 0x3cb05e5a, 0xbbf5a490, 0xbd469270, 0xbcb1613d, 0x3c4d4104, 0x3d29fd19, 0xbd3ca957, 0xbd367eca, 0xbcf4b8b0, 0xbd4899d8, 0x3c4ad04c, 0x3cd504aa, 0xbd292aa0, 0xbc93fb1a, 0xb8927000, 0xbcb399bd, 0xbcb1882d, 0x3cdf1e82, 0xbd154a58, 0xbba65590, 0x3d223bf5, 0xba21a2c0, 0x3c9cadfe, 0xbccd19c3, 0xbd063e1e, 0x3d2fa8af, 0xbcaad777, 0xbd493cf5, 0xba19c780, 0x3cdf4afe, 0x3cf71c46, 0xbd0e8150, 0x3d2b94df, 0x3c9890e6, 0xbc875256, 0xbb92a798, 0xb8d05400, 0x3b83e610, 0xbcf30377, 0xbc970b7a, 0x3cb85f32, 0x3d0aeb31, 0xbd100dc5, 0xbd2ec743, 0xba81f1a0, 0xbcd2f36a, 0x3c8b8912, 0x3cd213ce, 0xbcd8505a, 0x3caf84ca, 0xbd1a1f43, 0xbd22fc05, 0xbc38fb40, 0x3c29ffa8, 0x3d21e4f9, 0x3d336049, 0xbc29fb14, 0x3d4c8f65, 0x3d0156b9, 0xbc9c1a63, 0x3bf1d810, 0x3d2f3379, 0xbcc6024d, 0xbd2b784e, 0x3cc61f72, 0x3bcad3e8, 0x3d1d16c7, 0x3c493368, 0x3d4a3853, 0x3d2f9a0f, 0xbd18cc55, 0x3ca27c92, 0xbc0e0578, 0x3d2f9f6b, 0x3d25c15f, 0xbccba443, 0x3d2861f9, 0x3cdd1c26, 0xb9bba980, 0x3c215ce8, 0xbc6fe358, 0xbd436fd3, 0xbc5fa958, 0xbcfd9ef3, 0xbc2e3d88, 0x3c9630be, 0xbd019f08, 0x3c552b0c, 0x3ccead72, 0x3d3161b5, 0xbd349167, 0x3cfb291a, 0x3baf3a70, 0xbd30eaef, 0x3d36d16d, 0xbbff9db0, 0xbd05cfe5, 0xbd46d333, 0x3a5d36c0, 0xbd2f322b, 0x3c6ea574, 0x3cc23a2a, 0xbd087a4d, 0x3c9e21b6, 0x3c8b4572, 0xbcfb10fd, 0x3d256731, 0x3ca1cd0e, 0xbd4060a8, 0x3c9c80e2, 0x3d0bb7b1, 0x3caec47a, 0xbca2cfaa, 0xbcd33083, 0xbbd930f0, 0x3d2a8e01, 0x3a034b80, 0x3c964966, 0x3d2e454f, 0xbd1daa35, 0x3d42e051, 0x3cb0dc8e, 0xbd03e9f0, 0x3ce23c82, 0x3d2b9c51, 0xbad26360, 0x3cf6b6c2, 0x3c5ccecc, 0x3d0d4d23, 0xbd2023dd, 0xbd080fdd, 0x3d27cddf, 0x3d4c3a39, 0x3c8303fa, 0x3cce2002, 0xbd420ceb, 0x3ce895e2, 0x3d1dd9a3, 0xbc269ba0, 0xbcce26cd, 0x3ce6a7ea, 0x3cbdf30e, 0xbd48fe87, 0x3c5c97a4, 0x3c961dfa, 0x3c323fb4, 0x3d1aa5ef, 0xbb308e50, 0x3d0699af, 0x3cbf1eb2, 0xbd0a3460, 0x3ba9a618, 0xbcdfe007, 0xbc13b634, 0xbc5bbbe0, 0x3d2a4e3f, 0xbcd5f22a, 0x3c76f9f4, 0xbc9b65cd, 0x3cb59b36, 0xbcaa9fd0, 0x3ccb71da, 0xbd38c728, 0x3cc6f0ca, 0xbd1d5c6a, 0x3d320255, 0xbd3a9ed5, 0x3b3d4930, 0xbd3aaa4d, 0x3c9e2a82, 0x3be26210, 0x3b52f560, 0x3cbaf15a, 0xbc9efa8a, 0xbd0726e6, 0xbd2c5ebd, 0xbd0af8a2, 0x3d26a0d7, 0x3cc926b6, }; // 5 uint32_t bias_vals[] = { 0x3bded4d8, 0x3c9d39d2, 0x3ca89fd2, 0xbc5af538, 0xbcb69fcd, }; // 3,1,1,5 uint32_t output_exp_vals[] = { 0x3c0f5041, 0xbd5feb0d, 0xbe2ac302, 0x3e4629df, 0xbf31fe38, 0x3e5c01b4, 0x3e7c96f6, 0xbce63e5a, 0x3e379fba, 0xbf3027ad, 0xbdb021b6, 0xbe97d08d, 0xbef57ffa, 0xbdfbe7fc, 0xbf1bf24c, }; uint32_t clip_value = 0x3e4ccccd; // 3,1,1,5 uint32_t output_relu_exp_vals[] = { 0x3c0f5041, 0x0, 0x0, 0x3e4629df, 0x0, 0x3e4ccccd, 0x3e4ccccd, 0x0, 0x3e379fba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, VALID_PADDING, (void *)&clip_value); } void test_same_padding_non_zero_strides_medium() { input_set *set = &medium_input; strides_input_set *strides = &medium_non0_strides; // 3,10,8,5 uint32_t input_vals[] = { 0x3dedbd80, 0x3f3c7b79, 0x3e131b74, 0x3f07e9cb, 0x3e936dc0, 0x3f2a452c, 0x3f63ab13, 0x3f64a605, 0x3f17672a, 0x3ed1273a, 0x3ebebdd8, 0x3f0c947e, 0x3f5af4f0, 0x3e672280, 0x3f222b95, 0x3e84c4d4, 0x3f481888, 0x3eb31760, 0x3f282381, 0x3d832688, 0x3f50d901, 0x3e87184e, 0x3f130b99, 0x3ef625d8, 0x3f039d45, 0x3ef74f90, 0x3f47739d, 0x3f0f95c4, 0x3eb4895e, 0x3f3d0eef, 0x3e5b5400, 0x3f051d17, 0x3edcaddc, 0x3eff1d44, 0x3f1009db, 0x3e4da22c, 0x3f550f4d, 0x3e286098, 0x3c7b4a80, 0x3ee87202, 0x3f788b9a, 0x3f7a6028, 0x3f697980, 0x3e1754a8, 0x3f524aa1, 0x3f5341de, 0x3df96408, 0x3f3efd3b, 0x3f10f16c, 0x3f37ada8, 0x3e10ddac, 0x3f798359, 0x3da84670, 0x3f7b9cca, 0x3d6356b0, 0x3f000faa, 0x3f61b5d8, 0x3de66248, 0x3e5086a8, 0x3f4b5467, 0x3efa7626, 0x3dc718f0, 0x3f79b8e4, 0x3f520efc, 0x3dd857c8, 0x3f3d0355, 0x3f2585a9, 0x3f146def, 0x3f0bb6e8, 0x3f47e6ab, 0x3d92fb78, 0x3dbe5a80, 0x3ec52f64, 0x3e91dc5c, 0x3f6bc833, 0x3f01e701, 0x3f29857c, 0x3f56c01c, 0x3f0023e7, 0x3f0bcbe5, 0x3f2aa5fa, 0x3f13cb3e, 0x3f24c58f, 0x3f3d5dcf, 0x3ea97abc, 0x3f4123bc, 0x3cb9e960, 0x3f2df2c2, 0x3f0f3a6d, 0x3e778748, 0x3f0d6252, 0x3f2e7767, 0x3f658c24, 0x3f714eda, 0x3e8e536c, 0x3e811bb8, 0x3eb9ae8e, 0x3eec050e, 0x3ecf8cd2, 0x3ed0cf9e, 0x3ca3c7c0, 0x3f7f9666, 0x3f79f7d1, 0x3e2a18a0, 0x3e95ddf8, 0x3f452f8b, 0x3f7cedd5, 0x3e185a7c, 0x3f73aa6c, 0x3f7f1133, 0x3f74dbfb, 0x3f2c2fd8, 0x3e4872ac, 0x3eb6e2e0, 0x3e91935a, 0x3eb2b562, 0x3f64e525, 0x3f15b029, 0x3f513750, 0x3f3524e8, 0x3d59cbf0, 0x3f2e3b2b, 0x3ee0eb9e, 0x3f546dab, 0x3d14d5d0, 0x3f257374, 0x3f7919bb, 0x3f490b1c, 0x3f16ab5c, 0x3f40e084, 0x3e19099c, 0x3ee85d48, 0x3eba62fc, 0x3db78e00, 0x3f6ceab8, 0x3e317a24, 0x3f1fa2a0, 0x3f1420b6, 0x3c158fc0, 0x3e10f6c0, 0x3f22e418, 0x3ed5b692, 0x3ecace68, 0x3f3cc42c, 0x3ebeaef0, 0x3ee7b088, 0x3efb85e2, 0x3f601876, 0x3f1f4b7d, 0x3f1e81ea, 0x3eee9634, 0x3eb2c5fe, 0x3eef3554, 0x3f4a7a82, 0x3caf3280, 0x3f72cf34, 0x3e9aafd0, 0x3f01f6f8, 0x3d72e160, 0x3e3c0c40, 0x3ed318d6, 0x3f4a0b90, 0x3f5dc59f, 0x3edcbaf8, 0x3f2c8435, 0x3f4dea36, 0x3f36eda3, 0x3f7c7056, 0x3f6e9798, 0x3f7887d5, 0x3eb053aa, 0x3e8efdee, 0x3f7a7a39, 0x3f433fac, 0x3eb38584, 0x3f5f3ece, 0x3d731830, 0x3c367c80, 0x3f6a5f53, 0x3efdab28, 0x3f270c9d, 0x3f3e9627, 0x3e5eb05c, 0x3f647ede, 0x3c8dfda0, 0x3f720f81, 0x3d241a50, 0x3ec868f8, 0x3ec12f9a, 0x3ca47700, 0x3f2ca4ce, 0x3ef4abf4, 0x3ecb2688, 0x3e23561c, 0x3f6f5198, 0x3ea55200, 0x3d8ee818, 0x3f4a0a40, 0x3e4eb34c, 0x3f6c9f2b, 0x3f37ca0f, 0x3f6b2da8, 0x3f39cf91, 0x3f2b78e3, 0x3eb1faa8, 0x3f6d0da1, 0x3f683a3a, 0x3eeaf18c, 0x3e9a626a, 0x3e9ac5da, 0x3f1842a0, 0x3db66f18, 0x3f030844, 0x3f0081f5, 0x3eef6d7e, 0x3f3b02fd, 0x3d0fe810, 0x3f1b6ccb, 0x3f146d3e, 0x3f3b640f, 0x3e17cbcc, 0x3e51480c, 0x3f6e57e0, 0x3f4f759d, 0x3c89ac20, 0x3f455ae5, 0x3f23520b, 0x3f4254d0, 0x3f4762d4, 0x3e646460, 0x3ce018a0, 0x3e7ff60c, 0x3e7dbe08, 0x3f490e08, 0x3eab9ab0, 0x3f71279e, 0x3ec308dc, 0x3e79b7e8, 0x3f0533ca, 0x3e9092d0, 0x3f34ddf6, 0x3ebf1bfc, 0x3f287aca, 0x3f484329, 0x3ef93cb6, 0x3f086c69, 0x3f177abb, 0x3ee61b4e, 0x3e882744, 0x3f5d5d3d, 0x3d032af0, 0x3e86e918, 0x3e3787f8, 0x3e99895c, 0x3f1bf283, 0x3f7465f2, 0x3f3a3760, 0x3c8394c0, 0x3ed7777a, 0x3d429930, 0x3f519e3a, 0x3e119e9c, 0x3f1255b6, 0x3e56ab2c, 0x3f76628c, 0x3f75ffc9, 0x3ee93664, 0x3eb53df8, 0x3f722cfd, 0x3f671072, 0x3f325175, 0x3f6b4b00, 0x3e56199c, 0x3ed8c590, 0x3f284d2c, 0x3f2b1b87, 0x3e6548d8, 0x3f1813fd, 0x3f253675, 0x3f3ea74a, 0x3ebdaffc, 0x3f623436, 0x3f7ca4f7, 0x3ef80a6e, 0x3f2fd989, 0x3e97173c, 0x3f429e6f, 0x3f6a5080, 0x3efc7faa, 0x3f68eabf, 0x3f32bd55, 0x3ead4eae, 0x3f48fb09, 0x3e6f1bd0, 0x3c9c7b80, 0x3f2c641e, 0x3f2c62c7, 0x3dfbb258, 0x3eed3488, 0x3e4145d4, 0x3ef7b352, 0x3e261aec, 0x3f490dac, 0x3d5812f0, 0x3edf7d5c, 0x3f145c08, 0x3f0a4d41, 0x3f423434, 0x3e85940e, 0x3ecf4dbe, 0x3f2bf841, 0x3f2441e2, 0x3f2ab4d1, 0x3f6280f8, 0x3e2bf75c, 0x3c89cda0, 0x3f6eb70d, 0x3ec03ac8, 0x3cfe2700, 0x3ca7f1a0, 0x3d6cdd50, 0x3e617ee0, 0x3efb8ad2, 0x3f151055, 0x3df1f228, 0x3ebbda10, 0x3e5cd078, 0x3e6a4abc, 0x3f146456, 0x3ed83d5a, 0x3f572cf9, 0x3e803aaa, 0x3ec6558a, 0x3cafa8c0, 0x3f6ca7e8, 0x3f3e72ed, 0x3c539440, 0x3ed5dbd2, 0x3f190013, 0x3f54dc87, 0x3cba8620, 0x3f19e297, 0x3edbbc60, 0x3f3b6eab, 0x3f24e529, 0x3eb322e8, 0x3db05d18, 0x3b1da600, 0x3f5cb546, 0x3e4589b8, 0x3ee4f080, 0x3ebb4742, 0x3f2d2824, 0x3f17f560, 0x3e990320, 0x3f2a0a5b, 0x3e8dc70c, 0x3dba2c20, 0x3f640dfb, 0x3f0c54b2, 0x3f68b832, 0x3f072818, 0x3e011bec, 0x3f04d165, 0x3d15b270, 0x3f02ccb0, 0x3f26d422, 0x3f3403f1, 0x3f30c556, 0x3ef45046, 0x3de2eec8, 0x3e0befdc, 0x3db9c658, 0x3f25c969, 0x3f1a076a, 0x3f07da9d, 0x3eb46cd0, 0x3f7a1c27, 0x3e067c54, 0x3f73b91c, 0x3e9d248e, 0x3ee76372, 0x3f7a90dd, 0x3ec7cde8, 0x3ebcccea, 0x3e471868, 0x3e580598, 0x3eaea5d6, 0x3e17722c, 0x3f7da451, 0x3f46e5df, 0x3f1d91c9, 0x3ed3e17c, 0x3f6374ab, 0x3f09a825, 0x3edd9b1c, 0x3f2f6298, 0x3df09568, 0x3f3d1043, 0x3e1cc804, 0x3f78f9d1, 0x3f2ba9e8, 0x3f5b78d7, 0x3f334558, 0x3f316de8, 0x3f6ef91e, 0x3f31afd0, 0x3f0b2158, 0x3e8e10b0, 0x3edf2d64, 0x3dd6e110, 0x3f225347, 0x3f6d9959, 0x3ed320c6, 0x3e70d344, 0x3e56fdd0, 0x3f5d77a8, 0x3ea6728a, 0x3ee569e4, 0x3cb04d00, 0x3f3d3403, 0x3f432b18, 0x3cd6f2c0, 0x3f2d2f41, 0x3f3d8e67, 0x3e44f684, 0x3f25c4d7, 0x3f27bff1, 0x3f63e0cc, 0x3f63d261, 0x3f5708ab, 0x3ea6ad68, 0x3e92e8a0, 0x3ec7b2a8, 0x3e9e2806, 0x3e85dab2, 0x3e841af4, 0x3e4de57c, 0x3f533c07, 0x3e8cf034, 0x3eb08c02, 0x3ec0b52c, 0x3f4fccf0, 0x3f450456, 0x3f1611b5, 0x3eb682c4, 0x3f3d1629, 0x3f08e6c0, 0x3d88b960, 0x3ee858de, 0x3f7a1db8, 0x3e694c18, 0x3eea23e4, 0x3f5d92f8, 0x3f6247d8, 0x3ea96e62, 0x3f22f878, 0x3f7ca7c3, 0x3ef5a19e, 0x3efb917e, 0x3ece38ce, 0x3f6ffcce, 0x3f6f8161, 0x3f62cc20, 0x3ef849fe, 0x3f4d7328, 0x3f6c6233, 0x3dbb78f8, 0x3f63b421, 0x3d0ffff0, 0x3e21b148, 0x3e070a9c, 0x3d255c60, 0x3c81a9a0, 0x3f271171, 0x3efec452, 0x3f247bff, 0x3e816868, 0x3dab3408, 0x3f0071de, 0x3de909b0, 0x3f53b218, 0x3de4f200, 0x3ee2dc06, 0x3f1e3273, 0x3d1dbd50, 0x3d3bc1f0, 0x3e72dc20, 0x3f2921a7, 0x3f4e41b9, 0x3ec58d5e, 0x3f51ce94, 0x3f565b18, 0x3ed741f0, 0x3f367441, 0x3f0e265c, 0x3e40fa48, 0x3e2b5118, 0x3c98b7c0, 0x3f003e6a, 0x3f6d277f, 0x3e0dcc8c, 0x3f75654b, 0x3f45a03e, 0x3eec46a4, 0x3ca7f820, 0x3e937bc0, 0x3f27efc4, 0x3e5b3990, 0x3e7d651c, 0x3eb65652, 0x3e9fb5a8, 0x3f058f3e, 0x3f3a1be6, 0x3f7396ab, 0x3f21af26, 0x3e9628b0, 0x3f15e4f5, 0x3f5a691b, 0x3f6a8a45, 0x3f30558c, 0x3f24d9e0, 0x3f1b0465, 0x3ea9a774, 0x3efef674, 0x3f4ac8cf, 0x3f31965b, 0x3f292f47, 0x3f4d1662, 0x3f7fd9a8, 0x3dc89ce0, 0x3f31bf2c, 0x3dbf2fb8, 0x3f11056d, 0x3f706665, 0x3ec16a32, 0x3f585ffa, 0x3efb8c32, 0x3eafa1cc, 0x3f499693, 0x3f1d98fb, 0x3e3c0d90, 0x3f54e9b3, 0x3f084daf, 0x3f41cc22, 0x3dcb2790, 0x3cceba40, 0x3f7f2b2a, 0x3f2e0799, 0x3f32acd5, 0x3f408035, 0x3dca84b0, 0x3ef2750a, 0x3f418550, 0x3ed317c8, 0x3cbbbac0, 0x3e669788, 0x3e123e94, 0x3e5a33c0, 0x3f0cb858, 0x3f4fdebf, 0x3e8ae73e, 0x3f3ad384, 0x3f5fac72, 0x3f68225e, 0x3f299d5b, 0x3f383eb2, 0x3d2e2fc0, 0x3e86ebfe, 0x3ed4dd82, 0x3eb7489a, 0x3e0d7c48, 0x3f7216ff, 0x3d8de648, 0x3f27f280, 0x3f2986a1, 0x3e09a7f0, 0x3f4eabbe, 0x3e915532, 0x3ead61b0, 0x3f6c69ce, 0x3f448c4e, 0x3f39a72a, 0x3d6adc00, 0x3f15016d, 0x3f5e2975, 0x3e3a381c, 0x3f117bf9, 0x3f23d70f, 0x3f4a572f, 0x3f4da388, 0x3f18020b, 0x3f5d0c0c, 0x3f089df5, 0x3f4f9b78, 0x3e55f310, 0x3df335f8, 0x3e989620, 0x3ef388a0, 0x3f3ea204, 0x3f24c82e, 0x3f30d6ca, 0x3da9e5c8, 0x3e257ba8, 0x3f3ce840, 0x3f600e76, 0x3f4ffbb9, 0x3e64f914, 0x3f4379fd, 0x3ec28b48, 0x3f169355, 0x3da2a9d0, 0x3f5f400d, 0x3f14f664, 0x3f748e3c, 0x3f54bead, 0x3f2b8a26, 0x3e800e16, 0x3ebfc00e, 0x3f59eeb2, 0x3e427770, 0x3e7392a4, 0x3dcf7eb0, 0x3f16ad97, 0x3f792cb7, 0x3f59f716, 0x3f513bd6, 0x3f1c096a, 0x3f2d24f1, 0x3dc40ea0, 0x3ef7821c, 0x3f731fc0, 0x3e41f49c, 0x3e4c64a0, 0x3e8bfe88, 0x3d529000, 0x3da02110, 0x3ef52a00, 0x3eb6444c, 0x3dadb828, 0x3ebda364, 0x3f2fe0d1, 0x3e3b0660, 0x3e8bbeda, 0x3f0b56bd, 0x3f7121e5, 0x3f5671aa, 0x3f1b0b70, 0x3f714a25, 0x3f61cdce, 0x3ea6916c, 0x3f745fb4, 0x3ed63536, 0x3f1fa671, 0x3e221058, 0x3ed3a964, 0x3f60ac46, 0x3f10e377, 0x3dfb3328, 0x3f217fcf, 0x3e999712, 0x3f192c83, 0x3f3b2a9e, 0x3f5a65c4, 0x3efae0a6, 0x3e699c84, 0x3f077ba8, 0x3e365360, 0x3ed759c4, 0x3d0d34c0, 0x3f162cf4, 0x3f1a5f7b, 0x3ea8b7b8, 0x3f08cf56, 0x3ef5f27a, 0x3f4da628, 0x3e4ec16c, 0x3e2a9660, 0x3f108fbc, 0x3ee1f14e, 0x3f0f22a8, 0x3ecdd798, 0x3f6a96ff, 0x3ee219f4, 0x3e83d640, 0x3ef035e6, 0x3efc0d4e, 0x3ea456fc, 0x3f792d31, 0x3e407ae4, 0x3f076787, 0x3e3c0354, 0x3f30345e, 0x3f37721e, 0x3f4bac1e, 0x3e000e68, 0x3ef4a632, 0x3f1d8a79, 0x3f1b8efb, 0x3ee5baa8, 0x3e723a74, 0x3eddfe00, 0x3bdbda00, 0x3ea2edc2, 0x3ecd4328, 0x3f0667b2, 0x3ea660d6, 0x3e1485b8, 0x3f1d75db, 0x3eb8d374, 0x3dcd85c8, 0x3eb15f44, 0x3ebe3540, 0x3e0b351c, 0x3edf448a, 0x3f3f6611, 0x3b057d00, 0x3deefdf0, 0x3ea77d9a, 0x3eb96394, 0x3f13827e, 0x3f79fbc1, 0x3f43df3d, 0x3f40e6d9, 0x3e4d4560, 0x3f01590a, 0x3f3f1770, 0x3f5075ee, 0x3c016940, 0x3f369ccb, 0x3eef9256, 0x3f5c8a2b, 0x3eff87c6, 0x3ef98f3e, 0x3efc372a, 0x3f6c1bbe, 0x3d985528, 0x3f0fac56, 0x3ea1a5c8, 0x3d588fc0, 0x3f74d0e1, 0x3c2bfb80, 0x3f21bb2f, 0x3f4164fa, 0x3e7ee518, 0x3f3e7fc1, 0x3f5f306b, 0x3f2a9288, 0x3e402ec4, 0x3ecbc582, 0x3f3f92e6, 0x3ed30bb2, 0x3ece7c06, 0x3f1627af, 0x3e9e5b68, 0x3e83defa, 0x3f13f3d7, 0x3e9b44c8, 0x3eb6326a, 0x3f1e320d, 0x3f345313, 0x3f402f2a, 0x3e436ad0, 0x3f6b6267, 0x3f77bf4f, 0x3e25b374, 0x3f082df3, 0x3f0518ce, 0x3ed9cd10, 0x3e0e79bc, 0x3f375186, 0x3ef78588, 0x3f65373c, 0x3e0a1c48, 0x3efc3e56, 0x3e147014, 0x3f4c0eb4, 0x3ee02dc8, 0x3eb077a8, 0x3f6f37d5, 0x3efe9988, 0x3f6641c7, 0x3f6e233b, 0x3f5a3c19, 0x3e558d0c, 0x3f5cc5c2, 0x3eb8a8ba, 0x3f2cc5d1, 0x3f3101a7, 0x3de0c6e8, 0x3f54fef7, 0x3d95c008, 0x3e788eec, 0x3f1b67dd, 0x3f222409, 0x3f712da8, 0x3e67405c, 0x3f31b7d3, 0x3f4fd102, 0x3efd046c, 0x3efca6b0, 0x3f6d19a5, 0x3df793e8, 0x3daa5070, 0x3f7702cb, 0x3f506ab7, 0x3f27a076, 0x3f55bb1e, 0x3f72bd64, 0x3f27c240, 0x3d93cf20, 0x3f10d198, 0x3f2cc756, 0x3d59c870, 0x3f111e75, 0x3e4daff0, 0x3f0c06ad, 0x3f5da51d, 0x3e9dc660, 0x3eceaa4c, 0x3f58d67a, 0x3f44e0b4, 0x3daa4100, 0x3f47d049, 0x3e9400d8, 0x3e188cdc, 0x3e4b3d50, 0x3e8a3384, 0x3f3cbc6c, 0x3d554a90, 0x3edda170, 0x3ef5c6f4, 0x3ef7e32c, 0x3f468a31, 0x3d316110, 0x3f3b6d31, 0x3f70fabc, 0x3e7612bc, 0x3ec31408, 0x3f3676ac, 0x3e686450, 0x3ed8430e, 0x3f4ff828, 0x3d7e8100, 0x3e3bea48, 0x3de5ed28, 0x3d933b70, 0x3f65a8ef, 0x3c2b2400, 0x3e96fb7e, 0x3e4e3ed4, 0x3e4e905c, 0x3f6ef198, 0x3f0a7cf9, 0x3f3bd186, 0x3e02fcf4, 0x3f4f5b14, 0x3f11f976, 0x3c8567e0, 0x3e437f3c, 0x3d927f70, 0x3f436845, 0x3d3c3f30, 0x3e2e7e40, 0x3f2f5336, 0x3ed60ba6, 0x3f585907, 0x3ea42d1c, 0x3f53a5c3, 0x3ef1d578, 0x3d12f280, 0x3ea58648, 0x3f1db202, 0x3ed896d0, 0x3f1a69a7, 0x3e4895f8, 0x3e88f8de, 0x3ebae986, 0x3f2cacb6, 0x3e8b6300, 0x3f097243, 0x3d6d6890, 0x3f36aa21, 0x3dda6810, 0x3f5d5525, 0x3f773125, 0x3f08d4c5, 0x3ebb9654, 0x3f144a20, 0x3dba7120, 0x3f7e3683, 0x3ec8aa32, 0x3f69c524, 0x3f7356b9, 0x3d080870, 0x3f6afdd4, 0x3f797221, 0x3f6ee080, 0x3f174546, 0x3f63de2d, 0x3f0e2ba6, 0x3e8caba8, 0x3f7ed398, 0x3f1693d5, 0x3e2617fc, 0x3f4fb2de, 0x3e3aa900, 0x3f2a6432, 0x3e440a70, 0x3f7adf8b, 0x3eaff642, 0x3f33e8a1, 0x3e256498, 0x3e0dcc58, 0x3f38da84, 0x3e36d164, 0x3ea298a6, 0x3ebdbe6e, 0x3f4a9e9b, 0x3f3166c6, 0x3f403ca9, 0x3ee83b92, 0x3e6ec430, 0x3d567790, 0x3ee04c4c, 0x3f327eec, 0x3f7fb102, 0x3f39927d, 0x3ef05162, 0x3f18137c, 0x3f2d0df7, 0x3f4fd610, 0x3ee98a1e, 0x3dcb7bf0, 0x3f20d328, 0x3f3b9016, 0x3ad8fc00, 0x3f33401a, 0x3f08ff04, 0x3e879e7c, 0x3ebfabca, 0x3f062c57, 0x3f252797, 0x3c24c100, 0x3f5e3746, 0x3f5e2942, 0x3f04073d, 0x3eb16d70, 0x3f2a5fdf, 0x3f4eabd0, 0x3f45c239, 0x3f7d2f3a, 0x3f11bbdd, 0x3f0037c2, 0x3f0786a2, 0x3e909d36, 0x3d8ab390, 0x3ed8ae20, 0x3e2f5364, 0x3f24b350, 0x3f5e11ee, 0x3f4ecc19, 0x3f162952, 0x3ea0adbc, 0x3ee0edc0, 0x3f2e20f3, 0x3c141e80, 0x3e2d0eb4, 0x3e99b296, 0x3ea387f0, 0x3f045ce5, 0x3c0aea80, 0x3f025ea1, 0x3e8d1594, 0x3deaace0, 0x3f01ec3a, 0x3e798b40, 0x3f6190f6, 0x3ec02984, 0x3e9da7c8, 0x3f6e0478, 0x3cb27220, 0x3f423983, 0x3f17954b, 0x3cad7400, 0x3f04289c, 0x3ef04050, 0x3e41f8e8, 0x3e596930, 0x3eaf7e62, 0x3f2d03bc, 0x3f675d3c, 0x3f6acb66, 0x3f204dd4, 0x3f42f7f0, 0x3f5d68e3, 0x3eb8faa2, 0x3e9e208e, 0x3db43448, 0x3f7c3108, 0x3f06eb2f, 0x3df76fd0, 0x3f726839, 0x3f788afa, 0x3d2df150, 0x3f73f521, 0x3ee9f9fa, 0x3ecbcd28, 0x3e4d208c, 0x3dacc190, 0x3e50ee64, 0x3dbe8f88, 0x3f7b7970, 0x3f366db3, 0x3f69a598, 0x3ee6fcec, 0x3f56d6e5, 0x3f4b45d8, 0x3e218a18, 0x3ea5a320, 0x3f0a59ca, 0x3f1281a9, 0x3eead684, 0x3e2287f8, 0x3f002c55, 0x3f06f0e7, 0x3f7185a6, 0x3f563dfe, 0x3eda6c3e, 0x3f50510a, 0x3e0bd720, 0x3f364ccc, 0x3f6cb83c, 0x3e5c546c, 0x3f7160a0, 0x3f7a25d1, 0x3f2dc4c6, 0x3ddf1050, 0x3eb86014, 0x3f307988, 0x3e60b364, 0x3f2b216f, 0x3f170233, 0x3e90a560, 0x3f1fb4bb, 0x3f5c6307, 0x3f76e518, 0x3f579f62, 0x3eb86790, 0x3ef9d3ca, 0x3e99df66, 0x3e3fb484, 0x3ee57db0, 0x3de866c8, 0x3f0339c6, 0x3f32e51d, 0x3e46e738, 0x3f510500, 0x3f7cd665, 0x3f33a5da, 0x3e65e29c, 0x3f6270c5, 0x3f63d846, 0x3f48314f, 0x3cf30d40, 0x3e908352, 0x3f2e7409, 0x3dd3d868, 0x3ea48c34, 0x3c82db60, 0x3f21bf14, 0x3f756025, 0x3f45cae6, 0x3f5cf345, 0x3f564efa, 0x3f580521, 0x3f1dd566, 0x3d264190, 0x3e8df1a4, 0x3c2d0b40, 0x3eeb6ce2, 0x3f2e578b, 0x3f50245b, 0x3dbb7e00, 0x3f4343d9, 0x3f300078, 0x3f4ee399, 0x3e64e4bc, 0x3f28ffa4, 0x3f5ca694, 0x3e6593f0, 0x3f536710, 0x3eb0528a, 0x3ea7e840, 0x3f54e1d4, 0x3f28760a, 0x3f463c53, 0x3f1f4ded, 0x3f604425, 0x3f270acd, 0x3ee33c98, 0x3ddcf9e8, 0x3d8e3fe8, 0x3ebb1ca4, 0x3f0e38a2, 0x3ec5ac5e, 0x3f250d7a, 0x3ef72cd2, 0x3dbe4268, 0x3f3b1d04, 0x3f3f0582, 0x3e219e5c, 0x3ea6702e, 0x3f6beed3, 0x3f4c4630, 0x3eab05c0, 0x3f1085b2, 0x3f287fb3, 0x3f1cbb42, 0x3f0407ce, 0x3e474f60, 0x3f461279, 0x3ef0d36c, 0x3f26d8ef, 0x3e0f9860, 0x3eb7626a, 0x3eaa6ee0, 0x3d3ad180, 0x3ee73df2, 0x3f4fa2c1, 0x3f3fd545, 0x3f6f0e09, 0x3ec0cb9a, 0x3dd1c540, 0x3f0e4267, 0x3f7a8993, 0x3f71f72a, 0x3f13f715, 0x3f2934e9, 0x3f4d1b2b, 0x3f73b580, 0x3f24d9a9, 0x3f46160d, 0x3f005880, 0x3e28e334, 0x3f596991, 0x3e0d9ba4, 0x3e5bb108, 0x3e2d0298, 0x3ec001c8, 0x3e44075c, 0x3f02abe7, 0x3e48b7e0, 0x3f48f140, 0x3e371784, 0x3f724e6e, 0x3f63981a, 0x3f39aaa9, 0x3d023890, 0x3f0754cc, 0x3f341bd4, 0x3f16fd77, 0x3e4caa04, 0x3e423cf8, 0x3f6cc610, 0x3f16c03a, 0x3f6f8276, 0x3e9ad074, 0x3ec44f62, 0x3f185439, 0x3e572f90, 0x3f09432a, 0x397ed000, 0x3d006030, 0x3f6cce05, 0x3e6ffa90, 0x3e89707c, 0x3ec25468, 0x3d4c4850, 0x3f5e0be1, 0x3f21058c, 0x3f53870b, 0x3dcf7c00, 0x3eb316a2, 0x3e1fd5ec, 0x3ee94d58, 0x3f2a5bc7, 0x3f140db9, 0x3ecfbdf8, 0x3f7adedf, 0x3eb7adc8, 0x3f46abdb, 0x3f67a77e, 0x3f5de512, 0x3f071c08, 0x3df25a78, 0x3e4e1280, 0x3f38d7fc, 0x3f3bbb2d, 0x3f6b2c21, }; // 2,3,5,5 uint32_t kernel_vals[] = { 0x3e1010ca, 0xbd9de6bf, 0xbdb40e03, 0x3d07c460, 0x3dafaf78, 0xbccd1bd8, 0xbe1e0e30, 0xbaea0500, 0x3e05b604, 0x3c917808, 0x3e34318a, 0x3cf2cc70, 0x3dba5928, 0xbdef8b99, 0x3deeaf4c, 0x3e0999e4, 0xbcd53068, 0xbd1ff43c, 0x3e1fe34a, 0x3cfddc80, 0x3d891584, 0x3e2412a0, 0xbe18e584, 0x3e276c82, 0x3c90c168, 0xbdeb852c, 0x3e2ee1e8, 0xbe1c7d4b, 0xbe019dbd, 0x3bad51c0, 0x3e0acf02, 0x3cb43390, 0xbd828287, 0x3d279350, 0x3d8108b0, 0xbdb5cade, 0xbe291e11, 0xbddf82e9, 0xbda02529, 0xbd61ae8c, 0xbd8f694b, 0xbd358f20, 0xbe181e84, 0x3df22f4c, 0xbe364531, 0xbe1026d4, 0xbdf32df6, 0xbe0e3a40, 0x3e17ef54, 0xbca39b48, 0xbd9493c8, 0xbe342924, 0x3b92be80, 0xbdb81fab, 0x3d306e5c, 0xbd9226b0, 0x3e38f870, 0x3e16adbc, 0x3e12bdde, 0xbe2336c5, 0xbd4dc424, 0x3db7f748, 0x3d839a8a, 0xbe34d672, 0x3e1c0870, 0xbdc20690, 0xbe2b2f41, 0x3d374784, 0x3d9a9b28, 0xbe2067f5, 0x3e29e600, 0xbd91ac51, 0xbdc2de89, 0x3d43c5a8, 0x3e1d16f6, 0xbe0068ff, 0x3c4c4b20, 0x3e25828c, 0x3e298766, 0xbdf0dabf, 0xbdcca37b, 0xbe3720f9, 0xbdc71d63, 0xbe24b4d1, 0xbda01e6d, 0x3da88708, 0xbd25e58c, 0xbd84a85c, 0x3e0154de, 0xbd10a28c, 0xbcc18120, 0xbd9ed2bc, 0xbd44b5dc, 0x3e36fabe, 0xbdef4e3b, 0xbe31bfbd, 0xbcc802e0, 0x3db30ed0, 0xbc7a8200, 0x3e372460, 0x3d71c758, 0x3def98d4, 0x3d3826b0, 0xbdc5af54, 0xbd8cc9db, 0xbe04e70c, 0x3d36a850, 0xbe2cf434, 0x3dbae5f0, 0xbb9842a0, 0xbe0f969d, 0x3ddf7740, 0xbcb578d0, 0xbd0f7e4c, 0x3d916ec0, 0xbcd51e38, 0x3bc6af20, 0x3e0ef404, 0x3e28d4d4, 0x3d515bc4, 0x3d7d46cc, 0xbe177230, 0xbdf16a23, 0x3be38380, 0x3d9ecbcc, 0x3b974ce0, 0x3e272334, 0x3e1a3306, 0xbd79275e, 0x3e0c2950, 0xbdbe384a, 0xbdea4848, 0x3d23abb8, 0xbce4c568, 0xbc9cf250, 0xbde2f2f6, 0xbb33ed40, 0xbd2594e8, 0xbe375192, 0xbe039f4b, 0x3d08aae0, 0xbe10a348, 0x3cf9a400, 0x3e2eb8a6, 0x3c67d8b0, 0xbd5300d4, 0xbabd1200, 0xbdab0df9, 0xbd9b63b2, 0x3e14ad7a, }; // 5 uint32_t bias_vals[] = { 0xbc13d600, 0xbd897640, 0x3d116244, 0x3df5dc48, 0xbce727a0, }; // 3,5,3,5 uint32_t output_exp_vals[] = { 0xbee9b3fc, 0xbf17b60f, 0xbe484f39, 0x3f0961db, 0x3d4c1743, 0xbf2531ad, 0xbe9e12fb, 0xbd2cb655, 0x3e7577b7, 0x3e57e7a6, 0xbddbe7ef, 0xbd9c38f2, 0xbe8bdcb8, 0x3f07b811, 0x3e993fa2, 0xbee4d216, 0xbed2d3c1, 0xbf018cf6, 0x3e9ab29a, 0xbc846189, 0xbe2a2151, 0xbf0cf26c, 0xbe3d15aa, 0x3ec875d1, 0xbce80543, 0xbd2144f7, 0xbea62a1f, 0xbf0a4bb7, 0x3f1e16ea, 0xbe6af02a, 0xbefc6588, 0xbed44ade, 0xbf129453, 0x3ee895e4, 0xbdc1fd8c, 0xbec8491e, 0xbe75412e, 0xbdec8108, 0x3f1ac5f4, 0x3dbea2f0, 0xbdfc22ef, 0xbe71cce2, 0xbeee18a0, 0x3f0d220f, 0xbd4cce24, 0xbe78ddf6, 0xbec93b9a, 0xbf06ee8e, 0x3f03fe72, 0x3e3ac3ba, 0xbf12738d, 0xbf2febbf, 0xbebc542d, 0x3e8172af, 0xbd330054, 0xbeb90581, 0xbec3ecc7, 0xbf310a62, 0x3f4cf144, 0xbe7f9437, 0xbe86389f, 0xbec82670, 0xbe71353a, 0x3f0802ad, 0x3df16c7b, 0xbeab9b58, 0xbecb53ec, 0xbee876ac, 0x3f218016, 0x3e0a5d6e, 0xbe80e3b4, 0xbe6a7756, 0xbea33ab7, 0x3f3949a0, 0xbe2f42e1, 0xbe3941bb, 0xbddc8acb, 0xbecacf4e, 0x3ef3e4ce, 0x3eb546d3, 0xbee8c535, 0xbee112e6, 0xbe5fdadc, 0x3f58da9c, 0x3dc93527, 0xbdb5e1ed, 0xbe3e8ebb, 0xbec5b836, 0x3ec7d54a, 0x3d819f14, 0xbf0426fb, 0xbefe0525, 0xbe8f9be7, 0x3f4a54bd, 0x3dae38c1, 0xbf211377, 0xbea54527, 0xbf0947c1, 0x3db8822c, 0xbb87d99d, 0xbe25102c, 0xbe8a8a9d, 0xbf0bf3db, 0x3f5a6b25, 0xbe0e5dfa, 0xbdfbbc30, 0xbc731067, 0xbea56ac8, 0x3e765c6e, 0x3f01f8c7, 0xbea4492e, 0xbf227ee2, 0xbe21160c, 0x3e457e8b, 0x3eaed0ce, 0xbd9b51a3, 0xbeaefc45, 0xbeade1a5, 0x3efa07f4, 0x3c93b7b0, 0xbf0bc708, 0xbe736c16, 0xbebb2c04, 0x3f4cffa1, 0xbe6ba6d8, 0xbe6e2e8f, 0xbefa7f52, 0xbeb2ea70, 0x3f2b9797, 0xbdc01028, 0xbc79e4b4, 0xbe13949a, 0xbeb5c4d9, 0x3ebf20b2, 0x3bd54764, 0xbf0d56cd, 0xbee63f7f, 0xbde73ed3, 0x3ed4308f, 0x3dfa5af5, 0xbf22f3df, 0xbe1374eb, 0xbe34d7fa, 0x3e1a3b6d, 0x3e1f64b5, 0xbde3cde2, 0xbe300e8a, 0xbe04bcd1, 0x3f315c43, 0x3d585df5, 0xbec3da8a, 0xbe56fc4e, 0xbf353dcf, 0x3ebcad9c, 0x3c2c3339, 0xbe66802a, 0xbef105fa, 0xbee068fa, 0x3eb0b458, 0xba9b0dc8, 0xbd473b6e, 0xbe8544e8, 0xbebb0b5d, 0x3f0ce772, 0x3e0fecd2, 0xbf1b6e40, 0xbd1dd2cd, 0xbe6f7d6c, 0x3d20971f, 0x3e0530f4, 0xbc98b77a, 0xbeee6e72, 0xbef41f95, 0x3ef63aa7, 0x3ee45d03, 0xbea14327, 0xbef5e1a9, 0xbee27363, 0x3f1ee832, 0xbe403bbc, 0xbe42f7ae, 0xbe932cb8, 0xbeb69872, 0x3ebeca24, 0xbd155237, 0xbecb8a26, 0xbead579a, 0xbec12b5a, 0xbcecc13d, 0xbb50feab, 0xbd660f71, 0xbe938724, 0xbf0ee147, 0x3efae9af, 0x3e55edd3, 0xbea91e8f, 0xbed6ee3b, 0xbf095e37, 0x3e9da89b, 0x3e994dee, 0xbdcc19ee, 0xbed770c0, 0xbe91cccc, 0x3f06de06, 0xbde3ada4, 0xbd40085a, 0xbd522e19, 0xbe92716c, 0x3f4a1856, 0x3e3a5b61, 0xbf04a036, 0xbeae4b75, 0xbe462a7d, 0x3f07781f, 0x3e5d9f05, 0xbe83bdf3, 0xbeb8640d, 0xbf061386, 0x3e8624aa, 0x3eba5fd0, 0xbe5c435e, 0xbedc4cac, 0xbf00a447, 0x3f118d65, 0x3d7c81bf, }; // 3,5,3,5 uint32_t output_relu_exp_vals[] = { 0x0, 0x0, 0x0, 0x3f0961db, 0x3d4c1743, 0x0, 0x0, 0x0, 0x3e7577b7, 0x3e57e7a6, 0x0, 0x0, 0x0, 0x3f07b811, 0x3e993fa2, 0x0, 0x0, 0x0, 0x3e9ab29a, 0x0, 0x0, 0x0, 0x0, 0x3ec875d1, 0x0, 0x0, 0x0, 0x0, 0x3f1e16ea, 0x0, 0x0, 0x0, 0x0, 0x3ee895e4, 0x0, 0x0, 0x0, 0x0, 0x3f1ac5f4, 0x3dbea2f0, 0x0, 0x0, 0x0, 0x3f0d220f, 0x0, 0x0, 0x0, 0x0, 0x3f03fe72, 0x3e3ac3ba, 0x0, 0x0, 0x0, 0x3e8172af, 0x0, 0x0, 0x0, 0x0, 0x3f4cf144, 0x0, 0x0, 0x0, 0x0, 0x3f0802ad, 0x3df16c7b, 0x0, 0x0, 0x0, 0x3f218016, 0x3e0a5d6e, 0x0, 0x0, 0x0, 0x3f3949a0, 0x0, 0x0, 0x0, 0x0, 0x3ef3e4ce, 0x3eb546d3, 0x0, 0x0, 0x0, 0x3f58da9c, 0x3dc93527, 0x0, 0x0, 0x0, 0x3ec7d54a, 0x3d819f14, 0x0, 0x0, 0x0, 0x3f4a54bd, 0x3dae38c1, 0x0, 0x0, 0x0, 0x3db8822c, 0x0, 0x0, 0x0, 0x0, 0x3f5a6b25, 0x0, 0x0, 0x0, 0x0, 0x3e765c6e, 0x3f01f8c7, 0x0, 0x0, 0x0, 0x3e457e8b, 0x3eaed0ce, 0x0, 0x0, 0x0, 0x3efa07f4, 0x3c93b7b0, 0x0, 0x0, 0x0, 0x3f4cffa1, 0x0, 0x0, 0x0, 0x0, 0x3f2b9797, 0x0, 0x0, 0x0, 0x0, 0x3ebf20b2, 0x3bd54764, 0x0, 0x0, 0x0, 0x3ed4308f, 0x3dfa5af5, 0x0, 0x0, 0x0, 0x3e1a3b6d, 0x3e1f64b5, 0x0, 0x0, 0x0, 0x3f315c43, 0x3d585df5, 0x0, 0x0, 0x0, 0x3ebcad9c, 0x3c2c3339, 0x0, 0x0, 0x0, 0x3eb0b458, 0x0, 0x0, 0x0, 0x0, 0x3f0ce772, 0x3e0fecd2, 0x0, 0x0, 0x0, 0x3d20971f, 0x3e0530f4, 0x0, 0x0, 0x0, 0x3ef63aa7, 0x3ee45d03, 0x0, 0x0, 0x0, 0x3f1ee832, 0x0, 0x0, 0x0, 0x0, 0x3ebeca24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3efae9af, 0x3e55edd3, 0x0, 0x0, 0x0, 0x3e9da89b, 0x3e994dee, 0x0, 0x0, 0x0, 0x3f06de06, 0x0, 0x0, 0x0, 0x0, 0x3f4a1856, 0x3e3a5b61, 0x0, 0x0, 0x0, 0x3f07781f, 0x3e5d9f05, 0x0, 0x0, 0x0, 0x3e8624aa, 0x3eba5fd0, 0x0, 0x0, 0x0, 0x3f118d65, 0x3d7c81bf, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, SAME_PADDING, NULL); } void test_valid_padding_non_zero_strides_large() { input_set *set = &large_input; strides_input_set *strides = &large_non0_strides; // 4,15,10,6 uint32_t input_vals[] = { 0x3efb1fe6, 0x3f04c7af, 0x3e09e1c4, 0x3f0c288a, 0x3ec9f8a8, 0x3f69e8f8, 0x3e3ad78c, 0x3f6d04b6, 0x3f5c45b3, 0x3ece8426, 0x3f47fb5c, 0x3ebe3d66, 0x3f101556, 0x3f09cdc8, 0x3f6706c4, 0x3e0f1eb4, 0x3ec8bc90, 0x3dbd7ff8, 0x3b17de00, 0x3e931fc2, 0x3e7470b4, 0x3f62874f, 0x3d194080, 0x3f54f750, 0x3e43d79c, 0x3e659be8, 0x3f6dd296, 0x3f0ce854, 0x3eec83a2, 0x3e3a5c7c, 0x3dbfdce8, 0x3f14bd6f, 0x3eb2de3c, 0x3e895b6a, 0x3f64c7d1, 0x3bbf4400, 0x3f069316, 0x3eaa5b92, 0x3c677f40, 0x3f524fcf, 0x3e5915f0, 0x3eea46d2, 0x3e66215c, 0x3f40b78b, 0x3ed69440, 0x3f2d50b6, 0x3f6bdec5, 0x3f7b4367, 0x3efa6a62, 0x3da8c580, 0x3dfb13b8, 0x3de07918, 0x3f473fdf, 0x3df834f8, 0x3df558d0, 0x3e27efbc, 0x3f1ab25f, 0x3ed5af5e, 0x3ee2c9ba, 0x3f1bbf99, 0x3d8dc3b0, 0x3f6fa25c, 0x3f18bc2d, 0x3d8db638, 0x3ef80f76, 0x3de52090, 0x3ee26e70, 0x3e9ce620, 0x3e8f10c8, 0x3e62ada0, 0x3f6a02d0, 0x3f3457d3, 0x3f0f148b, 0x3bec7800, 0x3eb62f06, 0x3f17133c, 0x3f0211b9, 0x3f56b35c, 0x3f5c1b82, 0x3f5b93c2, 0x3f25babc, 0x3f237624, 0x3f115d74, 0x3ed65682, 0x3ea877aa, 0x3eba8990, 0x3e67ae8c, 0x3e9cfce2, 0x3f0a8356, 0x3d611b90, 0x3f79c40c, 0x3f00c1a1, 0x3f34a013, 0x3ea5df38, 0x3f09a2e3, 0x3e016568, 0x3e11df40, 0x3f4f4e7b, 0x3e04d988, 0x3d958d60, 0x3d873190, 0x3e4571cc, 0x3f2c5002, 0x3f2abab0, 0x3f4ace91, 0x3e4378b8, 0x3e584d8c, 0x3ea0633c, 0x3d4d85b0, 0x3ca631c0, 0x3e8631d8, 0x3eefbb12, 0x3f762250, 0x3e85832a, 0x3f7392cc, 0x3f16f6a8, 0x3da94818, 0x3f049964, 0x3f4c4075, 0x3f385374, 0x3e9f60ea, 0x3f7c0541, 0x3f188ebc, 0x3f480457, 0x3f06a99b, 0x3f1cdb4b, 0x3f471879, 0x3ef1355c, 0x3f0d7dc8, 0x3f5508a3, 0x3f78fa60, 0x3dcc6918, 0x3f062a79, 0x3f5d14df, 0x3e05e104, 0x3f6fb45c, 0x3e9c0a5e, 0x3f1047e2, 0x3e990dd2, 0x3f702316, 0x3f70868f, 0x3f18e412, 0x3f36c1c2, 0x3d1567d0, 0x3ec2f846, 0x3f2f2bed, 0x3ea3a6d2, 0x3e052938, 0x3e74002c, 0x3f5bacb6, 0x3ea05d00, 0x3d1b0c00, 0x3f545908, 0x3eb79dce, 0x3f62f452, 0x3eee4680, 0x3f4e453d, 0x3f6dcecc, 0x3ebde2f0, 0x3d75c940, 0x3f4690d8, 0x3f77b2f9, 0x3f5d7c4d, 0x3f6518a8, 0x3f559934, 0x3eec5048, 0x3f2c1e18, 0x3f63fa3f, 0x3f79d1ff, 0x3f265ef8, 0x3e84972c, 0x3f430748, 0x3ef0b100, 0x3e5a6b60, 0x3ec31cca, 0x3eeaebfe, 0x3e1c2028, 0x3f0ea570, 0x3f57326d, 0x3f6310ae, 0x3eb2d324, 0x3e1f5700, 0x3dbc2160, 0x3f3a7367, 0x3f459dbc, 0x3d951300, 0x3e7efe8c, 0x3f1c37dc, 0x3e7aa230, 0x3f6c120d, 0x3f4234c8, 0x3d168a80, 0x3eee7c14, 0x3ea7113e, 0x3e68b00c, 0x3f4297f7, 0x3ea0b0ae, 0x3f55be3a, 0x3f1ef513, 0x3f72b43c, 0x3f3a6516, 0x3ecac4d6, 0x3f039201, 0x3e794510, 0x3eeaedd8, 0x3acafc00, 0x3e2e0a30, 0x3f749de8, 0x3ec2e9f6, 0x3e08f674, 0x3e352a6c, 0x3f1b991c, 0x3ed49d32, 0x3f46f515, 0x3e550574, 0x3e3330cc, 0x3f097109, 0x3efa98f8, 0x3ea2fd6a, 0x3e0404ec, 0x3f1f102f, 0x3e58d0d8, 0x3ef864e0, 0x3f0055f8, 0x3e9f58b4, 0x3f1264ef, 0x3f6e1e66, 0x3d6e0380, 0x3dcced30, 0x3ee02d72, 0x3ee0a450, 0x3f3dbcbd, 0x3f4b58e6, 0x3f106ff4, 0x3eba5ef4, 0x3f362c53, 0x3f46a0a9, 0x3f290de0, 0x3eb889d8, 0x3d91fa90, 0x3ef58618, 0x3d90bf98, 0x3e966d00, 0x3f7b3920, 0x3f492bf2, 0x3eb87c68, 0x3c6bbbc0, 0x3f1b8c60, 0x3da5f5b8, 0x3e300078, 0x3eed0364, 0x3f50a465, 0x3f11cce6, 0x3e2b11a8, 0x3f57243b, 0x3f120649, 0x3f7923d1, 0x3dea6f38, 0x3f2325f1, 0x3f28b92b, 0x3e567b98, 0x3f7c185b, 0x3bac6980, 0x3f570842, 0x3ee800cc, 0x3eea43ee, 0x3f5854b4, 0x3e3ee6f4, 0x3f22787d, 0x3f7eb373, 0x3edca08a, 0x3f103e44, 0x3ee5f136, 0x3e6c3e70, 0x3d6f6d90, 0x3ed90442, 0x3f031156, 0x3f482df2, 0x3ee1bc50, 0x3f56bb38, 0x3f3cfe7e, 0x3ee127b2, 0x3f20a03e, 0x3e9a35a2, 0x3f780de4, 0x3f407beb, 0x3f5bf3c5, 0x3cc97360, 0x3e855818, 0x3dc7e2e8, 0x3f170ad5, 0x3f64bb17, 0x3f6221fb, 0x3f76cb6d, 0x3ee82c84, 0x3e8893cc, 0x3d434150, 0x3ed38ab8, 0x3eac05dc, 0x3f668dd6, 0x3f49803b, 0x3f68561a, 0x3ca9b8c0, 0x3f4bdfb8, 0x3f0b4755, 0x3ee48e54, 0x3eb4ef00, 0x3dbe76c8, 0x3d0444c0, 0x3d8fea10, 0x3f218222, 0x3f4c3771, 0x3effa3e2, 0x3f512bd2, 0x3e062a1c, 0x3e58cc50, 0x3ea83bc2, 0x3d744060, 0x3d19c180, 0x3ea59b66, 0x3f2e4483, 0x3f148556, 0x3f77eb26, 0x3e256ed4, 0x3df48b50, 0x3f06bb54, 0x3f3529f8, 0x3e14a980, 0x3f57a6f2, 0x3f78465d, 0x3ee75dba, 0x3f346d2f, 0x3f4253ca, 0x3efb970e, 0x3f3f5b7f, 0x3b682000, 0x3ea78bb8, 0x3ea5be72, 0x3d2381b0, 0x3ea07b70, 0x3e97bbb6, 0x3ee4fece, 0x3f7c73e0, 0x3e1f50a4, 0x3f4ceab9, 0x3f7e8915, 0x3f598169, 0x3e6ef65c, 0x3ec93908, 0x3f2b51c7, 0x3f7178f1, 0x3eb384a8, 0x3e7b2f94, 0x3ce514a0, 0x3da97e40, 0x3f4d4ce2, 0x3f323df1, 0x3f2c8b93, 0x3dbe1988, 0x3f15068a, 0x3f6d2592, 0x3f2fb19c, 0x3e9b12b0, 0x3f189359, 0x3eafd3f8, 0x3e906f12, 0x3e350cb4, 0x3ef71540, 0x3d880588, 0x3f7b54af, 0x3ee86f08, 0x3f193941, 0x3f69f1dc, 0x3f0da5f1, 0x3f7e8cae, 0x3f0155a5, 0x3f50c0d3, 0x3ea06680, 0x3ee6018e, 0x3f35bde6, 0x3f0c8ec9, 0x3f48b858, 0x3f34cb33, 0x3f2a8203, 0x3f192248, 0x3f28ca8c, 0x3f1b99ec, 0x3e248d4c, 0x3f2e2321, 0x3f10ea99, 0x3c1ee400, 0x3e811cb0, 0x3f04d7ec, 0x3e0ea6dc, 0x3eb266aa, 0x3b58bd00, 0x3f742656, 0x3f5c446e, 0x3f55f024, 0x3f4242aa, 0x3f635c84, 0x3f519668, 0x3efd1ed4, 0x3eddbbdc, 0x3c0c8200, 0x3f4f860d, 0x3f7a2db3, 0x3f4f22cc, 0x3e7f413c, 0x3e9b018e, 0x3f40b589, 0x3e7cb6b0, 0x3d8db6c8, 0x3df00618, 0x3e129dfc, 0x3eb2c392, 0x3e24078c, 0x3f668a5b, 0x3f732b7d, 0x3f2626e2, 0x3f174914, 0x3f10ffbc, 0x3f76b981, 0x3f2a3556, 0x3f1918f3, 0x3e86c1b6, 0x3ce4c600, 0x3e77149c, 0x3de0d530, 0x3e5dd56c, 0x3f2ca047, 0x3f57ec31, 0x3f5ee5d5, 0x3e0a74b4, 0x3ec78b28, 0x3f3dba83, 0x3f3205b8, 0x3e84e402, 0x3f462657, 0x3f4760a1, 0x3f2a4c2d, 0x3f7f45b9, 0x3f4a967e, 0x3f504b08, 0x3f6ef1e1, 0x3f68745e, 0x3f2a8f59, 0x3ebe6142, 0x3f01f724, 0x3e3b4198, 0x3f71f942, 0x3b47e300, 0x3f2ad0ac, 0x3f636b1d, 0x3ebe1466, 0x3e6c4184, 0x3e5258c0, 0x3f65dc3c, 0x3f052a59, 0x3eb0faaa, 0x3ea7c1be, 0x3f34196b, 0x3ebaadb4, 0x3e531e88, 0x3f2323c5, 0x3cfb8840, 0x3e3760f4, 0x3f22e05f, 0x3f4e688b, 0x3f1e3be7, 0x3e276500, 0x3dd6e130, 0x3ef6257a, 0x3e8b053a, 0x3f51e898, 0x3f7675c2, 0x3ef0dffc, 0x3ea9eb30, 0x3e6095bc, 0x3f5e1e30, 0x3f7d498f, 0x3e3fd274, 0x3f23b067, 0x3f7910d1, 0x3f4c62c2, 0x3f1854bc, 0x3e9636de, 0x3e96bef0, 0x3f66ad3a, 0x3f35ca4d, 0x3e116ee4, 0x3f3d2efc, 0x3f126699, 0x3f24e4a7, 0x3dbe5e30, 0x3f6e5dc9, 0x3f6f4499, 0x3e5065b4, 0x3ef74efe, 0x3e3fbcfc, 0x3e9af28c, 0x3f40dee9, 0x3d6f78c0, 0x3f1ef8cd, 0x3f49b785, 0x3e9c5d2c, 0x3e28c99c, 0x3efc5c32, 0x3f6a96f4, 0x3f1eefce, 0x3e82942c, 0x3da59718, 0x3e776bc8, 0x3e2db094, 0x3f0e7fbd, 0x3f4a7e9c, 0x3f73e136, 0x3f0ef035, 0x3e54c844, 0x3d3ab0e0, 0x3ceaef20, 0x3f761c50, 0x3eb43666, 0x3f4feac0, 0x3ed8ee16, 0x3eaa473a, 0x3f26617d, 0x3f5126e3, 0x3f3f94a2, 0x3f22481a, 0x3f2e4011, 0x3e8ef2de, 0x3e365e14, 0x3f7dd058, 0x3f60949d, 0x3ed27088, 0x3ece364a, 0x3f733387, 0x3dd4d518, 0x3e8fd25a, 0x3a223000, 0x3f7955f5, 0x3f19a65e, 0x3ec22a74, 0x3f06bcde, 0x3db46c30, 0x3f17d92c, 0x3f63e82b, 0x3ec37972, 0x3ee10f36, 0x3eb729e8, 0x3f16a912, 0x3e20ece8, 0x3e6976bc, 0x3c9a7e40, 0x3f17379c, 0x3f1f96b4, 0x3efb6a70, 0x3f3d9f7c, 0x3f493889, 0x3f104771, 0x3f691356, 0x3f653a89, 0x3ed9e542, 0x3f6d9d14, 0x3ec5448c, 0x3f059ac9, 0x3ee5a888, 0x3d29c310, 0x3dc77fe0, 0x3eaea27e, 0x3f29479d, 0x3e244c30, 0x3f431fc3, 0x3f7f4ff3, 0x3ef71410, 0x3e250eb8, 0x3f0de805, 0x3c97f220, 0x3e1ec460, 0x3e641744, 0x3f03c34e, 0x3e7bc584, 0x3f380601, 0x3f1f9a7e, 0x3cc19ce0, 0x3ecd6970, 0x3f4e7492, 0x3f63b24b, 0x3e7b8df0, 0x3eb98e48, 0x3ed8b934, 0x3f52f89d, 0x3f3d69e9, 0x3ed6865c, 0x3e849cac, 0x3f19a2a0, 0x3f3aa4fa, 0x3e951196, 0x3f15a2bb, 0x3e02e578, 0x3e5c0068, 0x3ec80afe, 0x3f502e89, 0x3e7df2f4, 0x3f5a0e27, 0x3f68c46e, 0x3e347d74, 0x3ec0f706, 0x3f2eabbb, 0x3ec41b44, 0x3ee48d30, 0x3f53eaf8, 0x3e919d0a, 0x3e9953f2, 0x3f610369, 0x3f3207eb, 0x3f66f78c, 0x3ee44a16, 0x3f1eb990, 0x3f7aff76, 0x3e52f3d0, 0x3ef4e9f0, 0x3d386090, 0x3f0ebbc6, 0x3f246f9a, 0x3d5ffcc0, 0x3f1cc8b7, 0x3f749b7a, 0x3ef87be0, 0x3f0fb75f, 0x3f18412c, 0x3ec070ea, 0x3f6a7f47, 0x3f3743ab, 0x3e8d5ac2, 0x3f7bb722, 0x3f5f411a, 0x3eba39de, 0x3e431950, 0x3d333210, 0x3f5220ff, 0x3f4a3d29, 0x3f61584e, 0x3ea5e54a, 0x3f58958b, 0x3e0f6de8, 0x3eb87362, 0x3f171095, 0x3f674b58, 0x3f40e5f4, 0x3dc28630, 0x3f0a15fe, 0x3e25d584, 0x3f02daca, 0x3f4faa88, 0x3f71cec7, 0x3f53415c, 0x3ef63138, 0x3ed4d464, 0x3f29385b, 0x3efdfe26, 0x3f6990ee, 0x3f42bb6d, 0x3eb2342c, 0x3f0012d8, 0x3e05c144, 0x3f208fdd, 0x3e836d7a, 0x3f6fd102, 0x3f2a1859, 0x3f56258f, 0x3f4565e6, 0x3e7e2ddc, 0x3e904c0a, 0x3ee4514e, 0x3f35b7db, 0x3f4684ee, 0x3f35c739, 0x3f02253b, 0x3f32d091, 0x3ef1ec72, 0x3e56d044, 0x3d43ca70, 0x3f0ed186, 0x3f09b44b, 0x3f44b512, 0x3e4c63e8, 0x3eccedfe, 0x3e93d28c, 0x3f4a4b8b, 0x3dbac570, 0x3da57090, 0x3f755b9b, 0x3f2dd421, 0x3e83d67a, 0x3ecea17a, 0x3f68c315, 0x3e8beea2, 0x3ef7233e, 0x3f2e6261, 0x3ef28322, 0x3d301700, 0x3ec74384, 0x3e875442, 0x3ebd7746, 0x3ee907e8, 0x3f38df88, 0x3dabbee8, 0x3f61f4bd, 0x3ee71514, 0x3f085c8c, 0x3f405a59, 0x3edac0de, 0x3f78adcd, 0x3f3ccc39, 0x3ea60262, 0x3f428f40, 0x3f2dbdd4, 0x3f7485c1, 0x3eab8edc, 0x3e69e668, 0x3de87048, 0x3e7c4bfc, 0x3cfbaf60, 0x3f0e1a87, 0x3e0a3a4c, 0x3f258435, 0x3ed50534, 0x3dd094b8, 0x3cb680e0, 0x3f46d914, 0x3f7d40f9, 0x3e8f32e0, 0x3ec4d108, 0x3ec1ad0a, 0x3f0448c0, 0x3ec27550, 0x3e16101c, 0x3e81ffd6, 0x3f09d368, 0x3f26a6b7, 0x3f2bd10c, 0x3f4a3448, 0x3f680539, 0x3f28a1c4, 0x3e9e6cb2, 0x3f0ce0c0, 0x3e1303c4, 0x3f323574, 0x3f720290, 0x3f3e9879, 0x3e8880e4, 0x3ebbe646, 0x3e78551c, 0x3f04bc80, 0x3edf7e8c, 0x3e5b8e58, 0x3f7248e5, 0x3f10a57f, 0x3cb5f580, 0x3ef776ee, 0x3f4a88a8, 0x3e7d2548, 0x3eb63a8e, 0x3eeb3014, 0x3f183e57, 0x3f38b629, 0x3f61f7cf, 0x3f60aaa6, 0x3f4c3d61, 0x3f632e9d, 0x3f5cc626, 0x3f121382, 0x3cf217c0, 0x3ea1e382, 0x3e311c44, 0x3e5324fc, 0x3f716802, 0x3e3d3080, 0x3e6df308, 0x3e285a10, 0x3e9105f8, 0x3f7b6fd1, 0x3dbe3dd8, 0x3eb093ac, 0x3f10a60a, 0x3d9ce3e8, 0x3f3415ef, 0x3f013730, 0x3f62d649, 0x3e3025f0, 0x3f282129, 0x3f49fce7, 0x3f1945e7, 0x3f59e7e8, 0x3e99773c, 0x3f1e920a, 0x3e227ea8, 0x3f5c3593, 0x3dfbd380, 0x3f3388d2, 0x3d744be0, 0x3f6007de, 0x3db4cd40, 0x3f7ee35b, 0x3f62f411, 0x3dfdd1d8, 0x3f522532, 0x3e5a0e20, 0x3f7aab9d, 0x3dff2c38, 0x3eba4ecc, 0x3f5bd074, 0x3f6b8e9a, 0x3f2aec15, 0x3e875894, 0x3f0f5970, 0x3effed90, 0x3ea6615e, 0x3ef2dc18, 0x3de973b8, 0x3c495280, 0x3f18e575, 0x3edd24cc, 0x3e279ef4, 0x3eb67724, 0x3f34ba39, 0x3f383a9f, 0x3f0ca9dd, 0x3f61c23a, 0x3f38048a, 0x3f0ffde7, 0x3cff45a0, 0x3e78b944, 0x3f19d762, 0x3f1efc57, 0x3f183493, 0x3f3c0ef1, 0x3e9b7286, 0x3ea6a7f6, 0x3d1c3580, 0x3f3ba3b7, 0x3e7e7b94, 0x3f3b319d, 0x3efd118a, 0x3ea636c6, 0x3c9e6720, 0x3ec85144, 0x3e87b89a, 0x3e7e22e8, 0x3ed49236, 0x3f7627a4, 0x3e95db98, 0x3f7f9ee5, 0x3f6fe8b9, 0x3f0443ee, 0x3f4808da, 0x3f30b5e4, 0x3f0bc545, 0x3f31cfdb, 0x38f86000, 0x3f233ba6, 0x3e99eb18, 0x3f7d6c3d, 0x3f09b22c, 0x3f3f2ec4, 0x3f124e24, 0x3f128af7, 0x3f2a6d40, 0x3ea586a2, 0x3edb681a, 0x3ece5504, 0x3f029603, 0x3f1a9d46, 0x3f383803, 0x3f5cc771, 0x3a27c000, 0x3db04f68, 0x3dce6d18, 0x3f1d2042, 0x3f22fbbd, 0x3dc10ea8, 0x3f4feda6, 0x3f5c7f71, 0x3f37a3c7, 0x3f21ee7c, 0x3c7d6ac0, 0x3f4d839b, 0x3e28c33c, 0x3d603190, 0x3d50af60, 0x3f454931, 0x3e641980, 0x3f053d19, 0x3f1e6400, 0x3bbaa300, 0x3ef85e94, 0x3e7c3734, 0x3ec13450, 0x3efbb828, 0x3f539b80, 0x3f3c920b, 0x3f40db11, 0x3caa9ae0, 0x3f7476a0, 0x3f31270e, 0x3f34d889, 0x3f265668, 0x3f38238e, 0x3f1e0f3f, 0x3f2a804e, 0x3f5a0e18, 0x3f7922fc, 0x3f556142, 0x3f3c373b, 0x3ec56d56, 0x3f2ebf49, 0x3f1a6b43, 0x3f7b678f, 0x3f449ef0, 0x3e28fcf0, 0x3db670a8, 0x3f16c306, 0x3e215480, 0x3d2edb40, 0x3eb5862c, 0x3d7800d0, 0x3defac10, 0x3f49bef3, 0x3b4d4900, 0x3f0326ec, 0x3e93b188, 0x3b953080, 0x3f24829a, 0x3eee36de, 0x3f72a546, 0x3f24f435, 0x3f25ed29, 0x3f644f16, 0x3f601ce4, 0x3e00230c, 0x3f007043, 0x3ecd65fc, 0x3f50572a, 0x3e6333d0, 0x3f6d09ee, 0x3f710c46, 0x3d63f3a0, 0x3e77e610, 0x3f55738f, 0x3ddadde8, 0x3f57d809, 0x3dfcfbb0, 0x3eb99b38, 0x3f7b469c, 0x3f0088bb, 0x3f105d58, 0x3dc54c08, 0x3f7c7ccf, 0x3f311603, 0x3e4cb7c4, 0x3f7ff53c, 0x3eceb33c, 0x3f6a67b8, 0x3f070edd, 0x3ef7f39e, 0x3d19c230, 0x3e107544, 0x3f28a38a, 0x3f7a0343, 0x3f3ab755, 0x3f545ce0, 0x3d30e140, 0x3f351b67, 0x3ebd2506, 0x3f063351, 0x3f038cb3, 0x3ed42b4c, 0x3e693418, 0x3f6da0cd, 0x3f632c9f, 0x3ca3a020, 0x3f367f4a, 0x3f10126c, 0x3f0d7629, 0x3f07fe5f, 0x3cd47e20, 0x3e0dd1c0, 0x3f5738ba, 0x3f77f75c, 0x3f56639f, 0x3f4d4f63, 0x3bee1000, 0x3d6a91e0, 0x3ce679a0, 0x3d653f50, 0x3ef009b2, 0x3f707b7c, 0x3f6e3f8d, 0x3f149e22, 0x3f48d35b, 0x3f0cbaf2, 0x3ddbda80, 0x3de6fb88, 0x3e90e962, 0x3f6943e1, 0x3ea97734, 0x3dbe7628, 0x3f5ef3c4, 0x3f533603, 0x3f1f5e27, 0x3f521baf, 0x3d4c61a0, 0x3e270004, 0x3eed11dc, 0x3f3b55fa, 0x3f2ea580, 0x3e837f60, 0x3dcaf748, 0x3d024910, 0x3ea39b1a, 0x3f4343ad, 0x3f1416ee, 0x3e909014, 0x3f0b7a44, 0x3f3ed8be, 0x3ef86f42, 0x3f403e99, 0x3e3c9860, 0x3f1e44f9, 0x3f639f3b, 0x3ecdc35e, 0x3f37b491, 0x3f4c9133, 0x3f0de154, 0x3e6d3a18, 0x3cdc73a0, 0x3f2e7908, 0x3ee000de, 0x3f28e79c, 0x3e30c8ac, 0x3ee7840a, 0x3f251eb0, 0x3f0e7d49, 0x3f326641, 0x3f470952, 0x3f6bf969, 0x3f25092a, 0x3f33a95c, 0x3f29c1b4, 0x3f358259, 0x3d3e86c0, 0x3f13c2da, 0x3ea2418c, 0x3d20d3d0, 0x3da3bc68, 0x3e2e98bc, 0x3af5be00, 0x3f5c74db, 0x3f2ddc69, 0x3f1c4ebc, 0x3ea536e0, 0x3f731956, 0x3f440397, 0x3f5a6bd7, 0x3edb8d4c, 0x3e825f1e, 0x3eb9e452, 0x3f54d22a, 0x3f7f766e, 0x3f367c5a, 0x3f75ca05, 0x3f13ff6e, 0x3e0c2060, 0x3ef3d12c, 0x3eb39a14, 0x3f2d35c9, 0x3db6a9e0, 0x3e9ea3f2, 0x3f367a3f, 0x3f5277d1, 0x3f62678d, 0x3f482f61, 0x3f6c0a9e, 0x3f68105b, 0x3f48a7c4, 0x3eb94e86, 0x3ee41e9a, 0x3e399568, 0x3f56523b, 0x3d27da80, 0x3ea3688e, 0x3ec94926, 0x3f40360d, 0x3f6095a9, 0x3d560080, 0x3f42e8a0, 0x3e221114, 0x3f357b2e, 0x3eeb2fa6, 0x3ec8f7de, 0x3f1e14bf, 0x3e9fb55a, 0x3e75799c, 0x3e043474, 0x3f3e3f41, 0x3f62ec9f, 0x3edf39a2, 0x3f240071, 0x3d0aa940, 0x3ec205ec, 0x3e90d806, 0x3eeedc50, 0x3f3c2177, 0x3f0cd18e, 0x3e32bd0c, 0x3e2b5510, 0x3db62460, 0x3f3b50df, 0x3f5c8656, 0x3d0cb440, 0x3eb97b82, 0x3eea0ba8, 0x3f445c08, 0x3f5e8508, 0x3e6ce20c, 0x3e8652b2, 0x3f151cc9, 0x3e9ae2da, 0x3e948fe6, 0x3f1851b1, 0x3e5ccc3c, 0x3f0565e0, 0x3e8522b4, 0x3eab573c, 0x3f5f7f0a, 0x3ece5d48, 0x3e0bc998, 0x3f03ed0c, 0x3db93a08, 0x3ec80d58, 0x3f114b7d, 0x3f343551, 0x3f5ce96e, 0x3e7cfab0, 0x3f40a8a8, 0x3f6285cf, 0x3e97a60c, 0x3ae6bc00, 0x3da64fa0, 0x3f492f69, 0x3f665170, 0x3f1f7ba1, 0x3f7b2b34, 0x3ee5bb02, 0x3e413d78, 0x3e854a76, 0x3f061166, 0x3c8bff80, 0x3f7a459f, 0x3ecbe174, 0x3f735006, 0x3e7056a8, 0x3edb975c, 0x3e1d7c10, 0x3e768ddc, 0x3defc8e8, 0x3f41f65d, 0x3f37fbbf, 0x3e8ec32a, 0x3eec0fa6, 0x3f38ed2b, 0x3ef3e1ea, 0x3f57dc16, 0x3ee48668, 0x3f29bd4c, 0x3f2a4ba5, 0x3f24b7df, 0x3f1dc4d0, 0x3f6e480a, 0x3f27fd8d, 0x3f0a3846, 0x3f4fa834, 0x3e458a54, 0x3c651500, 0x3d8294e0, 0x3f4f79b4, 0x3e8af340, 0x3f750540, 0x3f10410d, 0x3f68d688, 0x3ec04f0e, 0x3e9b4964, 0x3f57d1aa, 0x3e269844, 0x3d7dd470, 0x3f487e77, 0x3eea6ab6, 0x3f246078, 0x3f4b6754, 0x3f78f291, 0x3f09c52d, 0x3f7e4924, 0x3f7665f0, 0x3f6613b2, 0x3f5e8ecc, 0x3f55f7f1, 0x3d8810e0, 0x3e91f6ba, 0x3eb7a8a6, 0x3f145771, 0x3f584d56, 0x3dd12d38, 0x3f6d7552, 0x3e151aec, 0x3eeedc04, 0x3f6f1fc5, 0x3e503050, 0x3db59340, 0x3f403f9d, 0x3f4e20eb, 0x3f489973, 0x3f3799d7, 0x3f75306d, 0x3de0a890, 0x3f65653d, 0x3f78506c, 0x3f42ad47, 0x3f5dfae5, 0x3efaef42, 0x3f027d85, 0x3f18d19a, 0x3e55943c, 0x3e31d730, 0x3f63ae74, 0x3d23fa00, 0x3ec87ec4, 0x3e930264, 0x3e53a034, 0x3d868598, 0x3f4cfbde, 0x3f512309, 0x3c3be0c0, 0x3f41660f, 0x3eed1d32, 0x3e9f5226, 0x3f22bddc, 0x3e36b2ec, 0x3eb74a74, 0x3f385fae, 0x3f6cd6fe, 0x3f28d8f3, 0x3f4034b6, 0x3e87c4c8, 0x3f502e00, 0x3f463b41, 0x3ed869ca, 0x3f79ce5e, 0x3f4e5bd5, 0x3f18efff, 0x3eedb4ee, 0x3ed8c8da, 0x3cacda00, 0x3f39b71e, 0x3f08a753, 0x3f5adc83, 0x3dced118, 0x3f7f76b3, 0x3e961664, 0x3f4a107e, 0x3f15cb58, 0x3f1482e9, 0x3e2fa464, 0x3e396c64, 0x3e5afe2c, 0x3f27651b, 0x3e9dd2f2, 0x3d9471f8, 0x3f2fc954, 0x3d5d6120, 0x3f60812e, 0x3ebeee1e, 0x3ef74d5e, 0x3e2360f8, 0x3f280e5d, 0x3f223bf5, 0x3e098208, 0x3ed5c05e, 0x3f419257, 0x3f2f7988, 0x3e90e382, 0x3f73aa27, 0x3f5f8ca1, 0x3f6baa17, 0x3eebf75a, 0x3eb9d238, 0x3db97c70, 0x3f13beb0, 0x3f2fd1dc, 0x3f1b43ba, 0x3eadb87c, 0x3f22f4f3, 0x3f365e2c, 0x3eb67e5a, 0x3ee924b4, 0x3f19935e, 0x3f1fa90a, 0x3f6f9c0d, 0x3e6e8b98, 0x3d969cb0, 0x3ebfbd52, 0x3f4ae7d3, 0x3ef7b4bc, 0x3e32575c, 0x3d7e1040, 0x3f55f21b, 0x3f46b501, 0x3f5c4488, 0x3f0ad460, 0x3d8bba38, 0x3f755ec6, 0x3c0772c0, 0x3e5e1668, 0x3f24868d, 0x3ec90faa, 0x3eaa22fc, 0x3f337691, 0x3e967858, 0x3e9d1b90, 0x3ee62a4c, 0x3efd76d0, 0x3eec2bfe, 0x3ed491ba, 0x3f470aa6, 0x3f70f153, 0x3e8ec54c, 0x3ec2486c, 0x3ea9d4e6, 0x3f12c9bd, 0x3e5e73c4, 0x3e9d0336, 0x3e48e408, 0x3f6ba35e, 0x3f7ce98c, 0x3f67f738, 0x3e30e000, 0x3f0cfef9, 0x3e800654, 0x3e24da18, 0x3e4dde08, 0x3d63f810, 0x3e7dda24, 0x3f67f663, 0x3f682c33, 0x3df33cc8, 0x3f4a26e4, 0x3ecd1220, 0x3f3d2216, 0x3ddce4b0, 0x3f65e844, 0x3ece340a, 0x3f31a06d, 0x3ea55984, 0x3e92de8a, 0x3f152ad9, 0x3e714c98, 0x3f0982b7, 0x3f75ba4d, 0x3c6a9380, 0x3ec5acfa, 0x3f038cd8, 0x3f6bfac5, 0x3f542edf, 0x3c99a2e0, 0x3f6c8d6a, 0x3ec26f2e, 0x3e7785b0, 0x3ebddc76, 0x3f236c2f, 0x3f5d7b7e, 0x3ce05620, 0x3f457b46, 0x3f675754, 0x3ebf4f7e, 0x3efbcbdc, 0x3eae71ce, 0x3e990030, 0x3f706f56, 0x3f5827a4, 0x3f28a1b5, 0x3cdc3360, 0x3ea5c976, 0x3f40fb45, 0x3f07fbd7, 0x3eef39ea, 0x3dbfa1f0, 0x3e871ab2, 0x3f0444f9, 0x3f73d779, 0x3f008f41, 0x3ee47730, 0x3e5115b8, 0x3f2159a1, 0x3f56c876, 0x3ebc632a, 0x3ee5cf6e, 0x3f4fba1e, 0x3eda8ce4, 0x3eae05b6, 0x3f41a8c9, 0x3f6a0608, 0x3f3cf8b7, 0x3eab4d18, 0x3eaf8b42, 0x3e467e40, 0x3e57039c, 0x3efac590, 0x3f5c5b9a, 0x3f487734, 0x3f40a058, 0x3f204690, 0x3f1e977e, 0x3d1b5210, 0x3f1e529f, 0x3e2a73dc, 0x3ec374d8, 0x3f5b594f, 0x3ef58e9e, 0x3d0b0450, 0x3f4f1793, 0x3db6d750, 0x3d9766e0, 0x3f0fbede, 0x3f2a200b, 0x3e890cc0, 0x3eaf877a, 0x3f557638, 0x3d8476a8, 0x3f5fdda2, 0x3effd012, 0x3efe6fea, 0x3ef36232, 0x3f5750dc, 0x3f7b98fd, 0x3f6e69bb, 0x3ec07e7c, 0x3f67d100, 0x3dab3f40, 0x3de3f790, 0x3f39b8ac, 0x3f032c45, 0x3f3b3a41, 0x3e92a656, 0x3f37ab47, 0x3ec76088, 0x3b168e00, 0x3f7ffc48, 0x3f6d40da, 0x3ed852e6, 0x3e78782c, 0x3f365fc1, 0x3db7e790, 0x3f2a4690, 0x3f44258b, 0x3f578106, 0x3ed8b2f6, 0x3f446045, 0x3e3ca5d0, 0x3f2a38e6, 0x3eabb6be, 0x3ec0e31c, 0x3c312e40, 0x3f4c44ac, 0x3f73eac4, 0x3f2e6733, 0x3f01bf30, 0x3f3774a5, 0x3f0af237, 0x3f59b555, 0x3f45a569, 0x3d17de70, 0x3f185d3a, 0x3eea4ab8, 0x3f284b11, 0x3e8ad5f4, 0x3f29c851, 0x3f34265c, 0x3e56612c, 0x3e9c3ba0, 0x3f4d67b6, 0x3f1b4671, 0x3f4876cf, 0x3f6b7e85, 0x3f6c9081, 0x3e3444d4, 0x3ec7a8d0, 0x3f6df398, 0x3f15ae99, 0x3f17e000, 0x3f439479, 0x3f7da41d, 0x3f062d00, 0x3db7a440, 0x3f5b43bf, 0x3f07b2d3, 0x3f3777c8, 0x3e6cffd0, 0x3f78570b, 0x3f5306f8, 0x3dc78520, 0x3ed4442e, 0x3f768b99, 0x3f0d2fd2, 0x3f019e24, 0x3f2061ec, 0x3f64958c, 0x3ddbafe0, 0x3ede4ff0, 0x3f2c735d, 0x3f5c2ae3, 0x3f05987a, 0x3f3a8226, 0x3f103c9e, 0x3f60991e, 0x3f17be78, 0x3f7d64cd, 0x3f7ecd70, 0x3f2a7cbb, 0x3f3392f4, 0x3ee1fb42, 0x3eeb50f4, 0x3f6ceafc, 0x3e95aaf4, 0x3f51d9dd, 0x3f30d26e, 0x3f672cec, 0x3ece85ca, 0x3f3a1108, 0x3eb9833c, 0x3ecdfc3c, 0x3f744326, 0x3e4c115c, 0x3e944106, 0x3f51c13f, 0x3e038480, 0x3e8662c4, 0x3e4daaa0, 0x3c34c500, 0x3f2c3bea, 0x3f74d7e6, 0x3f6bc555, 0x3eba5ba6, 0x3f70b2e2, 0x3f421331, 0x3eb55894, 0x3ee6db14, 0x3e09bf0c, 0x3dffdf50, 0x3ec6aca2, 0x3f2c1388, 0x3f2fb529, 0x3f66b2d9, 0x3f7278b9, 0x3f00df53, 0x3eb554fe, 0x3cd22800, 0x3f41eda7, 0x3e96add2, 0x3e073dd4, 0x3f41d61f, 0x3e7d0e3c, 0x3f3797a2, 0x3f2d6060, 0x3eaee812, 0x3f495f54, 0x3f17d3e9, 0x3e29a128, 0x3ec94d3c, 0x3e878340, 0x3f397a76, 0x3e802aa2, 0x3ef726c8, 0x3f1b7d12, 0x3f341766, 0x3e1ff270, 0x3e4b8150, 0x3f707c7e, 0x3f306ce9, 0x3ec96bd0, 0x3f743dd4, 0x3eba121c, 0x3e9de208, 0x3e293244, 0x3d3474b0, 0x3f17851b, 0x3f6750a5, 0x3f28eddf, 0x3f06e1bb, 0x3e34752c, 0x3e2f601c, 0x3c5a4cc0, 0x3f049716, 0x3f0dcb62, 0x3f0a8c27, 0x3eb62324, 0x3d822228, 0x3ead06f8, 0x3f3f0a3d, 0x3f7d1f3e, 0x3f067ad0, 0x3dc8bbc8, 0x3f7f414d, 0x3f41c1aa, 0x3d1592a0, 0x3f56773d, 0x3eddb3a4, 0x3f79aaa3, 0x3d3a7be0, 0x3e838bcc, 0x3f097530, 0x3e883aca, 0x3f28beee, 0x3f2f533a, 0x3f3ccde2, 0x3f7642ce, 0x3f296fd6, 0x3f5bf4e3, 0x3f7baace, 0x3e69e954, 0x3f5c01ae, 0x3e2c1cbc, 0x3f417069, 0x3e5c1d0c, 0x3eaa39ae, 0x3df9cf68, 0x3eb76c40, 0x3e593544, 0x3f2e3814, 0x3ea9971a, 0x3f466aee, 0x3eab6256, 0x3ed7a840, 0x3f5520fc, 0x3f55d7ab, 0x3f5edf92, 0x3f1f5934, 0x3f1339bf, 0x3f69261c, 0x3f6e3d77, 0x3f08ed87, 0x3e07a544, 0x3f50f963, 0x3e8cbac4, 0x3dbb0060, 0x3f38aca9, 0x3f29aac1, 0x3eb8da7a, 0x3f68687b, 0x3f4a6173, 0x3aa8ba00, 0x3f4410ec, 0x3c191e00, 0x3db66910, 0x3ee78460, 0x3e8250c2, 0x3eda77e6, 0x3e150e0c, 0x3e85435a, 0x3f3b6662, 0x3ecaca3c, 0x3f2623c9, 0x3edf3894, 0x3f182df0, 0x3f3a721e, 0x3f5bb953, 0x3e9b0806, 0x3f5c289b, 0x3e9737d4, 0x3ee818ea, 0x3f2c3e8c, 0x3f7085f2, 0x3eb91014, 0x3e14ff5c, 0x3f09fc37, 0x3e878f32, 0x3f36a5c5, 0x3ea6c388, 0x3e933240, 0x3de07df8, 0x3f441b49, 0x3f1b30d8, 0x3f33b738, 0x3e05692c, 0x3ec0c92a, 0x3cb27d20, 0x3f447bf3, 0x3f33eb6c, 0x3d9ec4a8, 0x3f438b95, 0x3f4acfa9, 0x3f181633, 0x3f254931, 0x3e1dcf7c, 0x3f2a58c5, 0x3e34e20c, 0x3f266b7a, 0x3f647e3b, 0x3f5a65fb, 0x3ee099ae, 0x3eb35820, 0x3eaab0e2, 0x3e8738dc, 0x3e395a90, 0x3e88a826, 0x3f2187fd, 0x3ed68c56, 0x3db58110, 0x3f486561, 0x3edd8560, 0x3f088cd6, 0x3f7be94f, 0x3eebcafc, 0x3f63d8d3, 0x3f0b7a92, 0x3f5020e1, 0x3f2ae997, 0x3dc740a8, 0x3f6c0217, 0x3ee646b4, 0x3f0510e1, 0x3f63518b, 0x3f292a1e, 0x3f70fc3c, 0x3f72a4a8, 0x3f1106c8, 0x3f316cb3, 0x3f4630ed, 0x3ea42778, 0x3ee7383a, 0x3f3f7ffe, 0x3f0779e9, 0x3e613330, 0x3f28fe48, 0x3f67f1b4, 0x3f1c7a16, 0x3e9c3b4a, 0x3f124dce, 0x3ee4e97e, 0x3f1636eb, 0x3df17868, 0x3d8c80c0, 0x3f25f56f, 0x3e8fd746, 0x3f61a234, 0x3f0965ee, 0x3e868be4, 0x3d768430, 0x3f2c07b0, 0x3f7d6acc, 0x3f52edc2, 0x3f6fbf5d, 0x3ca6e3e0, 0x3e79da24, 0x3f620b27, 0x3d3edd10, 0x3f482759, 0x3f0491a1, 0x3f0f50ba, 0x3eed244c, 0x3f0a1668, 0x3ede80d4, 0x3edc13d4, 0x3f31beaf, 0x3de467e0, 0x3f185740, 0x3ceb64c0, 0x3e55df5c, 0x3f0ce9de, 0x3eed511c, 0x3f5b1690, 0x3f72794f, 0x3f336dab, 0x3e238744, 0x3f5316b3, 0x3f655fde, 0x3e292c48, 0x3ed5a3d8, 0x3dd0dfd0, 0x3f44c4e0, 0x3f16495c, 0x3b92b700, 0x3f21bf81, 0x3f583be9, 0x3f109eb0, 0x3f5df0b1, 0x3f467ca9, 0x3eae953e, 0x3f71a80f, 0x3da50470, 0x3f47aa45, 0x3ec203d4, 0x3f726be5, 0x3ea4fdee, 0x3da21d58, 0x3f294699, 0x3d8ae288, 0x3ed194aa, 0x3f47ab15, 0x3f247150, 0x3ed1772c, 0x3f544a52, 0x3cd05740, 0x3f315a73, 0x3e1e1b2c, 0x3f32bb5f, 0x3f0f36c4, 0x3d7816a0, 0x3f4cd169, 0x3e9cd702, 0x3ecafbe6, 0x3d3fda60, 0x3f6f5538, 0x3e866d56, 0x3e31c90c, 0x3ef28564, 0x3f382084, 0x3f01b0c1, 0x3f5a0649, 0x3f7d7fad, 0x3e6503c0, 0x3f6d0c17, 0x3f4b17fc, 0x3f764541, 0x3f41fcd5, 0x3f05afb0, 0x3e51a34c, 0x3f2a0c40, 0x3f5cb1e6, 0x3ed4cbda, 0x3f10db2b, 0x3ed5ed12, 0x3eb950a4, 0x3f7d710e, 0x3e72b1ec, 0x3c2da780, 0x3d1e3950, 0x3f651ef4, 0x3f3e816b, 0x3ef423b6, 0x3e98b0d8, 0x3d36b290, 0x3ead6a7e, 0x3f6f7e1b, 0x3f4012b1, 0x3ea35be8, 0x3f4544ce, 0x3f1377ff, 0x3f721bb8, 0x3f2cf517, 0x3dfd3388, 0x3f7094cd, 0x3f1bf9b5, 0x3eaebfe8, 0x3f0a8a99, 0x3dd93808, 0x3f0a5181, 0x3e3e3494, 0x3e77e78c, 0x3e2ae294, 0x3ec64f1e, 0x3f7a17b6, 0x3db13438, 0x3f3bba34, 0x3df86fc0, 0x3f67f92a, 0x3ea7af42, 0x3d41f930, 0x3d9a9040, 0x3f6c3d62, 0x3ef11d6e, 0x3e5eb804, 0x3f3dcc72, 0x3b6d7a00, 0x3ebe9c3e, 0x3e5e8b30, 0x3f6cc3e7, 0x3e0ecaf8, 0x3f5085d8, 0x3f136306, 0x3eea04f8, 0x3ecc6b04, 0x3e9aa354, 0x3f56f005, 0x3ee9a98a, 0x3eb50038, 0x3f3fdd0e, 0x3f739072, 0x3edc6df0, 0x3f61328e, 0x3f257d3e, 0x3d0ec5c0, 0x3f3790ce, 0x3eeb52c2, 0x3f306a5f, 0x3f2bd889, 0x3f5e42c6, 0x3f637ddd, 0x3f1fed94, 0x3d7b5f70, 0x3da97158, 0x3f7fd7d5, 0x3f55b2b7, 0x3f0f845f, 0x3f61a892, 0x3e641338, 0x3e986a90, 0x3f033e43, 0x3f42648d, 0x3e6d3d40, 0x3ee2adde, 0x3cef7220, 0x3f1226fb, 0x3f60081e, 0x3f5767db, 0x3f2cd931, 0x3ee94946, 0x3ece2fd2, 0x3e8b272c, 0x3e505a5c, 0x3f2e950c, 0x3f5d3165, 0x3f7bb32c, 0x3f46cd2c, 0x3f641a27, 0x3dbe0a88, 0x3f231482, 0x3ee4dcde, 0x3f08c3e8, 0x3eddcd8e, 0x3edbbf50, 0x3f0e508a, 0x3c029500, 0x3f5e7667, 0x3f572967, 0x3ed03836, 0x3f364022, 0x3e2b88bc, 0x3ecdb87c, 0x3f4f4864, 0x3e806d3e, 0x3f0a7597, 0x3ed0a246, 0x3ef8c7fa, 0x3eb39dec, 0x3f15bcab, 0x3f521cc1, 0x3eeb58c6, 0x3ee273e8, 0x3ee64b6e, 0x3f1cb300, 0x3e70507c, 0x3f4c7ada, 0x3ed285de, 0x3f74d3e4, 0x3f13b2b0, 0x3eb69026, 0x3df0a208, 0x3f64acf9, 0x3eaee482, 0x3dd0ada0, 0x3ec1330c, 0x3d33aa30, 0x3efc51f4, 0x3e506660, 0x3f0fcc47, 0x3e1bc37c, 0x3eedba8c, 0x3f6b1b56, 0x3ebbb730, 0x3cbca4c0, 0x3ef07072, 0x3ea0d5fc, 0x3d3c8150, 0x3e910c26, 0x3d4b8220, 0x3f16b029, 0x3edb4bee, 0x3f1856bb, 0x3e941346, 0x3cce5f20, 0x3d0297d0, 0x3edf75be, 0x3ebf3696, 0x3eb4db48, 0x3f3ac8eb, 0x3e958cf6, 0x3e3b0190, 0x3f7924b8, 0x3f2158b9, 0x3f283a31, 0x3f6f451b, 0x3f1ad181, 0x3f02752a, 0x3eaa7496, 0x3e9e61ce, 0x3e89e424, 0x3f706390, 0x3ea8fc3c, 0x3e8c4196, 0x3e8fd3e0, 0x3ef14214, 0x3f2f7db5, 0x3f183726, 0x3a17dc00, 0x3da3a6d8, 0x3f13fa3b, 0x3ed8d010, 0x3d09d8d0, 0x3ece6948, 0x3f2a96ed, 0x3ed3d1e2, 0x3dcdf918, 0x3f5a2b0e, 0x3f04d936, 0x3f61fd07, 0x3f3157e3, 0x3e8f2bbe, 0x3db68a58, 0x3f35a7dd, 0x3f43e0f6, 0x3f05c40e, 0x3f7727bc, 0x3ec23d50, 0x3f526af1, 0x3f35a25f, 0x3f1640bf, 0x3efb444a, 0x3bbe6600, 0x3f4d6d00, 0x3f1d3e2f, 0x3efe6e34, 0x3e8f4d72, 0x3f04a7c4, 0x3ecf7ee6, 0x3f4a3ac3, 0x3f1935b1, 0x3e3b9ccc, 0x3ea0885e, 0x3e42c47c, 0x3e9e71e6, 0x3f537d42, 0x3ed8f5e2, 0x3f0891a9, 0x3f1bdf8b, 0x3eb4e490, 0x3ea74d7e, 0x3f7fb442, 0x3f476d72, 0x3ddb9e80, 0x3e1eabac, 0x3d491a30, 0x3f02c419, 0x3f08d52d, 0x3e9f71de, 0x3f02cc29, 0x3de4c790, 0x3ee8028e, 0x3f775731, 0x3e6fc344, 0x3f26d772, 0x3f7d9af7, 0x3efcafaa, 0x3c8e0ae0, 0x3ee53c22, 0x3ee54618, 0x3f2ab56d, 0x3edb31fa, 0x3d963600, 0x3f13813a, 0x3f6d9550, 0x3f1473f4, 0x3f20891d, 0x3f7a432d, 0x3f1cab7e, 0x3eff8f70, 0x3f11b90f, 0x3ea4aace, 0x3e224f90, 0x3e41257c, 0x3e2da9e8, 0x3f2d4e43, 0x3e754fd8, 0x3f6609e9, 0x3d173320, 0x3f64929a, 0x3f46b6a9, 0x3e408dac, 0x3ee75e32, 0x3f433d57, 0x3e85f0f2, 0x3f300ef5, 0x3f4aaa91, 0x3efe4ba2, 0x3f41e04f, 0x3e0ca418, 0x3d95dc50, 0x3e9078ca, 0x3f675c91, 0x3eb8a6d0, 0x3f4baf39, 0x3f0c2056, 0x3d889150, 0x3bd57f80, 0x3e3a3bf4, 0x3e4e4df0, 0x3eab0ffe, 0x3f0c133c, 0x3ea79c34, 0x3e8cd78a, 0x3f05f9a1, 0x3f63d135, 0x3ee0af50, 0x3f27b67f, 0x3ee4e7f8, 0x3f3c424d, 0x3f76cc28, 0x3bdfcd80, 0x3da7c8d8, 0x3e2aa0cc, 0x3f12e4cb, 0x3f7b9b09, 0x3ec001c6, 0x3f5a9924, 0x3e39f428, 0x3f7dea38, 0x3e77cae4, 0x3dc868a8, 0x3f2db1a3, 0x3ec09fc8, 0x3ebc5a10, 0x3ea7699c, 0x3e3691a4, 0x3e8ce004, 0x3f456d22, 0x3e617344, 0x3f4c46f1, 0x3f302bad, 0x3ebc5b8e, 0x3f2d88ef, 0x3f046b5b, 0x3c6da840, 0x3f07e6d8, 0x3e815280, 0x3f4aab7d, 0x3ec04340, 0x3ea633c6, 0x3cd27500, 0x3f43a1fe, 0x3f2b887c, 0x3f432174, 0x3d973220, 0x3f216c73, 0x3ea7b2da, 0x3da974a0, 0x3ea73f28, 0x3f7726e0, 0x3ea9e0f8, 0x3f22ee20, 0x3f5295a8, 0x3f1a30ec, 0x3e713490, 0x3f3b1cdb, 0x3f28c7a8, 0x3de7f4c0, 0x3f1962d3, 0x3dc47678, 0x3d580600, 0x3f5ba907, 0x3c5ec180, 0x3ea29cf6, 0x3e0a047c, 0x3eb521bc, 0x3f2d12e4, 0x3f0211b7, 0x3ea0e182, 0x3da1c048, 0x3f6bf772, 0x3f687cb3, 0x3f118e12, 0x3e447350, 0x3f4b3135, 0x3d9e52d8, 0x3f68de56, 0x3f055759, 0x3f2783b2, 0x3f276191, 0x3f3cfd76, 0x3f5e2fad, 0x3f353203, 0x3e00a790, 0x3e66de8c, 0x3f6f604a, 0x3e9292ce, 0x3f59fb9a, 0x3f7d4d6c, 0x3bf91c00, 0x3f1b3f19, 0x3ea647b8, 0x3f771c34, 0x3e231834, 0x3f554200, 0x3eb29dfc, 0x3e974ebc, 0x3ef8058c, 0x3f14963e, 0x3c889480, 0x3f122b20, 0x3e9b9d12, 0x3f2399df, 0x3d616380, 0x3f3d3cea, 0x3dc06950, 0x3f587785, 0x3d12b6e0, 0x3f7781fe, 0x3f62c99c, 0x3ee9ee7e, 0x3f3cbefc, 0x3e5c43a0, 0x3f460b5f, 0x3da5f5d8, 0x3dc047f8, 0x3e9ebaee, 0x3f6aa518, 0x3eded60e, 0x3f0290a3, 0x3f3117fd, 0x3e8dcd20, 0x3f6eeccc, 0x3ed9a660, 0x3e752314, 0x3ed8b392, 0x3e35c83c, 0x3f01303d, 0x3d0433a0, 0x3ea7ca66, 0x3ed2f11e, 0x3f62dd89, 0x3f2736d8, 0x3e85ce88, 0x3f2cddad, 0x3dc79ee0, 0x3dd59368, 0x3cd7e200, 0x3ec8262c, 0x3f0088c5, 0x3e8f9eac, 0x3ef69be0, 0x3f5703d8, 0x3f28dc67, 0x3f343f42, 0x3e694760, 0x3eaf07d0, 0x3f4701f8, 0x3e9addd4, 0x3f5ecb0d, 0x3e01e05c, 0x3f7c0eac, 0x3f61b64c, 0x3f3dbde3, 0x3f276e4b, 0x3f1b9fe1, 0x3f5a00a1, 0x3e56a4d8, 0x3d355100, 0x3e97513e, 0x3f7563c0, 0x3f44a370, 0x3f484d75, 0x3f14a3f0, 0x3edd9a86, 0x3e97c540, 0x3f2b38fa, 0x3ea52450, 0x3e1ffda8, 0x3cb4f400, 0x3ea919ac, 0x3f16e4ac, 0x3f06c521, 0x3cef2c20, 0x3e16a5d0, 0x3f121e6e, 0x3f5dd2ff, 0x3f3e0a5a, 0x3f7f21a2, 0x3f77966f, 0x3f45f1c8, 0x3f54eecc, 0x3df838c0, 0x3f68cc88, 0x3bad1000, 0x3b71b500, 0x3ddc5348, 0x3e3f66dc, 0x3ecdd10a, 0x3f1b1411, 0x3f768d3e, 0x3e9790d6, 0x3f31fdaf, 0x3ecd4b82, 0x3e99dda8, 0x3f4fe66f, 0x3d883970, 0x3f73ffad, 0x3e817a76, 0x3ef645de, 0x3f5f42fd, 0x3f685a96, 0x3f7ee0b8, 0x3e857726, 0x3d54d6d0, 0x3ef6b218, 0x3f64870a, 0x3efa433a, 0x3f0a2d42, 0x3ecd5ef4, 0x3f27b5b8, 0x3f18d599, 0x3f02a468, 0x3ec6ae00, 0x3e45c4e0, 0x3e796a30, 0x3e94739e, 0x3f675640, 0x3f3364bc, 0x3f4c8dee, 0x3ea8903e, 0x3f1a1c09, 0x3e2e204c, 0x3eb4b28a, 0x3f7fe159, 0x3f0cca06, 0x3e791940, 0x3ea3d052, 0x3f26184e, 0x3f2a704c, 0x3d9060d0, 0x3f7a80cf, 0x3f4cc0c6, 0x3f2fc910, 0x3f3b2d26, 0x3db69cf0, 0x3f026699, 0x3f454095, 0x3f6df60a, 0x3f7cd023, 0x3f677425, 0x3e504aa0, 0x3f74c4de, 0x3f1d1252, 0x3f4d6716, 0x3dfeca28, 0x3f7d2b23, 0x3e0efe44, 0x3ebd1232, 0x3d23bc30, 0x3f5d98b6, 0x3f53cbe5, 0x3f2c4d0b, 0x3f1d8d9c, 0x3e04e914, 0x3f4eac75, 0x3f7b688e, 0x3ebf9742, 0x3eb606cc, 0x3f15e1f4, 0x3f715d1b, 0x3ea678e6, 0x3d730a30, 0x3adc4600, 0x3ed41538, 0x3f7d191c, 0x3f7944c0, 0x3ed2342e, 0x3f35d0b4, 0x3f37a5c5, 0x3f60a0e3, 0x3f2d200b, 0x3f4b7f21, 0x3f39493a, 0x3f0a7a43, 0x3e298768, 0x3de3f950, 0x3ee894ba, 0x3f603702, 0x3f23688b, 0x3f4d266a, 0x3f4b505d, 0x3f5bf4df, 0x3e99ec82, 0x3eea0b92, 0x3eba586c, 0x3f241f30, 0x3ed36a62, 0x3f3b0ead, 0x3f0c6c68, 0x3e1ca338, 0x3ef19a80, 0x3f0391b3, 0x3e4ae480, 0x3f312cd1, 0x3e882b00, 0x3d6cdbd0, 0x3df20720, 0x3f552ce6, 0x3d8457d8, 0x3f279a29, 0x3f14306c, 0x3f352f27, 0x3e948830, 0x3e9876d4, 0x3f1b89ae, 0x3dadca70, 0x3ec64564, 0x3eb84b2e, 0x3ebfbf88, 0x3df3d1d0, 0x3c94a980, 0x3f332e28, 0x3e358be8, 0x3f7d27eb, 0x3f00cc29, 0x3e110758, 0x3f4659a3, 0x3ef088e4, 0x3f07299b, 0x3f0e49b4, 0x3ebf8244, 0x3f5bdcad, 0x3f30ee6b, 0x3f01aba3, 0x3f3168b8, 0x3f5304c5, 0x3f46c8c2, 0x3f02b22d, 0x3d9b1968, 0x3e89197c, 0x3ed0d7f8, 0x3f084022, 0x3ef2b110, 0x3dbf97b0, 0x3f42eb04, 0x3f5c85a5, 0x3f02584f, 0x3ec52bbe, 0x3e3eee8c, 0x3f2c42e5, 0x3dd8dbd8, 0x3ed53dbe, 0x3b89b580, 0x3e9d8f04, 0x3f231fea, 0x3ef7aef2, 0x3f0cfdea, 0x3f010a37, 0x3ea89d68, 0x3d95ab20, 0x3eaba508, 0x3e504740, 0x3eb6260a, 0x3d955910, 0x3b191000, 0x3c63b380, 0x3f5b70c3, 0x3f702761, 0x3f5597a9, 0x3f624aee, 0x3f7f215a, 0x3ecb9636, 0x3ef8b348, 0x3f4a5694, 0x3d9e2ac8, 0x3d1d91f0, 0x3f6d324d, 0x3d8694d8, 0x3f6ed642, 0x3f6c61fe, 0x3eaf6eb2, 0x3f4f39d3, 0x3d8870c8, 0x39c60000, 0x3f6eeb8c, 0x3ed64f4e, 0x3ea5316c, 0x3f381d93, 0x3dec5f48, 0x3f3fcd55, 0x3f7e3b3f, 0x3e437988, 0x3ee9f06a, 0x3f137d39, 0x3d9b9cb8, 0x3e8f6fd4, 0x3f0db959, 0x3d9dc550, 0x3f0cf803, 0x3c824ca0, 0x3f49b93c, 0x3f0024f8, 0x3f61567c, 0x3f0ef5bd, 0x3e3fb8b0, 0x3e89f82e, 0x3f1acbc7, 0x3ebe55ca, 0x3efcee30, 0x3e192cd8, 0x3f116e1b, 0x3eef0498, 0x3d1bd930, 0x3dfcf888, 0x3f29be21, 0x3f4c5b60, 0x3f05cd59, 0x3e04c3b8, 0x3eb0b3cc, 0x3eb1c690, 0x3e884f5e, 0x3d3f6610, 0x3e7c24b0, 0x3ead28a0, 0x3f602641, 0x3e373220, 0x3dd1cd80, 0x3e1397c4, 0x3f1e61b1, 0x3ec616c2, 0x3efd70d6, 0x3f17132d, 0x3dee0960, 0x3f129730, 0x3f5e06a9, 0x3eb00f6e, 0x3d459be0, 0x3f783b0d, 0x3cc6fc60, 0x3f1f52b1, 0x3f41e3d2, 0x3f590e1e, 0x3f2c68a8, 0x3ec32c28, 0x3ec5a670, 0x3ede47be, 0x3f2943ca, 0x3f75085b, 0x3f7f4144, 0x3f123e70, 0x3d8f9718, 0x3ecab2aa, 0x3e8f3f76, 0x3e8d5bf0, 0x3f74b88f, 0x3f490d95, 0x3f637989, 0x3e7c7200, 0x3e0d5968, 0x3f4218e6, 0x3f0b3015, 0x3f37ed57, 0x3da88578, 0x3eb5f42c, 0x3f4c8054, 0x3f080983, 0x3eb9a226, 0x3f0af081, 0x3f61c384, 0x3f109a3f, 0x3f13bee0, 0x3f5db356, 0x3f0d5e9c, 0x3ea82f4c, 0x3f1bcd4b, 0x3d51b510, 0x3f09f00c, 0x3d82ec08, 0x3f5e6ee1, 0x3ecde5dc, 0x3e0f95a0, 0x3ed39f80, 0x3f413551, 0x3e812c1c, 0x3f37428a, 0x3edcc670, 0x3f6d241a, 0x3ed78a4a, 0x3e8a14ba, 0x3eccb736, 0x3daea0c0, 0x3f7fca4b, 0x3f2a8309, 0x3f02ce7c, 0x3b694900, 0x3f7aee80, 0x3f437099, 0x3f121298, 0x3eeb6eb2, 0x3f5f222d, 0x3e207f14, 0x3f654eeb, 0x3f5354b5, 0x3f53c7f7, 0x3f65607b, 0x3da58fb0, 0x3d020c20, 0x3ebab812, 0x3d99f038, 0x3f48fb5d, 0x3da33a48, 0x3f2c382f, 0x3f4faac1, 0x3e44648c, 0x3e17d650, 0x3f69759f, 0x3f5c2d9c, 0x3f2f7408, 0x3f4deeb8, 0x3e80369c, 0x3f578763, 0x3f161695, 0x3ee9a0b2, 0x3f2387f6, 0x3e8ab8c6, 0x3f0fbe20, 0x3f43d4d7, 0x3f0236dc, 0x3f03aeed, 0x3eb6a360, 0x3ec6ae26, 0x3f1cf6ba, 0x3d8155f0, 0x3eb5f598, 0x3f2ec944, 0x3f4a5829, 0x3eca81ce, 0x3e7cfa68, 0x3f2349be, 0x3f51cedc, 0x3e97243c, 0x3e15ae84, 0x3e97e128, 0x3f24110c, 0x3f4d4bce, 0x3f5f5de8, 0x3efc9c5e, 0x3e98d9ee, 0x3e20c9fc, 0x3ee26668, 0x3f19ec8f, 0x3f637941, 0x3f5c45a1, 0x3ef920aa, 0x3f284d25, 0x3f5f43b9, 0x3f444684, 0x3d65a5f0, 0x3f330075, 0x3eda58ca, 0x3ea54fec, 0x3e9e695a, 0x3f29556b, 0x3f0917b6, 0x3f3dde5d, 0x3bb33000, 0x3e32842c, 0x3e607d38, 0x3f24c664, 0x3e474a28, 0x3f6d56dd, 0x3f44add0, 0x3f17fe92, 0x3f13ac13, 0x3f4a9cde, 0x3e2eab70, 0x3e357750, 0x3f4ba011, 0x3e9934ee, 0x3f069a5d, 0x3ea8c8c0, 0x3d824180, 0x3ed1326a, 0x3d65a1a0, 0x3f194f22, 0x3f4847f3, 0x3f00b367, 0x3e9e3ed4, 0x3f6f9af8, 0x3f003f05, 0x3ef6506c, 0x3f7cf576, 0x3e98e6f6, 0x3e9a530c, 0x3ec3ac60, 0x3ca49e20, 0x3f43598f, 0x3eda0dd6, 0x3f770751, 0x3f6db49f, 0x3f002df0, 0x3f551e6c, 0x3ec5fa6c, 0x3e91dc8a, 0x3f3c2046, 0x3f0c31bb, 0x3eded452, 0x3d0fc900, 0x3f140fe7, 0x3f0272ac, 0x3f6cf8ef, 0x3f752bed, 0x3f71371d, 0x3f3e06fe, 0x3ec62fd6, 0x3da0cfd0, 0x3f2770a1, 0x3e4ec10c, 0x3f359ed9, 0x3f4a0f07, 0x3f52ab68, 0x3f5a19cb, 0x3ed9b99a, 0x3e243410, 0x3f5aabd3, 0x3f5da3d4, 0x3f04112d, 0x3f0c9229, 0x3f1190d6, 0x3f5d2301, 0x3d577600, 0x3f031693, 0x3f5bb257, 0x3e8fb77c, 0x3f035d2b, 0x3e592930, 0x3e982898, 0x3ebe9a04, 0x3f5fae2f, 0x3f0c312b, 0x3e05dc00, 0x3f18bbf3, 0x3dfa7188, 0x3f10b13c, 0x3f2799d5, 0x3e736dec, 0x3eaac872, 0x3f794288, 0x3f1c02af, 0x3edc8d40, 0x3eeb2854, 0x3ed88fc8, 0x3f60f296, 0x3f17ef3f, 0x3e9c10ea, 0x3cebcc60, 0x3f3b4496, 0x3e38213c, 0x3f1914ee, 0x3e145484, 0x3f251a26, 0x3f1e3292, 0x3e522ba0, 0x3f22835e, 0x3f22030e, 0x3e484284, 0x3f42a72c, 0x3e5380cc, 0x3f5a0420, 0x3f3e0d80, 0x3f0c6364, 0x3e6575dc, 0x3ebc5ca2, 0x3f5ebe2f, 0x3f6327c9, 0x3eb0dd20, 0x3f1b9df8, 0x3e24c074, 0x3f0f117f, 0x3e87cef2, 0x3f10ad68, 0x3f44e1f6, 0x3e1b9914, 0x3f44a79d, 0x3e069a74, 0x3ece147a, 0x3ee649b8, 0x3f5ac8a1, 0x3ecfca14, 0x3f128ed6, 0x3ee27a88, 0x3de5bc88, 0x3f1fae3b, 0x3d4c0ad0, 0x3ec8a086, 0x3ee8ee7e, 0x3f14b396, 0x3f75e742, 0x3f70ad2f, 0x3e34e8ac, 0x3ea88008, 0x3f23a599, 0x3f5b54ce, 0x3f4a42b6, 0x3f1e336d, 0x3f0bb247, 0x3e3c62d0, 0x3f4ad45d, 0x3f33b8a4, 0x3f701309, 0x3e7cba70, 0x3e6e9144, 0x3ee55078, 0x3f0b4a38, 0x3f2208b1, 0x3f4ab2aa, 0x3ec93514, 0x3f54cda5, 0x3ef9e268, 0x3f5318c3, 0x3f4271d0, 0x3e446518, 0x3c0cc540, 0x3f6ffca9, 0x3eac477e, 0x3edd9ad4, 0x3f64204f, 0x3f790415, 0x3ef92596, 0x3e605498, 0x3ec16dbc, 0x3f31715b, 0x3f0c059f, 0x3edd9362, 0x3d34d790, 0x3f0fb023, 0x3eb1630a, 0x3f1b5d28, 0x3f7b4b91, 0x3f75c52d, 0x3f1cd993, 0x3f083531, 0x3ed72c16, 0x3f011af4, 0x3e47e100, 0x3f11ed07, 0x3f105f4f, 0x3f6b70d1, 0x3dce81e0, 0x3f5d206c, 0x3f2b5a0f, 0x3f510dd5, 0x3f773089, 0x3dcc1078, 0x3f68548d, 0x3f7b910d, 0x3f0069c2, 0x3e9a6492, 0x3eb39030, 0x3f2c1836, 0x3e6e8a30, 0x3f67045a, 0x3f5ebf5d, 0x3f32486f, 0x3ef29262, 0x3e13a8a8, 0x3f42ab87, 0x3ebf0958, 0x3cbb6ce0, 0x3efe75b2, 0x3eff1664, 0x3d968ac8, 0x3d755380, 0x3eace430, 0x3f3e1fad, 0x3dcebc90, 0x3ea1f368, 0x3f71ad48, 0x3ef44b0a, 0x3f695d62, 0x3d8f45d0, 0x3f6325f6, 0x3ea517a6, 0x3f4b12ad, 0x3ee85e72, 0x3e8bb160, 0x3eb37644, 0x3e6946f0, 0x3e963a1c, 0x3bc5d680, 0x3d991c50, 0x3f0dba99, 0x3ead6efc, 0x3e2cbb1c, 0x3e93f2c8, 0x3f4c888f, 0x3f06a59e, 0x3e5d6af0, 0x3eaa509a, 0x3f66abce, 0x3f0eb11f, 0x3e106ef8, 0x3e01d60c, 0x3ebd6b4a, 0x3e83a364, 0x3d291040, 0x3f3147c6, 0x3f6c54ef, 0x3f2d46e2, 0x3ea063ee, 0x3dbd23d8, 0x3f2c3471, 0x3f198565, 0x3f14cc7a, 0x3f50197a, 0x3f4fe81f, 0x3d7f2de0, 0x3f6817dc, 0x3f66531d, 0x3eae3468, 0x3ed86a7a, 0x3e8ffc1e, 0x3ecbc786, 0x3ed739a6, 0x3edfb1c8, 0x3f0bed6b, 0x3f153681, 0x3e90d1ac, 0x3f688961, 0x3cdd5920, 0x3f2553a5, 0x3ed1ddc8, 0x3e7fbcac, 0x3f3641e1, 0x3ebb566c, 0x3dc216d8, 0x3db053e0, 0x3eff6246, 0x3f2e5590, 0x3ef1d916, 0x3e2611d0, 0x3ef35528, 0x3f5048ad, 0x3e206988, 0x3ce4f4e0, 0x3f0c57e6, 0x3eb6e9c6, 0x3ed75f84, 0x3f69ffdc, 0x3f3f286c, 0x3f7f7f91, 0x3e011f98, 0x3db3a9d8, 0x3f58e30d, 0x3f310050, 0x3e1d9ce0, 0x3ef19468, 0x3e8f5922, 0x3ef21cf8, 0x3f6651bd, 0x3e3668e8, 0x3f08cb81, 0x3f1a8bee, 0x3f40511c, 0x3f692993, 0x3e435dd8, 0x3ef67a0a, 0x3e0cefd8, 0x3f6c71b4, 0x3f3acd2b, 0x3c410100, 0x3ebc59c0, 0x3da99290, 0x3e6a7b8c, 0x3dafd3d0, 0x3d2a67f0, 0x3f450ccb, 0x3ddb5478, 0x3d39eb10, 0x3f0eafb7, 0x3e754dc0, 0x3e1c7c50, 0x3f5ee4b2, 0x3f1c7e7a, 0x3f60c0d1, 0x3f0b805c, 0x3f16f607, 0x3f25316c, 0x3f5c4ba5, 0x3f5dcab2, 0x3f3b84a1, 0x3d3da1b0, 0x3a912400, 0x3ddbe120, 0x3e504938, 0x3ea8786a, 0x3f60c1da, 0x3f22c4fd, 0x3f1d1d95, 0x3e711420, 0x3f0ef8af, 0x3f043f45, 0x3f5293d7, 0x3f291b7f, 0x3eea3d2c, 0x3e5e64bc, 0x3f4825cc, 0x3eec1d98, 0x3ed758d4, 0x3e89a952, 0x3cfde3c0, 0x3df27828, 0x3d927b30, 0x3d87e550, 0x3f3b4132, 0x3f0eacf2, 0x3ec04a88, 0x3e82f43c, 0x3f6252aa, 0x3f7cc3a5, 0x3e865bf2, 0x3e710808, 0x3e094d7c, 0x3f59cebc, 0x3eed3662, 0x3f1b9e85, 0x3dbe8080, 0x3d8b4470, 0x3f0c5d83, 0x3d23fb30, 0x3d7561c0, 0x3f781334, 0x3ed7dcaa, 0x3ed4da30, 0x3f5e52b1, 0x3f54d0af, 0x3ebe54a8, 0x3d85b380, 0x3e5194b4, 0x3f5493d8, 0x3f79d6f0, 0x3d887998, 0x3f03ace0, 0x3eb52c78, 0x3f7751ac, 0x3f04adea, 0x3d050890, 0x3ebaf404, 0x3e97a6d6, 0x3ebc7e76, 0x3dbf44a8, 0x3e158ffc, 0x3f2da489, 0x3eaa71a8, 0x3e980f0c, 0x3f2a1f1e, 0x3f7779af, 0x3f639c13, 0x3debd510, 0x3f513358, 0x3ee5acf8, 0x3ebf290e, 0x3ed4b634, 0x3ed78f0a, 0x3f2d7ee6, 0x3dc26f60, 0x3f2c05ce, 0x3e597350, 0x3f172c2e, 0x3d738630, 0x3f4674f7, 0x3e80a71a, 0x3f3a06f0, 0x3f68d353, 0x3f6f7572, 0x3f2a407b, 0x3cc1ebc0, 0x3bf95f00, 0x3c373940, 0x3f647d22, 0x3e898bd6, 0x3db94918, 0x3e0e7130, 0x3eb4baa6, 0x3eef9370, 0x3f7f4a1a, 0x3ea125b4, 0x3f5307a1, 0x3d539b00, 0x3f32ee21, 0x3f1fa938, 0x3f4cf527, 0x3f34f504, 0x3f19c8da, 0x3ee7ff62, 0x3f791b26, 0x3f674aad, 0x3f5433cb, 0x3ebf244c, 0x3f2564cc, 0x3f2ee888, 0x3f6ee3dc, 0x3f402302, 0x3e2db948, 0x3f10354d, 0x3d77e9a0, 0x3e086dfc, 0x3ebbe8a0, 0x3f5717f8, 0x3f098e91, 0x3f50a649, 0x3f21cf6e, 0x3eef57ee, 0x3e6f544c, 0x3f25f7b4, 0x3eafbafe, 0x3f062946, 0x3ee87e1e, 0x3ea6e1dc, 0x3f1c66a4, 0x3ee6fe92, 0x3ee91d80, 0x3f572123, 0x3ec88b50, 0x3f742018, 0x3f54e90f, 0x3e65086c, 0x3f0a6c6e, 0x3e8fd818, 0x3f244c65, 0x3d2a4a40, 0x3f72aaa5, 0x3e95a6de, 0x3f1ebabd, 0x3f340a85, 0x3d4c40f0, 0x3e63d1dc, 0x3f579876, 0x3f29635d, 0x3e5158d8, 0x3f0c63df, 0x3e11fe8c, 0x3efd9a12, 0x3efb66cc, 0x3eca6a44, 0x3ed66508, 0x3dec61c0, 0x3d35f550, 0x3de20030, 0x3db20850, 0x3f75d785, 0x3e89cfa0, 0x3ee36e38, 0x3ea5cf3a, 0x3f628708, 0x3e4a2ba4, 0x3e3ef4e0, 0x3ebe1fd4, 0x3f3204d2, 0x3f388c96, 0x3d266f80, 0x3f4e05f6, 0x3f570918, 0x3e3650e0, 0x3e44cef8, 0x3f461eba, 0x3ead68a2, 0x3d984998, 0x3f51f8aa, 0x3e748b64, 0x3f6ca2d9, 0x3f20e07b, 0x3e94f292, 0x3e08ffe8, 0x3f548a2d, 0x3e1a4b84, 0x3e60af70, 0x3e9aff5a, 0x3efda772, 0x3e3a124c, 0x3f645cca, 0x3e188670, 0x3f45c4e3, 0x3f0502e6, 0x3e865ef4, 0x3ebb3d6a, 0x3e5807b4, 0x3eef22f4, 0x3f0e776c, 0x3f325003, 0x3f5be481, 0x3f3bada9, 0x3f49fa0c, 0x3d996b70, 0x3e56903c, 0x3e8d8cb2, 0x3d8e7520, 0x3f58b77a, 0x3ba20200, 0x3cbe9c40, 0x3f60815f, 0x3cc5e9e0, 0x3e71f000, 0x3f62a7ea, 0x3e6d3bd8, 0x3f59cb91, 0x3ec5af5e, 0x3ecc41b2, 0x3e8ad474, 0x3f3b6b09, 0x3ed75dc2, 0x3e0f521c, 0x3ed84246, 0x3e9a1586, 0x3cb52520, 0x3f1d0fcd, 0x3f6bd064, 0x3f599cab, 0x3eb66bf6, 0x3f535c3a, 0x3b856700, 0x3ebca092, 0x3ecc6d48, 0x3f08dcc0, 0x3b897f00, 0x3f2ae8ed, 0x3f2d2a36, 0x3e464a74, 0x3dcb02e8, 0x3eda8a62, 0x3f4b9edc, 0x3f125394, 0x3f788ddb, 0x3e7b4104, 0x3d5c6a60, 0x3f6309c8, 0x3e8c04be, 0x3f3667b9, 0x3ed8dc34, 0x3ef846f6, 0x3f02654a, 0x3de06ea0, 0x3f4cb88b, 0x3d6d4bc0, 0x3e9cad44, 0x3f6ed175, 0x3f098e2a, 0x3f3d5201, 0x3f3ce099, 0x3e733bb0, 0x3f37f4c5, 0x3ea4e26e, 0x3f1f2323, 0x3f556ee5, 0x3f455e12, 0x3dba88b8, 0x3f4b6c7e, 0x3ed9a0a6, 0x3eb84ec4, 0x3f6619fc, 0x3f2dae60, 0x3ec23506, 0x3d520070, 0x3ef910c0, 0x3f2ab23a, 0x3d07a9b0, 0x3f29343c, 0x3e169d5c, 0x3e85c5e4, 0x3e8ccb44, 0x3f0d6acc, 0x3f0610ab, 0x3da08f18, 0x3ef4f6c2, 0x3f6c30d2, 0x3e864474, 0x3ebcc42a, 0x3edf7a74, 0x3ef1a0b4, 0x3e8aaf86, 0x3f38f8f8, 0x3f245c9e, 0x3f418e46, 0x3e041c3c, 0x3e960e66, 0x3f277689, 0x3d12b8f0, 0x3e127ed4, 0x3e0e877c, 0x3f576bb4, 0x3f60cb7a, 0x3d9b4cf0, 0x3f02649d, 0x3ef08648, 0x3e76ea30, 0x3ed2ec12, 0x3f3181de, 0x3e73a63c, 0x3df88ff8, 0x3ec23b34, 0x3f1fa52a, 0x3f569318, 0x3f033044, 0x3f589280, 0x3de7e730, 0x3f1c62a8, 0x3eb6dd84, 0x3e6c4f20, 0x3d413ab0, 0x3f5b45cf, 0x3e80d9a0, 0x3edf4900, 0x3ef9cf66, 0x3e8e76d8, 0x3d2590e0, 0x3f0dcfa7, 0x3f7f0b3d, 0x3e73b644, 0x3ea4492e, 0x3f302059, 0x3da70828, 0x3e8a3234, 0x3e58c8c8, 0x3eb2b674, 0x3f48fb98, 0x3f105af2, 0x3f598be0, 0x3d7be3d0, 0x3f57fb03, 0x3ec08bbe, 0x3f788d7f, 0x3f495be3, 0x3f501880, 0x3f594dd8, 0x3d3d6b10, 0x3f367bd7, 0x3f6d9f4a, 0x3f369aae, 0x3d698ae0, 0x3f027daf, 0x3eee638a, 0x3f1d3820, 0x3f2134f1, 0x3f6675db, 0x3d8e8820, 0x3ed46a7a, 0x3f73c1e5, 0x3eb09022, 0x3e3b7b2c, 0x3e069588, 0x3f6a933d, 0x3ee4b4b4, 0x3ec684b4, 0x3f6451c7, 0x3ea6806c, 0x3f1cec2d, 0x3f339f15, 0x3ec154e4, 0x3ea7c544, 0x3f0b5d07, 0x3e8b78d0, 0x3f5f1241, 0x3e3d5bec, 0x3f44d002, 0x3e8ed2c2, 0x3f45e176, 0x3ece9b6a, 0x3e8bff6c, 0x3ee269a8, 0x3e379324, 0x3e0df360, 0x3e9ea76a, 0x3e806788, 0x3e401320, 0x3f4eea32, 0x3eefd2f2, 0x3f2911b5, 0x3d9bb480, 0x3f4c48e2, 0x3f7df2cf, 0x3f43a17f, 0x3f534ea2, 0x3e0ac4a8, 0x3c91cfe0, 0x3cd24a20, 0x3da674c0, 0x3ef5e8de, 0x3ec76640, 0x3e3a5a88, 0x3eaaa6d4, 0x3f059644, 0x3e0c21f4, 0x3e9584ce, 0x3f4419cc, 0x3f6f30ca, 0x3f4ee81e, 0x3f5c7c9a, 0x3d9d93a8, 0x3ea9e01c, 0x3f204655, 0x3f5f3f42, 0x3f507d1e, 0x3dd3d140, 0x3f1fac08, 0x3eb3896e, 0x3d98b210, 0x3e744904, 0x3f2701f6, 0x3ed3260e, 0x3f1f0b91, 0x3e423b14, 0x3f0ec2bc, 0x3f02b3c0, 0x3f2433a2, 0x3f462c82, 0x3d7a6790, 0x3e2dd630, 0x3eeac03a, 0x3ebb3756, 0x3e280664, 0x3ea68fea, 0x3f4e6127, 0x3f5a9e70, 0x3e359020, 0x3f6171f9, 0x3eb47ea4, 0x3e86c8c4, 0x3f24b254, 0x3f153db9, 0x3e8848a8, 0x3d5150b0, 0x3f0f86c9, 0x3f442c61, 0x3f2b5c06, 0x3f2a0203, 0x3f6ae7f9, 0x3d4ff760, 0x3d825e90, 0x3e1d82ac, 0x3c2d3900, 0x3e0bec74, 0x3f4b4ae0, 0x3f3ea747, 0x3d38e940, 0x3f7fb9d4, 0x3d2f52e0, 0x3f17bb21, 0x3f784439, 0x3f0619a3, 0x3df725c8, 0x3f72d11d, 0x3db65e90, 0x3f720730, 0x3f783c9c, 0x3eb51d22, 0x3f27b0cc, 0x3f05baec, 0x3e96f534, 0x3f461b79, 0x3f1e7da3, 0x3f418f68, 0x3edf861e, 0x3f14a742, 0x3d644f00, 0x3ef4cd4a, 0x3eaeb200, 0x3f3491c8, 0x3ed2cdaa, 0x3e7b3738, 0x3f40d64f, 0x3e8a2624, 0x3f3d2bb5, 0x3e23b094, 0x3f4fa2aa, 0x3f1dd2f1, 0x3edd400e, 0x3f7b44c9, 0x3e70bbb8, 0x3f492120, 0x3e298a98, 0x3dfa5b98, 0x3e9b0b02, 0x3e92b148, 0x3f6494f3, 0x3f4a54c1, 0x3e435654, 0x3ebd4994, 0x3f6f391c, 0x3eb764e0, 0x3f728eca, 0x3edbccd2, 0x3ec57116, 0x3f6654cc, 0x3f10e510, 0x3f062043, 0x3f693583, 0x3d8a1020, 0x3f4edcf2, 0x3f2559da, 0x3f10889d, 0x3eb765e0, 0x3f55386e, 0x3f35beee, 0x3f148d45, 0x3f5cbf2e, 0x3e607d30, 0x3ef5e90a, 0x3e9d6a82, 0x3f4c40d1, 0x3d8ce2a8, 0x3f5477a7, 0x3eb4a2c2, 0x3ec3bf78, 0x3e994b32, 0x3b59dc00, 0x3f5a9476, 0x3f7a4370, 0x3d9fc408, 0x3e5048fc, 0x3ea3ab18, 0x3d191bb0, 0x3e56a758, 0x3f206535, 0x3e4637c8, 0x3f0140c8, 0x3d54a3c0, 0x3ee116be, 0x3f63e06b, 0x3e08bfd8, 0x3f7f2a9d, 0x3f34bac9, 0x3f78b84a, 0x3d7c0d10, 0x3f2ed9da, 0x3d4240e0, 0x3e3212b8, 0x3c426440, 0x3e738ae4, 0x3e802148, 0x3f218f91, 0x3f4f649e, 0x3f46325e, 0x3f2cb56a, 0x3efd33e0, 0x3f63e5c0, 0x3f6a03c8, 0x3f67f7c3, 0x3f57f7d1, 0x3f128f66, 0x3eb8db2c, 0x3f1768ed, 0x3f2f1311, 0x3f7e06ce, 0x3f539971, 0x3e36d1bc, 0x3f21276d, 0x3f4c7853, 0x3be14a80, 0x3e241fa8, 0x3f68cd85, 0x3f5dadd7, 0x3da7f6e8, 0x3f1e2519, 0x3f32df33, 0x3f74f0f1, 0x3f6dd595, 0x3f539f6c, 0x3f043a4a, 0x3f7d281d, 0x3f7c2902, 0x3ea4c72a, 0x3f44af85, 0x3f28cbf4, 0x3f6afd3b, 0x3f34f8ff, 0x3e95bc74, 0x3f2167a4, 0x3ef247ee, 0x3e99cb86, 0x3ea68870, 0x3f25b107, 0x3f5dbbef, 0x3f58b045, 0x3ebe5cb0, 0x3f1e7667, 0x3f186432, 0x3f60e65a, 0x3f679bba, 0x3de9cd40, 0x3cb8fd20, 0x3f3b2e03, 0x3f35b46f, }; // 4,6,6,7 uint32_t kernel_vals[] = { 0x3c843120, 0x3d9cb687, 0x3d5b919e, 0xbd96186c, 0x3d58fa3a, 0x3d2d416a, 0xbd0d67ab, 0x3d843683, 0x3d71186a, 0xba010e00, 0xbd9f03ba, 0x3d06df00, 0xbc1a3998, 0x3d79f232, 0x3daa7307, 0x3d925f53, 0xbb375d80, 0x3d134948, 0xbd1e015e, 0x3d34a30a, 0x3d18cc42, 0xbd3504c0, 0x3cf0d59c, 0x3b31aa80, 0x3d82c6a5, 0xbd98537c, 0x3cd30210, 0xbd32858e, 0x3d962b29, 0xbd041de8, 0x3d5905ca, 0xbd9318dc, 0xbc822da4, 0xbd99ca93, 0xbca3e600, 0x3d8da64d, 0xbd764cd8, 0x3c444220, 0xbd7b8ddb, 0x3d32a706, 0x3c441368, 0xbd3e4fd3, 0xbc691d58, 0xbd96f41f, 0x3da60aeb, 0xbd4b25de, 0xbd95ae4c, 0x3d577b42, 0x3d946765, 0x3d5dfee2, 0xbd1e98c3, 0x3d08d7f8, 0x3cda02c0, 0x3d3aa8ca, 0x3d621622, 0x3cdba8cc, 0xbd0418ee, 0x3d98a03d, 0x3d872eed, 0xbd827dc6, 0xbc851910, 0xba82bcc0, 0xbda376c0, 0x3d9e0c99, 0xbd82fce2, 0x3a965840, 0xbcb0ab80, 0xbc87e814, 0x3b674180, 0x3d722b1a, 0xbd8ff94b, 0xbd24e630, 0x3da4799d, 0x3d207270, 0xbcb18006, 0x3cc6e480, 0x3d07dcb2, 0xbd27e0b8, 0x3ce3646c, 0x3cfd7400, 0x3b931450, 0x3c9d81c0, 0x3d827fff, 0xbcb4a356, 0x3d90e22b, 0xbd5dc973, 0xbd93ad6e, 0x3d86e28b, 0xbcfe8596, 0x3a359380, 0x3c8cefc0, 0x3d1e98e8, 0x3d92a301, 0xbce5a52c, 0xbc7dc138, 0xbd70686e, 0x3d67f49a, 0x3c5fb808, 0x3d6cfd3a, 0xbd762403, 0x3d91afd3, 0xbcac63d6, 0xbca5e2f0, 0x3da11785, 0xbc47cad8, 0x3d686e6a, 0xbd9d768b, 0xbbd3e1c0, 0x3d29cdf8, 0x3c8e1a50, 0xbbdf52c0, 0x3d84ca75, 0x3d558672, 0x3cb35b44, 0x3d3ae79a, 0xbba14450, 0x3c4f23e8, 0xbd92a8e0, 0xbc7e1008, 0x3d0aef56, 0xbd1ee9c0, 0x3c1ef9e8, 0xbd816bee, 0x3d5d5a0e, 0x3cf05d90, 0x3d945d4b, 0xbd7c9058, 0xbd84b6db, 0xbd22a31b, 0x3cab977c, 0x3d937d2f, 0xbc86fb94, 0xbd9aefe6, 0x3d965a17, 0xbc85e5cc, 0xbd8383cf, 0x3d3ed7da, 0xbd93875c, 0x3ca917f0, 0x3d27d858, 0xbca242f0, 0xbdaa27de, 0xbd41e7de, 0x3cd140cc, 0x3da4c293, 0xbd9d1c4f, 0xbd8573b4, 0xbd12fe33, 0xbd4da3e8, 0xbd9c6e88, 0xbc53e6e8, 0xbd3007c6, 0xbda06ec6, 0xbbe3b240, 0x3cc78960, 0xbb067e00, 0xbc596918, 0xbbda3d70, 0x3d00ebbe, 0x3d104f7a, 0xbc8a715c, 0x3bb9fa70, 0xbd9b2ed4, 0xbd29cdb6, 0xbb7bdc20, 0xbda18690, 0x3d8aa6f3, 0xbd8896d6, 0x3af500c0, 0x3da33325, 0x3d688536, 0xbcf6ccb6, 0xbd7d58b0, 0x3cfffc2c, 0xbc37caf8, 0xbd80b8fa, 0xbcfc3a1c, 0xbd60d596, 0x3d316982, 0xbc6309a8, 0xbd838248, 0xbce41de6, 0xbd779b3b, 0xbd853a67, 0x3d999799, 0x3d863273, 0xbc750968, 0xbd2b6248, 0xbbebcf40, 0xbca76e64, 0x3d714b62, 0x3bed9700, 0xbd86f7ae, 0x3d2196fa, 0xbb24a280, 0x3ceb63fc, 0xbd0a6a16, 0xbd256e18, 0xbd8f2f32, 0xbd2632de, 0xbd6850db, 0xbd02f30b, 0x3d4e678e, 0xbc3a5be8, 0x3da842a5, 0xbd004ba0, 0xbc3ad7c0, 0xbbfebf80, 0xbce8a4d6, 0xbd07428e, 0xbc3f40e8, 0x3ca5ae7c, 0x3ceca810, 0xbd2a1138, 0xbd9a6d3c, 0xbd7f63d0, 0x3c99953c, 0xbd90eb57, 0x3d2dc97e, 0xbd69bda6, 0x3d8f2d3b, 0xbc447de8, 0x3d6e7a9a, 0x3c0de408, 0x3c6a67e0, 0xbcb53cac, 0xbcb237ac, 0xbc6d7660, 0xbd99aa56, 0x3ce2c874, 0x3d9807fb, 0x3ccfee9c, 0xbd55f0f3, 0x3d9c9a4d, 0xbcae07e6, 0x3d2915ba, 0xbcda6406, 0x3c906df0, 0xbcc83906, 0xbd36f4d6, 0x3d923683, 0x3d8667cf, 0x3da75c75, 0xbc8bf5a0, 0x3d98efe1, 0x3cdf5530, 0x3d1c689a, 0x3d6335f6, 0xbd842942, 0xbda390a0, 0x3d52fe0e, 0xbcd93720, 0x3b76c480, 0xbd769e0e, 0xbd5e580b, 0xbc9c6a80, 0x3d52ce0e, 0x3da14773, 0x3cb84a70, 0xbd2e62a3, 0xbc04cf60, 0xbd89c570, 0x3bc6d770, 0xbd031beb, 0xbd2739c3, 0x3da4af81, 0xbc8278cc, 0xbb758b60, 0x3c92de7c, 0xbd3cfcd0, 0xbcd8cdc6, 0x3d514702, 0x3d77b8a6, 0x3d007242, 0xbd089b6b, 0x3cdfe96c, 0x3d019e30, 0xbc45f238, 0xba8bdc40, 0x3d15f902, 0x3c68bd00, 0x3ce60520, 0xbd35ca38, 0x3c5ca7c0, 0x3d6f2aea, 0x3d908d8d, 0x3d108622, 0x3d808301, 0xbccbab96, 0xbd9517e8, 0xbd1a1a9e, 0xbd8656ab, 0xbc53a0e0, 0x3d9c6e5d, 0xbcc3dbac, 0xbd946d5c, 0x3d7fea56, 0xbc807d7c, 0x3cf08e5c, 0x3c29b0e8, 0x3d90cc99, 0x3c8a5c84, 0xbd676793, 0x3c5a74e8, 0x3bd0f9d0, 0x3cb3ad1c, 0x3d918bc7, 0xbd13a94e, 0x3d8deccd, 0x3cbc253c, 0x3d98008b, 0xbd183573, 0x3cfa6ed0, 0xbd0c2a7b, 0xbcf67e00, 0xbd20b236, 0xbd0a6de3, 0xbd9db21e, 0x3d88543b, 0xbcdb5996, 0xbd51acd8, 0x3d64ed4e, 0x3c90d3d4, 0x3d287db2, 0x3c4da880, 0xbbbddfc0, 0xbd4532e3, 0x3d9fc6c5, 0x3cca5754, 0x3cd4b7d4, 0x3c59de38, 0xbcebf0fc, 0x3d15333a, 0x3cf11144, 0xbbc5d4d0, 0x3ba666d0, 0x3d878075, 0x3d7cfa7a, 0xbd2e5538, 0x3d9d7023, 0x3c15b2a8, 0xbd9ea2e4, 0x3b2f2d20, 0x3d96e0c7, 0x3c12a888, 0xbbf2f780, 0x3a1e5180, 0xbd82f792, 0xbd5499b8, 0x3d0988e6, 0x3bbd3c40, 0x3ca2d0f4, 0xbd214ade, 0xba48f600, 0x3d1398b2, 0x3d088956, 0xbd396bc8, 0x3d0a9f36, 0x3d7298e6, 0x3c7ee2c0, 0xbd8b436e, 0x3d2533b0, 0x3d00c956, 0x3cc59610, 0x3d90e525, 0x3da28ad9, 0xbd9a6c17, 0xbb412ce0, 0x3d212ece, 0xbcab2ff6, 0x3d2d7bc6, 0x3c140260, 0xbcf299ec, 0xbd9c39df, 0xbcc3b556, 0xbca145c0, 0x3c91e144, 0x3d68b302, 0xbb8eba80, 0x3d9cbb9f, 0x3da20deb, 0xbd4f8996, 0x3d8817e5, 0xbd451a30, 0xbc2489b8, 0x3d615c9e, 0xbd1eeff0, 0xbd997632, 0x3d6bd0ca, 0x3da5d6ad, 0xbbbc2c40, 0x3d8f81dd, 0xbc95bc60, 0x3c8441fc, 0x3d1f521e, 0xbd3a9aae, 0xbd64f95b, 0xbd3c07ae, 0xbd8ba57b, 0x3c5915e8, 0x3d0441f6, 0xbc5d2880, 0xbd46130b, 0x3b99d490, 0xbd535633, 0xbce4b076, 0x3da31483, 0xbd100a10, 0x3d529016, 0x3d776636, 0x3c7266a8, 0xbd447ce6, 0x3c39d588, 0x3d8a88c1, 0xbd6102e0, 0xbd4c0f96, 0xbd96a177, 0x3d63fb9a, 0x3da48ae1, 0xbc077de0, 0x3d0d0a12, 0xbd4e8c08, 0xbd8836e0, 0x3c4003f8, 0x3b867570, 0x3d249868, 0x3d7159fa, 0x3cd562cc, 0xbd770406, 0x3d311d2a, 0x3d80deab, 0xbc89604c, 0xbd03fa18, 0xbc3ed040, 0xbd879210, 0xbd853ca2, 0xbc3a2820, 0x3ca8a814, 0xbd707186, 0xbd4ebae0, 0xbd285338, 0x3d44252a, 0x3d43a6ea, 0x3cc93b7c, 0x3d31e60a, 0xbd83f6fc, 0xbcdc9816, 0x3b56cd60, 0x3b9d9870, 0xbd498360, 0x3c890e2c, 0x3da91cb9, 0x3d3b95aa, 0x3d3a85da, 0xbd99b3e4, 0x3be1f540, 0xbd9dae9b, 0x3c377bb8, 0x3d8ad909, 0x3d7ea3ba, 0x39b0fb00, 0xbc559880, 0x3d12fd0e, 0x3caeb8b0, 0x3d30ec4a, 0x3cc17f34, 0x3da66999, 0x3c9d8bd4, 0xbc49a868, 0xbc7262c8, 0xbd575d66, 0x3d53849a, 0x3d20d3aa, 0xbd3eaa60, 0xbd3ae560, 0x3d8c6e43, 0x3d5f4c2a, 0x3da44397, 0xbd4126fb, 0x3d1a521e, 0xbcc23d56, 0x3d3aa852, 0x3ce978bc, 0xbd3873de, 0xbc7f1120, 0xbd9cbb92, 0xbd2e5fc3, 0x3d44b92e, 0xbd1cecc6, 0x3c1dae28, 0x3da088e3, 0xbd572ea8, 0x3da278a1, 0xbd427378, 0xbafe5a00, 0xbd1732bb, 0xbda94f20, 0x3c960d6c, 0x3d5e8046, 0xbc9b8540, 0xbcd4d6bc, 0x39561200, 0xbc11d0e0, 0x3d41fe0e, 0x3d9b803d, 0xbca97a70, 0xbb9b3cb0, 0xbd294f7b, 0xbd628373, 0x3d289706, 0x3cdbf240, 0xbd41cdce, 0x3cecef54, 0x3d90fa4d, 0xbc888134, 0xbc5a2918, 0xbce128e6, 0xbcb35750, 0x3d63d15a, 0x3d930435, 0xbba63e90, 0x3da11179, 0x3bae9d40, 0xbba646f0, 0xbd4a1e16, 0xbd5c64bb, 0xbd49d440, 0x3c643d48, 0x3b8e4b70, 0x3da8028d, 0xbd2bd5cb, 0xbd8d052a, 0xbd49def0, 0xbd673928, 0x3d25a522, 0xbd975f9f, 0x3ce6f274, 0xbd2083b3, 0xbd9ef9ef, 0x3da66731, 0xbd9d9aa8, 0x3ce37d8c, 0x3c248e08, 0xbccab67c, 0xbd0598d8, 0xbd03547e, 0x3cf5786c, 0x3d4a7152, 0xbd93b99f, 0xbbaa4240, 0xbd92ad06, 0xbda84d06, 0xbd7fab28, 0x3da9bac9, 0x3be5d250, 0x3b5ff2e0, 0xbcc6309c, 0xbd87240b, 0x3d5bfcfe, 0xbc884a9c, 0x3c4008c8, 0x3d264cae, 0x3d91e3b3, 0x3d8f85b9, 0xbd8c734b, 0xbd79c950, 0x3d3b9e9a, 0x3d1eb410, 0x3cf60a2c, 0xbd73f176, 0xbd6e1b78, 0x3d921101, 0x3a9b9ec0, 0x3ce062bc, 0x3a38ee00, 0x3da89639, 0xbda2fe80, 0xbd66eb48, 0x3cbeca5c, 0xbd805854, 0xbd961532, 0xbd771aa3, 0xbd80bab3, 0x3d820b2d, 0x3d893ed5, 0x3d6cc3f2, 0xbd579be0, 0x3d4aff3a, 0xbdaa21ab, 0xbd3f0063, 0x3d309d5a, 0xbc76d488, 0xbc947420, 0xb9d77d00, 0xbcf10e30, 0xbd95628c, 0xbd0a576b, 0xbbc7eb90, 0x3d9e278d, 0xbd93adc3, 0x3ce18a20, 0x3cae06f0, 0xbbef3980, 0x3c951ac4, 0x3d3e7aea, 0xbc8b84cc, 0x3d1d235e, 0xbb533c80, 0xbcf53716, 0xbb5518e0, 0x3d09b736, 0x3c4245a0, 0x3bac8070, 0xbd3c4a9b, 0xbd17e246, 0xbd5e6703, 0xbd8cf436, 0xbd26ed80, 0x3d86dd01, 0xbd3953de, 0x3d9f7ecd, 0x3da99971, 0x3d8142d9, 0x3d77f962, 0x3d8e694d, 0x3c8f9720, 0x3d29f5f0, 0x3da2b95d, 0x3d441176, 0x3d954c0d, 0xbd8d7ca2, 0x3d691db2, 0xbcfa8bb6, 0x3d82379f, 0x3da5ea69, 0x3d4b5ffe, 0xbd80ba9f, 0xbd6b7473, 0x3cf3ae6c, 0x3d48c2de, 0xbd309196, 0x3cc590e4, 0xbbfbd930, 0xbc531940, 0xbce4b526, 0xbd3e999e, 0xbd30845e, 0x3d1114ca, 0xbc801fc4, 0x3d963419, 0x3d9e1e59, 0xbd14bd60, 0x3d8d42f1, 0x3d4d7052, 0xbd252866, 0x3d9e72d7, 0xbd13bfa0, 0x3d5877ce, 0x3d2382b8, 0xbd2090c3, 0xbd89eac2, 0xbd8b6e5b, 0x3c407860, 0x3ba1f480, 0xbbc0e000, 0xbd23f85b, 0xbd56f7c6, 0x3da21681, 0xbd89f284, 0x3c250938, 0xbc8da464, 0x3d0af776, 0xbda13d8a, 0x3daa67cb, 0x3abe13c0, 0x3d7437f6, 0xbd91eb66, 0x3d3c8f82, 0x3c07c488, 0x3d48e0ca, 0xbcd5b28c, 0xbd940127, 0x3c6ad8c8, 0xbcbb58a6, 0xbd891232, 0xbcb343b0, 0x3c9e3bfc, 0x3bc78cf0, 0x3d9a7bd1, 0x3c332128, 0x3d468eea, 0x3c9bdc54, 0xbca528ac, 0x3d85f30b, 0xbd9feb7e, 0x3d6ef656, 0x3c987604, 0xbd0e4006, 0x3c0fe698, 0x3d98f085, 0x3c88284c, 0x3d7a6ac2, 0xbd232328, 0xbcf65dd6, 0x3d8b1c87, 0x3c8579b0, 0xbd6c9a18, 0xbb8c4070, 0xbce53460, 0xb966da00, 0x3d96bf7f, 0xbd8e6da4, 0xbce5f490, 0x3d52ab1a, 0xbda75136, 0x3d4eb822, 0xbcd06aec, 0xbb83bd70, 0x3d0cd1ee, 0x3b944bc0, 0xbd85cd7e, 0x3d852373, 0xbd83b8ee, 0x3ba8cdb0, 0x3cd6a290, 0xbd38d6cb, 0xbd3d1808, 0xbc85171c, 0x3da3c7e5, 0xbd739646, 0x3c8ae160, 0x3d21d400, 0x3ccb75c0, 0xbc889df0, 0xbc72fc28, 0xbc17e118, 0xbd7a7630, 0xbc61a280, 0x3d0696ae, 0xbd8153da, 0x3d0f75ae, 0x3c39d300, 0xbd4ec36b, 0x3d87b79f, 0x3d303cca, 0xbd040c7e, 0x3c61e480, 0xbd467ac3, 0x3c94ba84, 0xbd458a26, 0x39c9c400, 0x3da4a66d, 0xbcbe4bb0, 0x3d0eb460, 0x3c9431b4, 0xbd8442ea, 0xbd8dfeff, 0xbc699a60, 0xbc989a74, 0xbd2eeb46, 0x3caecdb4, 0xbda8bd30, 0x3d820281, 0x3cb36bec, 0x3cea7350, 0x3d5f5bf6, 0x3d30c10a, 0x3d1d6ace, 0x3d41da46, 0x3c8bb4b0, 0xbc60f2b8, 0x3d9cdd91, 0x3d91abb9, 0xbd1b2748, 0xbc59dff8, 0xbc775560, 0x3d493bb6, 0xbd63f4ce, 0x3d5ff1ae, 0x3d979a9b, 0x3c82ebfc, 0x3d746e3a, 0xbd2269a3, 0x3d8ee721, 0xbd82397e, 0xbd9c315f, 0xbd39c52b, 0xba1c2e80, 0x3cdbe304, 0x3d1f1e42, 0x39e59000, 0x3d613952, 0xbda8895f, 0x3c5c46c8, 0x3cae243c, 0xbc63e420, 0x3c691308, 0x3d9d74d5, 0xba9f3440, 0x3c329100, 0xbcaeb7ec, 0xbd43f623, 0xbd1088e8, 0x3d9526a1, 0xbd1756e8, 0xbabed200, 0xbce877e0, 0x3d6c38c6, 0xbd4f0708, 0x3d855191, 0xbd1f726e, 0xbd3c8a5b, 0x3bf92500, 0xbd9791e2, 0x3da2554d, 0x3da04af7, 0xbbf66f80, 0xbd4b6d36, 0x3d6f47ea, 0xbc42df68, 0x3cb09534, 0xbba09dc0, 0xbd86382b, 0xbd70b530, 0x3d35f66e, 0x3aeb94c0, 0xbc878d1c, 0xbc168020, 0x3cb30270, 0x3cc2b0f0, 0xbc180f08, 0xbda1d4ee, 0xbd4ccd98, 0xbd894473, 0xbd9af53e, 0xbb0c2d60, 0x3d17f51e, 0xbd7b7eee, 0xbc5da258, 0xbd4dd2a3, 0x3da186fd, 0x3d134758, 0x3d193cc2, 0xbd115248, 0xbd8bf6a3, 0x3d031b48, 0xbd69ef46, 0xbc223768, 0xbcca49fc, 0x3c20e208, 0xbc83cb20, 0x3c1916b8, 0xbd8399a2, 0xbd8255ca, 0xbda299d2, 0x3d914165, 0xbcc6bf0c, 0x3a114400, 0x3cd1da4c, 0x3d4228c2, 0x3d7670c6, 0xbd1e2430, 0x3d629c22, 0xbd4473c0, 0x3d7feb8a, 0x3d9cdef1, 0x3cca8d20, 0x3d56a59a, 0xbd00ebd6, 0x3ccd2300, 0x3c0c9fa8, 0x3d5b419a, 0xbc144938, 0xbcc62d7c, 0xbda34f16, 0xbd173876, 0xbd8a6fd3, 0x3cbecc6c, 0x3cee48a4, 0x3c92f5bc, 0x3d8ea19d, 0x3d4007c2, 0xbd5ce9b0, 0xbd44c9a3, 0xbbdc8c40, 0x3d940e0f, 0x3d0eed0a, 0x3d055578, 0x3ba45490, 0x3c31d480, 0x3d755952, 0xbbe273d0, 0xbb1f86e0, 0xbd2a17e6, 0xbd3b3688, 0xbd85c086, 0x3cae4764, 0x3da0ae0d, 0x3d8840e1, 0x3d583022, 0xbd31600b, 0x3ab47ec0, 0x3d7743b2, 0xbcebc4c0, 0xbcaca0a6, 0x3d1f8a70, 0x3d8fa7f7, 0x3da7431d, 0x3d83c1fd, 0x3d2a48ee, 0xbd0b1903, 0x3c50cd78, 0x3bc170f0, 0xbd6136a3, 0xbd80455c, 0xbc50a718, 0x3c9e07a4, 0x3c6be758, 0xbc4dd160, 0xbd8690a4, 0x3d694d86, 0x3aff6500, 0x3d50db16, 0x3cd51a0c, 0x3d0f99b0, 0xbd1f047b, 0x3d6936aa, 0x3d8abc69, 0x3d0001c8, 0x3d4db9ae, 0xbd20db0e, 0xbd2bbe13, 0x3d7f21f2, 0x3cf3f014, 0xbbf91340, 0x3d39be8a, 0xbce444ec, 0x3da7e361, 0xbd123e96, 0xbd253e5e, 0xbc4a61f8, 0x3d7d283a, 0xbcb0f940, 0xbd3055bb, 0xbda15e84, 0xbd8c7f2f, 0x3daa2d09, 0x3b6c8920, 0xbd990704, 0xbd6569b8, 0x3c041668, 0xbd8e3924, 0xbd94a413, 0xbd420e3e, 0xbd396483, 0xbd7490ab, 0x3da40ca1, 0x3d48e22a, 0x3aa71100, 0xbd02a233, 0xbcf71146, 0x3d8b2c4d, 0xbd1a098e, 0x3aa1dcc0, 0x3ca652d4, 0x3bc7ce30, 0xbd1bbdb6, 0xbda6f36e, 0x3d09e0f0, 0x3c87be40, 0xbb0ed7e0, 0x3d49bbf2, 0xbd4c58f8, 0x3da8bae1, 0xbda70c08, 0x3c911f2c, 0xbd927990, 0xbceb18dc, 0xbd17b05b, 0x3b1281e0, 0xbca1db74, 0xbd9849da, 0x3c5786f8, 0xbc909ac4, 0x3d1c371a, 0x3b9e3a50, 0x3d3c374e, 0x3d883bd5, 0x3d056576, 0xbd86a74b, 0x3d8bc7e9, 0x3d620cb2, 0x3d8c0993, 0xbd88e19e, 0xbd5979e0, 0xbd898838, 0x3d6ee24a, 0xbd14ad70, 0xbd38acf8, 0xbbfe6bd0, 0xbcf2441c, 0x3c12b5f8, 0x3d7d8002, 0x3d9c2885, 0x3d7dabba, 0x3da9cb05, 0xbd21b2ab, 0x3cb0d1f4, }; // 7 uint32_t bias_vals[] = { 0xbda771f8, 0x3da2ff01, 0xbbafffb0, 0x3d986e05, 0x3b05b520, 0xbd0b22e0, 0x3d55a4aa, }; // 4,4,2,7 uint32_t output_exp_vals[] = { 0x3aae9b04, 0x3d11f138, 0x3ea6c5e5, 0x3e27faa2, 0x3e1af7ae, 0xbcd55ed5, 0x3d64578e, 0xbe34ca8f, 0xbea1a8b4, 0x3f224d3d, 0x3d8b4f5c, 0x3d5da826, 0x3d5ba7f0, 0x3e837ddb, 0xbc3cbed6, 0xbedabd2f, 0x3e0e76a3, 0x3e5e1078, 0x3eb6b112, 0xbbb0ae9e, 0x3ea6b36e, 0x3e7f83d2, 0xbe01a079, 0x3e566d4b, 0x3ecdcb4c, 0x3e278bed, 0xbe1ca4ea, 0x3e033ef1, 0x3e36026f, 0xbe814275, 0x3eda68e1, 0x3ece2c47, 0x3e99d145, 0x3de7c10a, 0x3e003eb8, 0x3ddc462f, 0xbf128f10, 0x3ef8c6c4, 0x3e0b4fe8, 0x3e234e9f, 0xbc68b0cc, 0x3ec20083, 0x3e2b8213, 0xbe83f3f4, 0x3f0cedbc, 0x3ecffe92, 0x3eab0eeb, 0x3a5ee371, 0x3eaf1fcd, 0xbdfdd7b5, 0xbe333d06, 0x3e4d244d, 0x3d9c8735, 0x3da1fd6f, 0x3dbdf320, 0x3edff713, 0x3da12ca6, 0xbe418c28, 0x3ea46203, 0x3ed77016, 0x3d4e8755, 0x3e85bec4, 0x3ec9875d, 0x3e7c02c8, 0xbed5c916, 0x3edba911, 0x3e9fc87d, 0x3e3d0777, 0x3d3e1d2d, 0x3dd82c20, 0x3e96fc25, 0xbf131fb2, 0x3f6dc404, 0x3e083262, 0x3e8bcd87, 0x3dfb8de2, 0x3db91ad3, 0x3ebcac31, 0xbe9b16af, 0x3ec8e755, 0x3f036f70, 0x3e78d3e5, 0x3cc1b424, 0x3e73c23c, 0x3d8a27e0, 0xbea947af, 0x3f006376, 0x3e3b6c9c, 0x3e145c90, 0x3b90ce9d, 0x3e8ef2c4, 0xbca2e459, 0xbe94037d, 0x3ee2e324, 0x3e83fadd, 0x3cdd4517, 0x3e2722a4, 0x3e85ec31, 0x3dde5094, 0xbef14213, 0x3f1f8519, 0x3ea5cc4d, 0x3e96bce1, 0xbbc4f4a2, 0x3e86b220, 0x3d91f714, 0xbf0b7eea, 0x3ede3416, 0x3ebd898b, 0xbdc5e339, 0x3d645a8c, 0x3ecd54ea, 0xbe7270b7, 0xbe2a28d0, 0x3efe2f4f, 0x3ecdd1bb, 0x3eb541ae, 0x3df78530, 0x3e2ff48b, 0x3ecf015e, 0xbdfc62ab, 0x3f306492, 0x3e32bcf1, 0x3d46d562, 0x3e26ff13, 0x3ebb5471, 0x3e0fdbb5, 0xbe8821f2, 0x3e9b86b6, 0x3dab64b8, 0x3e64597d, 0xbdbbcdc7, 0x3e3f9585, 0x3de4346a, 0x3dcbc01b, 0x3e5b0824, 0x3e80aced, 0x3e3d057f, 0xbdb1dc06, 0x3ed614bf, 0xbe4b9925, 0xbea5e903, 0x3efbac65, 0x3f0429b1, 0x3e397d7b, 0x3ef9017d, 0x3f09e093, 0x3cee88fd, 0xbf13fa56, 0x3ea66d86, 0x3ec4d5e4, 0x3deb3387, 0xbe3fe165, 0xbe29dbc3, 0x3e006749, 0xbe356e13, 0x3f4c4463, 0xbd05aef1, 0x3e5cacf5, 0x3bb3f58a, 0x3f0276b4, 0x3e19ffaf, 0xbefbb77f, 0x3f02c7a0, 0x3ed7c512, 0x3da438e7, 0x3e27f543, 0x3e0d4b61, 0x3e462486, 0xbeece080, 0x3f2434e2, 0x3d412397, 0x3d27f66b, 0xbe8014f3, 0x3e6c1353, 0xbe6eaff0, 0xbeba0a82, 0x3ed479f9, 0x3ea08d22, 0x3e3a5d62, 0xbe168c35, 0xbb8818a5, 0x3eb64d64, 0xbe94a7f4, 0x3ef4553a, 0x3e1b35e2, 0xbb866309, 0x3c700992, 0x3ee4e2bc, 0xbe081632, 0xbe209e82, 0x3ef13307, 0x3f0aaf13, 0x3d33f762, 0x3db0d374, 0x3dac7411, 0x3de43756, 0xbea7e814, 0x3e9bfcf1, 0x3e985384, 0x3e92c2f7, 0xbe351877, 0x3e0cf9db, 0xbea20a24, 0xbf169121, 0x3f10234e, 0x3e807156, 0x3e6978b4, 0xbd83f065, 0x3ecb7fbb, 0xbce91195, 0xbe653e1a, 0x3eef12cc, 0x3ded14a4, 0x3d0345ca, 0x3dbafae5, 0x3ebe95f8, 0x3e1207d8, 0xbeea224b, 0x3eea7e97, 0x3f063448, 0x3e843290, 0x3da4e66c, 0xbdcffdd6, }; // 4,4,2,7 uint32_t output_relu_exp_vals[] = { 0x3aae9b04, 0x3d11f138, 0x3ea6c5e5, 0x3e27faa2, 0x3e1af7ae, 0x0, 0x3d64578e, 0x0, 0x0, 0x3f224d3d, 0x3d8b4f5c, 0x3d5da826, 0x3d5ba7f0, 0x3e837ddb, 0x0, 0x0, 0x3e0e76a3, 0x3e5e1078, 0x3eb6b112, 0x0, 0x3ea6b36e, 0x3e7f83d2, 0x0, 0x3e566d4b, 0x3ecdcb4c, 0x3e278bed, 0x0, 0x3e033ef1, 0x3e36026f, 0x0, 0x3eda68e1, 0x3ece2c47, 0x3e99d145, 0x3de7c10a, 0x3e003eb8, 0x3ddc462f, 0x0, 0x3ef8c6c4, 0x3e0b4fe8, 0x3e234e9f, 0x0, 0x3ec20083, 0x3e2b8213, 0x0, 0x3f0cedbc, 0x3ecffe92, 0x3eab0eeb, 0x3a5ee371, 0x3eaf1fcd, 0x0, 0x0, 0x3e4d244d, 0x3d9c8735, 0x3da1fd6f, 0x3dbdf320, 0x3edff713, 0x3da12ca6, 0x0, 0x3ea46203, 0x3ed77016, 0x3d4e8755, 0x3e85bec4, 0x3ec9875d, 0x3e7c02c8, 0x0, 0x3edba911, 0x3e9fc87d, 0x3e3d0777, 0x3d3e1d2d, 0x3dd82c20, 0x3e96fc25, 0x0, 0x3f6dc404, 0x3e083262, 0x3e8bcd87, 0x3dfb8de2, 0x3db91ad3, 0x3ebcac31, 0x0, 0x3ec8e755, 0x3f036f70, 0x3e78d3e5, 0x3cc1b424, 0x3e73c23c, 0x3d8a27e0, 0x0, 0x3f006376, 0x3e3b6c9c, 0x3e145c90, 0x3b90ce9d, 0x3e8ef2c4, 0x0, 0x0, 0x3ee2e324, 0x3e83fadd, 0x3cdd4517, 0x3e2722a4, 0x3e85ec31, 0x3dde5094, 0x0, 0x3f1f8519, 0x3ea5cc4d, 0x3e96bce1, 0x0, 0x3e86b220, 0x3d91f714, 0x0, 0x3ede3416, 0x3ebd898b, 0x0, 0x3d645a8c, 0x3ecd54ea, 0x0, 0x0, 0x3efe2f4f, 0x3ecdd1bb, 0x3eb541ae, 0x3df78530, 0x3e2ff48b, 0x3ecf015e, 0x0, 0x3f306492, 0x3e32bcf1, 0x3d46d562, 0x3e26ff13, 0x3ebb5471, 0x3e0fdbb5, 0x0, 0x3e9b86b6, 0x3dab64b8, 0x3e64597d, 0x0, 0x3e3f9585, 0x3de4346a, 0x3dcbc01b, 0x3e5b0824, 0x3e80aced, 0x3e3d057f, 0x0, 0x3ed614bf, 0x0, 0x0, 0x3efbac65, 0x3f0429b1, 0x3e397d7b, 0x3ef9017d, 0x3f09e093, 0x3cee88fd, 0x0, 0x3ea66d86, 0x3ec4d5e4, 0x3deb3387, 0x0, 0x0, 0x3e006749, 0x0, 0x3f4c4463, 0x0, 0x3e5cacf5, 0x3bb3f58a, 0x3f0276b4, 0x3e19ffaf, 0x0, 0x3f02c7a0, 0x3ed7c512, 0x3da438e7, 0x3e27f543, 0x3e0d4b61, 0x3e462486, 0x0, 0x3f2434e2, 0x3d412397, 0x3d27f66b, 0x0, 0x3e6c1353, 0x0, 0x0, 0x3ed479f9, 0x3ea08d22, 0x3e3a5d62, 0x0, 0x0, 0x3eb64d64, 0x0, 0x3ef4553a, 0x3e1b35e2, 0x0, 0x3c700992, 0x3ee4e2bc, 0x0, 0x0, 0x3ef13307, 0x3f0aaf13, 0x3d33f762, 0x3db0d374, 0x3dac7411, 0x3de43756, 0x0, 0x3e9bfcf1, 0x3e985384, 0x3e92c2f7, 0x0, 0x3e0cf9db, 0x0, 0x0, 0x3f10234e, 0x3e807156, 0x3e6978b4, 0x0, 0x3ecb7fbb, 0x0, 0x0, 0x3eef12cc, 0x3ded14a4, 0x3d0345ca, 0x3dbafae5, 0x3ebe95f8, 0x3e1207d8, 0x0, 0x3eea7e97, 0x3f063448, 0x3e843290, 0x3da4e66c, 0x0, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, VALID_PADDING, NULL); } void test_valid_padding_zero_strides_large() { input_set *set = &large_input; strides_input_set *strides = &zero_strides; // 4,15,10,6 uint32_t input_vals[] = { 0x3dde9a10, 0x3f5666b9, 0x3e8a80fa, 0x3e0e30e4, 0x3ebd0716, 0x3f22510c, 0x3f0f0b05, 0x3f0b527d, 0x3f46e8f1, 0x3f0e2236, 0x3f3843d9, 0x3f11a3bb, 0x3e53223c, 0x3e9ebd48, 0x3f7f5de3, 0x3ed7b118, 0x3d040570, 0x3e91fc24, 0x3f65f617, 0x3e86c634, 0x3d95c918, 0x3f7380cd, 0x3f234774, 0x3edabe94, 0x3e7135f4, 0x3e350480, 0x3e5e08cc, 0x3f2f8802, 0x3f6d3d5b, 0x3ed9ee36, 0x3eccc264, 0x3ea07fe0, 0x3f7c6112, 0x3f2b105b, 0x3ebd523c, 0x3f315182, 0x3f39ff9c, 0x3e83e828, 0x3f62ed12, 0x3f5dfc1c, 0x3ef1d4fe, 0x3b973980, 0x3f25010e, 0x3df4f550, 0x3f216f1a, 0x3e72ac50, 0x3f3f925f, 0x3ef34a1c, 0x3f1514ea, 0x3f1912bd, 0x3f7518ff, 0x3f560cc0, 0x3ee8d69a, 0x3f28636f, 0x3ef8336a, 0x3e366224, 0x3efab474, 0x3f00be28, 0x3efabf90, 0x3f268971, 0x3ecc927e, 0x3efa2e24, 0x3f1e3dea, 0x3d25ae80, 0x3f28c692, 0x3e699f80, 0x3e892528, 0x3f5c0fa4, 0x3f3d0b21, 0x3f504cea, 0x3eec2d20, 0x3ea48b0c, 0x3f7c7068, 0x3e2b6d44, 0x3f7788a7, 0x3e275054, 0x3efed888, 0x3f4bfe3c, 0x3f6120fe, 0x3f504c76, 0x3dff1a98, 0x3f4e8175, 0x3ef0831c, 0x3f1ddffc, 0x3e82330a, 0x3dc33bc8, 0x3f394b53, 0x3f634e17, 0x3f47ebf7, 0x3f7f3c84, 0x3f4cd033, 0x3d9d2098, 0x3f341604, 0x3eed28a2, 0x3f763a8b, 0x3ea42184, 0x3f29d214, 0x3f7b3dc8, 0x3e94f71c, 0x3eabbd3a, 0x3f0b6fd7, 0x3f46fac2, 0x3e276790, 0x3e82797c, 0x3e92c996, 0x3f1592e2, 0x3f12d101, 0x3edcf45a, 0x3e86d9bc, 0x3f6d4119, 0x3f30d665, 0x3f5fad7a, 0x3e13afb0, 0x3f144cd9, 0x3efede78, 0x3f72d999, 0x3e4f1154, 0x3f40f5ea, 0x3f474e3b, 0x3efa4892, 0x3e5460cc, 0x3f23568b, 0x3f450c05, 0x3f61a5aa, 0x3f4859d2, 0x3cd13f40, 0x3e3f6d04, 0x3e805646, 0x3f53dfe9, 0x3ef89136, 0x3e0add1c, 0x3f33e7df, 0x3efae34a, 0x3f2113b1, 0x3f3ed68e, 0x3dfa3530, 0x3f4b139a, 0x3f233a7e, 0x3d8516b0, 0x3f1aa364, 0x3e66ff18, 0x3f38dcf6, 0x3f231575, 0x3d83d8c0, 0x3e2fe2e0, 0x3f1aa7d5, 0x3f78784e, 0x3f096b77, 0x3e45bb30, 0x3ef7329e, 0x3f145b96, 0x3f0ff17d, 0x3f30c586, 0x3f1e8e09, 0x3ed5ce52, 0x3f17f212, 0x3ee5824a, 0x3f7dc58f, 0x3c189280, 0x3f772b3a, 0x3d60d290, 0x3f67010e, 0x3f3d57cf, 0x3f11a4b3, 0x3c8f9220, 0x3ec55dfa, 0x3f1152b0, 0x3f7e784b, 0x3f5b8914, 0x3f3f87da, 0x3f2d606d, 0x3f7465f2, 0x3f4048d2, 0x3ed29954, 0x3f51c6fa, 0x3ea0a238, 0x3f3b0cd7, 0x3e51a488, 0x3e1e8910, 0x3ed2c5de, 0x3e8d776e, 0x3eabf5c4, 0x3f6f08c2, 0x3e34abe8, 0x3eecc686, 0x3ec6b340, 0x3f0ef530, 0x3f6a2f92, 0x3f6312d6, 0x3f53b437, 0x3f64b769, 0x3e071134, 0x3eaaf75e, 0x3eea6cbc, 0x3f4f7b3c, 0x3f6153a5, 0x3f621982, 0x3f3e978e, 0x3f1f06ec, 0x3f35445c, 0x3eb2f924, 0x3e9ec55e, 0x3f51c216, 0x3f7d51ea, 0x3d2a5290, 0x3e8f57d2, 0x3eeea1a0, 0x3f177ad9, 0x3e6167f4, 0x3f6e0812, 0x3f682c4a, 0x3f18b998, 0x3e3f51dc, 0x3f0eb695, 0x3efa3014, 0x3d83a8f0, 0x3f5400e4, 0x3de51a28, 0x3f044430, 0x3f28dfee, 0x3e848d58, 0x3d1c74a0, 0x3ec975c6, 0x3f11e457, 0x3f1b0942, 0x3ed94f5a, 0x3f727868, 0x3e330edc, 0x3e920154, 0x3f13b95a, 0x3f3a6348, 0x3c5207c0, 0x3f05a886, 0x3ed204f2, 0x3f6a800e, 0x3eea6228, 0x3f1a60d5, 0x3f2abe0b, 0x3e4471d4, 0x3ebdc5c4, 0x3f46891e, 0x3f339bc7, 0x3f173a63, 0x3c6fa340, 0x3edc80ca, 0x3cf6d5a0, 0x3f7c30af, 0x3f44aa42, 0x3f001b8b, 0x3e1f0ad0, 0x3f071aa5, 0x3d830718, 0x3e519f6c, 0x3f5af810, 0x3ddd5948, 0x3dd93078, 0x3f2b2a8f, 0x3dd55958, 0x3e186300, 0x3d32ef30, 0x3e906c9e, 0x3f325c14, 0x3ed906a2, 0x3eb646dc, 0x3d4eb620, 0x3eec02b6, 0x3ec49966, 0x3f37af89, 0x3f15ac66, 0x3f021455, 0x3ed9680a, 0x3f49fa35, 0x3f223794, 0x3e55bda0, 0x3cecfce0, 0x3f7af654, 0x3f00a73a, 0x3f55119d, 0x3f04f474, 0x3f729c90, 0x3eb28c82, 0x3ce7c2c0, 0x3f6852b3, 0x3ddd8638, 0x3e5ff158, 0x3e189898, 0x3f46bbe7, 0x3f4e5dcf, 0x3e769b38, 0x3effedc6, 0x3e88efca, 0x3f5d77a8, 0x3f348d05, 0x3e978342, 0x3d546e00, 0x3ef2d14a, 0x3ec0c2b2, 0x3f38002e, 0x3f7d2946, 0x3f7ea4b8, 0x3f056100, 0x3ed5704c, 0x3f6d2747, 0x3ec7e3f6, 0x3f663e4e, 0x3da77ed8, 0x3f169043, 0x3f36da8a, 0x3f5562d8, 0x3f654053, 0x3f426c9a, 0x3d6bb610, 0x3f233c4c, 0x3f359222, 0x3d8ffb60, 0x3f5e3978, 0x3e83b710, 0x3eda2fc0, 0x3e9adcb2, 0x3d3ad540, 0x3e6a84ac, 0x3f688790, 0x3f737dc8, 0x3f34f35b, 0x3ddcc4f8, 0x3f147b0e, 0x3f2fa60f, 0x3dc02228, 0x3f57c84d, 0x3dba3300, 0x3d0b1030, 0x3e6c3878, 0x3ea7c9de, 0x3ea03e24, 0x3ea43e30, 0x3ec423e2, 0x3f7f26eb, 0x3f420836, 0x3eb02a96, 0x3e159168, 0x3e896ebe, 0x3ddc4ee0, 0x3ebd628e, 0x3efa24b2, 0x3dbdf0b8, 0x3f6638e7, 0x3e80da60, 0x3f492d7d, 0x3ecff6b8, 0x3f163ca6, 0x3ee5d554, 0x3f1cae60, 0x3e3afd54, 0x3e86460a, 0x3f45a3ef, 0x3edc3dc0, 0x3f2c2859, 0x3e7cf8ac, 0x3f334c75, 0x3e842c28, 0x3e7026d0, 0x3f65fdbb, 0x3f719460, 0x3ede5fd6, 0x3e75b1ac, 0x3d8c6be8, 0x3d2c88d0, 0x3daf1b08, 0x3eba86ea, 0x3f586ea8, 0x3f712640, 0x3f26be89, 0x3c52abc0, 0x3f37a1b8, 0x3e9ab7ae, 0x3f778239, 0x3f1cc44e, 0x3f759a65, 0x3ef2481a, 0x3f7c9113, 0x3f17a8e7, 0x3f010e4a, 0x3f0226dc, 0x3f20b226, 0x3f2863ba, 0x3e9adea6, 0x3f0a25ee, 0x3d3f6df0, 0x3f284520, 0x3f320f11, 0x3f3c65be, 0x3f20ed9d, 0x3f0f8492, 0x3e8b1e8c, 0x3f4810fe, 0x3f641106, 0x3e8cdbce, 0x3e8199ca, 0x3d13ded0, 0x3f59d926, 0x3ed58276, 0x3eeebb88, 0x3f095c8e, 0x3e845efc, 0x3f63f1ad, 0x3f137a99, 0x3de7ee08, 0x3efeb994, 0x3f05beda, 0x3e688e04, 0x3efcfb46, 0x3f55867b, 0x3c3e7dc0, 0x3f6d645e, 0x3f4e03a8, 0x3f3f44fe, 0x3eea0742, 0x3f697c49, 0x3f7706f6, 0x3eaa1804, 0x3e4bf2f0, 0x3f528e35, 0x3ead3262, 0x3ea84e78, 0x3f77c29f, 0x3d2ab6e0, 0x3f5e5096, 0x3ede2990, 0x3d20b2c0, 0x3f4a4c64, 0x3ea004aa, 0x3f107192, 0x3ec62bdc, 0x3ee0dd08, 0x3eab5996, 0x3ee2688e, 0x3f70b6ca, 0x3f367c38, 0x3f3703c0, 0x3e0e7294, 0x3d27dbd0, 0x3e8e7d26, 0x3f32af3f, 0x3f2a3f2a, 0x3db1c370, 0x3f4519b3, 0x3f34aa2b, 0x3e1e5c14, 0x3d85acc0, 0x3f5f1e1f, 0x3ea4b136, 0x3f3a3b66, 0x3e736488, 0x3f18ff06, 0x3ed88d1e, 0x3f6afd1d, 0x3e64fbc0, 0x3ef46cb2, 0x3d3e21b0, 0x3f1be89b, 0x3d468400, 0x3f003634, 0x3e842706, 0x3e3e4764, 0x3e7c9e38, 0x3f53fd99, 0x3f378a79, 0x3f4b4832, 0x3de73ed8, 0x3f4036f6, 0x3f321383, 0x3f7d92f0, 0x3f2d9197, 0x3d9fbdd8, 0x3f1d5f3f, 0x3e31b094, 0x3e630d20, 0x3ddcca98, 0x3f3ced3a, 0x3f0dbd5c, 0x3f7d0a1c, 0x3f535d3c, 0x3de89e08, 0x3ed6d14e, 0x3ef5b28e, 0x3f4b3164, 0x3f606410, 0x3dd17730, 0x3e9b5210, 0x3eb28bf4, 0x3f128966, 0x3f4e7f32, 0x3e401670, 0x3f2cee74, 0x3f78534f, 0x3f417f95, 0x3e4ca56c, 0x3cfe2aa0, 0x3ee6706a, 0x3e25c45c, 0x3f46bc4d, 0x3f3e6af8, 0x3dafa298, 0x3f70143c, 0x3ebbbce6, 0x3f0f0a79, 0x3f1e9e36, 0x3f7415e6, 0x3ea5b550, 0x3f044ea3, 0x3e902d2a, 0x3f7bbffe, 0x3ebe17f6, 0x3f58254c, 0x3f2eb2a9, 0x3f0d0d50, 0x3e8fe4b4, 0x3f59fd71, 0x3e978a5a, 0x3f56f198, 0x3ed0adf6, 0x3f078ee9, 0x3f220c69, 0x3e0186dc, 0x3f1a3fc2, 0x3df6e6f8, 0x3ecb2ba4, 0x3f01f111, 0x3e914772, 0x3ec2fa9a, 0x3f5c0c34, 0x3e2ce3c4, 0x3e688ce0, 0x3e4c5c6c, 0x3e197710, 0x3f153d72, 0x3de9fe40, 0x3dcb82d8, 0x3e802ffa, 0x3f6f96d3, 0x3f111cab, 0x3eaa9140, 0x3f639e7d, 0x3e81c8f4, 0x3e73f658, 0x3f28144d, 0x3f79a8bf, 0x3ed0dc28, 0x3c997ee0, 0x3e81f87c, 0x3ecb3056, 0x3e185a84, 0x3ef76e98, 0x3f60b77c, 0x3d44ae80, 0x3f596e31, 0x3f7791bc, 0x3def36c8, 0x3f7ba9b4, 0x3e00e470, 0x3cbd5740, 0x3e83c666, 0x3ebe7e1c, 0x3f47be8d, 0x3e38b0f8, 0x3ddd5388, 0x3f296cd3, 0x3f6dcc4d, 0x3ede214a, 0x3f64cb7c, 0x3f6b83d7, 0x3db74d28, 0x3f05418c, 0x3f6c030d, 0x3e72fb40, 0x3f170005, 0x3efa00aa, 0x3efb578c, 0x3f1fea78, 0x3f4fce40, 0x3e488180, 0x3f700aa9, 0x3f5b50a2, 0x3ed435e6, 0x3e086648, 0x3f4b174c, 0x3c2939c0, 0x3eeae46a, 0x3f114a86, 0x3f214240, 0x3e4ac3f8, 0x3f5ae693, 0x3e39caa0, 0x3e9b7cb0, 0x3f207954, 0x3e679794, 0x3f35f930, 0x3f14fab7, 0x3eb63b42, 0x3f3ae46c, 0x3da38db0, 0x3e777d44, 0x3f5b4f5b, 0x3e2bd12c, 0x3ec4c640, 0x3efe0a04, 0x3ed14470, 0x3e8b93fc, 0x3da4eed8, 0x3f5fa53c, 0x3e1f86ec, 0x3f0f9ac9, 0x3efcee4a, 0x3f313a50, 0x3f071c15, 0x3f5d44c9, 0x3eec2ebe, 0x3f0a13cf, 0x3ed6d21e, 0x3f7b9ed5, 0x3eef0120, 0x3f571c5b, 0x3f6befec, 0x3f607b3f, 0x3f537d7e, 0x3d8b4a48, 0x3ec1ad4c, 0x3e1a8fa0, 0x3de922f8, 0x3f3bcb03, 0x3ea04e1c, 0x3f466874, 0x3f2c44c4, 0x3edfbbe4, 0x3f4fe4dd, 0x3f43503d, 0x3e99177a, 0x3f547e6b, 0x3df35af8, 0x3f52ffa7, 0x3dec08e0, 0x3f0e64c0, 0x3e0c8588, 0x3e171508, 0x3f3edf17, 0x3ef7e06e, 0x3f1732af, 0x3eb4c858, 0x3f2a4919, 0x3e552a04, 0x3e9c4d5a, 0x3eede6c6, 0x3f013ec9, 0x3e1b7d40, 0x3f69938c, 0x3f636881, 0x3f5664e3, 0x3e6e669c, 0x3dc7b5f0, 0x3edf5cc4, 0x3f16adc4, 0x3e9c66ce, 0x3ec0871e, 0x3f40173a, 0x3e79c3cc, 0x3d6829e0, 0x3e45a1a4, 0x3f44d2d6, 0x3f59ba11, 0x3f3873af, 0x3e866832, 0x3e5f5550, 0x3f3095ba, 0x3f0a1994, 0x3e2a01b0, 0x3ec81fee, 0x3df462b8, 0x3ec164cc, 0x3f111a8d, 0x3d5dc7e0, 0x3d3c9cb0, 0x3f5e78ac, 0x3f0956a1, 0x3f5f80b1, 0x3f512aba, 0x3f44f54a, 0x3f7dd77c, 0x3e52c9ec, 0x3dd14f80, 0x3b5cda00, 0x3effc556, 0x3f0df3ec, 0x3ea90e42, 0x3f42940f, 0x3f7734a2, 0x3f4b1e5e, 0x3f776aa0, 0x3e485e24, 0x3f011595, 0x3ef540ae, 0x3f0748a5, 0x3e46d958, 0x3f6ec052, 0x3f166e84, 0x3f5db818, 0x3e988ebe, 0x3df37ec8, 0x3d138ce0, 0x3e39f538, 0x3e9f145a, 0x3f72514e, 0x3f13ceab, 0x3e99a322, 0x3e262edc, 0x3f617b26, 0x3e5d84dc, 0x3f1addd1, 0x3d824e90, 0x3f6fc8f7, 0x3e26588c, 0x3ea986fa, 0x3eb074ae, 0x3d090e40, 0x3f688236, 0x3ef57cd8, 0x3f7bfe40, 0x3c3dcf80, 0x3dba81f8, 0x3e42aa74, 0x3ec9e218, 0x3f3acc72, 0x3f5d4b80, 0x3f7789e4, 0x3d112700, 0x3f4fab9f, 0x3e7883c0, 0x3f57ece7, 0x3f799bcd, 0x3e6c8aa0, 0x3efaa290, 0x3f2899ed, 0x3f0c8eff, 0x3e7a7e68, 0x3e6b8fd8, 0x3f145bda, 0x3e320ddc, 0x3f45866a, 0x3f49a803, 0x3f6dd94c, 0x3ca89800, 0x3f75a2de, 0x3f2b8b90, 0x3e9fe78a, 0x3f5f2f68, 0x3e718f34, 0x3ec2cddc, 0x3e84f64e, 0x3f569922, 0x3d141e50, 0x3f54a651, 0x3daa4730, 0x3f65103c, 0x3f5c03bb, 0x3ee2a65a, 0x3ed6f704, 0x3ed0de16, 0x3f4d955c, 0x3f420b48, 0x3f1e7c00, 0x3d9e5cf0, 0x3f332f34, 0x3f1d0d66, 0x3df5cb48, 0x3dd27670, 0x3f00f0a1, 0x3d2ef880, 0x3f595d1d, 0x3f757dff, 0x3e2434c8, 0x3eb6ee10, 0x3f3160b4, 0x3f4340a3, 0x3e2bf9d8, 0x3f44c362, 0x3df45d88, 0x3f03aaf1, 0x3e8aedb0, 0x3f0864ba, 0x3e82663e, 0x3f7f893c, 0x3f2c9e98, 0x3f7bef69, 0x3e92bda0, 0x3d8595e0, 0x3f6ac9e2, 0x3f162920, 0x3ef30786, 0x3e1fbfe4, 0x3d9d8840, 0x3e8fffb8, 0x3f690843, 0x3ca13020, 0x3f6e3e98, 0x3f56cb81, 0x3f699860, 0x3f2800b6, 0x3f7c2a76, 0x3f25f83f, 0x3e8f9a3a, 0x3f4b45c1, 0x3e941d82, 0x3f0a6617, 0x3f5b568c, 0x3ebefe56, 0x3f062dc4, 0x3e6c3608, 0x3f644910, 0x3f3d9385, 0x3f2248e3, 0x3f16e417, 0x3f422fc9, 0x3e02743c, 0x3f10b997, 0x3f787f63, 0x3eff6528, 0x3f31f201, 0x3ed63288, 0x3e4dc254, 0x3eef9eba, 0x3ea424f0, 0x3e033898, 0x3f483b3e, 0x3eee0e60, 0x3f54a3ae, 0x3f707107, 0x3eb1d8b8, 0x3ea3f662, 0x3e86a1f0, 0x3e3a55a0, 0x3c5b4080, 0x3f400a5d, 0x3ba1e600, 0x3c245d80, 0x3e03f8dc, 0x3f4bd525, 0x3f56d750, 0x3f465ca5, 0x3f753a24, 0x3f53932c, 0x3f753932, 0x3f3002fa, 0x3f7573e1, 0x3edc2d02, 0x3eea00b4, 0x3f4ef31c, 0x3f2061a2, 0x3ed42d84, 0x3cfc5a00, 0x3f3582b0, 0x3eb5e528, 0x3f39b688, 0x3f3d6023, 0x3e93d0ac, 0x3ed99934, 0x3ca1a700, 0x3ee8cbc6, 0x3ed281a4, 0x3f22db40, 0x3f553c37, 0x3f569447, 0x3ef9dd52, 0x3e9119ae, 0x3d9d6450, 0x3ed21636, 0x3d7c0c80, 0x3ebf4de0, 0x3eff1cdc, 0x3f0d44fd, 0x3f6fa051, 0x3d224dc0, 0x3f35bc2d, 0x3f36af8d, 0x3dabfb38, 0x3f5f0742, 0x3f1d0ba1, 0x3f72de8e, 0x3f595940, 0x3efda5c6, 0x3ed11820, 0x3f2caeca, 0x3f1b0ee9, 0x3f79485e, 0x3eaa2076, 0x3e8c2908, 0x3f2aab2a, 0x3f1fb784, 0x3ebed2b0, 0x3efaad12, 0x3f32d9c5, 0x3f5ca5aa, 0x3f13aac6, 0x3f33e900, 0x3e9c048a, 0x3ebeec30, 0x3de4ace8, 0x3ee1bf3e, 0x3eda1554, 0x3e4304a0, 0x3eccea32, 0x3c185780, 0x3a62c000, 0x3f129687, 0x3f2b6afb, 0x3ef8dd9a, 0x3efef2c8, 0x3efabb70, 0x3f31329b, 0x3eaaf4b2, 0x3e705b30, 0x3f359ace, 0x3d755780, 0x3e03656c, 0x3f5aee42, 0x3f601ac2, 0x3ecf12c2, 0x3f1542cb, 0x3f616c0f, 0x3f65fa63, 0x3eb25ac8, 0x3f3150f8, 0x3e4f0330, 0x3f7f2005, 0x3c8f2020, 0x3d7e11f0, 0x3ce24b60, 0x3f4f1d9b, 0x3e59a0f8, 0x3e95f830, 0x3e8259fc, 0x3e9af1a6, 0x3e9d9f6a, 0x3f2be0f4, 0x3e58d5cc, 0x3c3b3ec0, 0x3db825b0, 0x3f22da62, 0x3f33d2af, 0x3f2a8f48, 0x3eeebd58, 0x3f47df0d, 0x3e562c84, 0x3f389e47, 0x3f73c47b, 0x3f0f051d, 0x3e09338c, 0x3f09097a, 0x3f2636c7, 0x3f7fdd98, 0x3f43b245, 0x3e887714, 0x3ee2db9a, 0x3dc37750, 0x3e4248b8, 0x3f68cb57, 0x3e9e4ddc, 0x3ef87f02, 0x3eae45ac, 0x3ef16d84, 0x3e9b63ba, 0x3f15d482, 0x3f7686fc, 0x3f32374b, 0x3ecaa86e, 0x3d4eb820, 0x3e189168, 0x3f657fb2, 0x3f487ddb, 0x3e485900, 0x3e87ec2e, 0x3f4c0789, 0x3ef47170, 0x3f05f39d, 0x3f071df5, 0x3f7ef527, 0x3e44b92c, 0x3f741fe0, 0x3f72785a, 0x3e8d064a, 0x3f56187b, 0x3f6369db, 0x3f763261, 0x3f20d6c1, 0x3f361d8b, 0x3f01b064, 0x3e3e8e40, 0x3e477d3c, 0x3f30fba9, 0x3f7de0ed, 0x3f4e06a5, 0x3f120740, 0x3f0fc4b2, 0x3e124838, 0x3f6bd6fc, 0x3e524bb8, 0x3dd3ae18, 0x3f026d51, 0x3f0c2ae3, 0x3f1f40f5, 0x3ef1961c, 0x3ed25ff8, 0x3ea8a132, 0x3ef53324, 0x3efd0554, 0x3e04ffa0, 0x3f5e4d19, 0x3f15b827, 0x3f3a2ce0, 0x3e509920, 0x3f578a80, 0x3f35395e, 0x3f0202ea, 0x3ef45882, 0x3ee79d08, 0x3f311f86, 0x3f46114c, 0x3f527009, 0x3f03040e, 0x3f67a752, 0x3f636c40, 0x3f305276, 0x3f1d0907, 0x3f375100, 0x3d14c6c0, 0x3f6427f7, 0x3e173860, 0x3f4086d0, 0x3f251e5a, 0x3f08e8aa, 0x3f2c5678, 0x3ebfe734, 0x3ca7c0c0, 0x3ea0cb40, 0x3e240a40, 0x3e7771dc, 0x3f46629f, 0x3d2f2a90, 0x3de78420, 0x3f2098a2, 0x3f6036b8, 0x3d57cbd0, 0x3ec24cb8, 0x3f1abc4f, 0x3e7fa680, 0x3f531f0a, 0x3f008460, 0x3f25578b, 0x3d686ee0, 0x3f509a87, 0x3f59da6b, 0x3e893680, 0x3e8757ae, 0x3f5db794, 0x3e1a2738, 0x3f0f2303, 0x3ea6bab0, 0x3eb59ca6, 0x3f21173a, 0x3ef9bf4c, 0x3f58b072, 0x3ea3aede, 0x3e826bf6, 0x3f48612c, 0x3e9ae01e, 0x3ef38c3e, 0x3eb5d910, 0x3f231879, 0x3ef604e6, 0x3e5c26e8, 0x3f0ce0b9, 0x3e993b1e, 0x3f40f716, 0x3d03ba80, 0x3f46ef54, 0x3f16e89e, 0x3f0a2dab, 0x3f09c400, 0x3f17d07c, 0x3f6a60a4, 0x3b3eb100, 0x3ec323c4, 0x3f11e57d, 0x3e9e09d0, 0x3f6dc06e, 0x3f113b2d, 0x3ec51676, 0x3ea7c88e, 0x3f51a558, 0x3dc49d10, 0x3ef73706, 0x3f7c9820, 0x3ea1bf14, 0x3cd7c060, 0x3f520de6, 0x3f09a730, 0x3f1d1603, 0x3f6d2e4e, 0x3e36f550, 0x3f2b96c8, 0x3f65850c, 0x3ea4292e, 0x3e1bf0b4, 0x3f48ff2d, 0x3eb264c2, 0x3f04938b, 0x3e04a5a4, 0x3e719f1c, 0x3e2851e0, 0x3ea32a5c, 0x3ee7f486, 0x3d942018, 0x3edb51c2, 0x3d9b0df0, 0x3f5f80d5, 0x3e79d294, 0x3d6368e0, 0x3ed616ec, 0x3ec07510, 0x3eb2237c, 0x3e336bfc, 0x3f0857f4, 0x3f643c6a, 0x3f0a9bd0, 0x3ea97538, 0x3f0cc6ea, 0x3f0349d7, 0x3f7837e4, 0x3f28e3c4, 0x3f182155, 0x3c2022c0, 0x3dcfc128, 0x3cc5d4e0, 0x3edc633c, 0x3f049650, 0x3dc3f3d0, 0x3f554ea0, 0x3f14f358, 0x3e9f12d0, 0x3f5e568b, 0x3efee806, 0x3ee80fbe, 0x3efa549a, 0x3eb13138, 0x3edea102, 0x3ee5caa8, 0x3f14c6f6, 0x3f5f7be2, 0x3f6a3552, 0x3f3530d0, 0x3f4d53c4, 0x3f328d76, 0x3f762e45, 0x3d4a4180, 0x3f78be4d, 0x3f364eb2, 0x3f4f252a, 0x3e675ea4, 0x3f18c5b8, 0x3e16f590, 0x3f2c6606, 0x3ecca7fe, 0x3f2c1590, 0x3f03fae4, 0x3f046c04, 0x3f5054bf, 0x3eb195a4, 0x3cbb6940, 0x3ec22620, 0x3f6e4ef7, 0x3ef9a4e6, 0x3e97d63e, 0x3f72afeb, 0x3ec5c2dc, 0x3f3718ee, 0x3dbd3cc0, 0x3e243758, 0x3e83a3f2, 0x3f4afacc, 0x3db27ea8, 0x3f20dfa1, 0x3e8267e0, 0x3bf90e00, 0x3e3e79ec, 0x3f4af74f, 0x3f0b254d, 0x3f2904d4, 0x3ed25a54, 0x3ecf2002, 0x3f216188, 0x3ed106f4, 0x3ce40b80, 0x3f128659, 0x3d0af280, 0x3d42f880, 0x3f0c2351, 0x3f1b1295, 0x3dcd9fa0, 0x3eef4b00, 0x3d8d4058, 0x3f34d4e6, 0x3f022e1e, 0x3dc43d48, 0x3f4a4526, 0x3f77f9c3, 0x3f027a21, 0x3e61a9a0, 0x3f28a426, 0x3f6a5e14, 0x3e7ed790, 0x3f595100, 0x3ee07650, 0x3f103dca, 0x3f265efc, 0x3f6d0eda, 0x3f208d06, 0x3eee460a, 0x3f53c6ad, 0x3f35f4e4, 0x3e491a8c, 0x3edfa122, 0x3f6ae4c8, 0x3c04b240, 0x3ee4a666, 0x3e640d3c, 0x3f057a38, 0x3ef2d08a, 0x3ddb1d30, 0x3f1ef9bd, 0x3f59b5f6, 0x3ec9467e, 0x3b9f4e80, 0x3ef417b8, 0x3d40d7b0, 0x3f166c75, 0x3f48c414, 0x3dc185e0, 0x3dcfb480, 0x3f29a020, 0x3dea2738, 0x3f3c5bc2, 0x3f63d794, 0x3ecdaf12, 0x3f4092f3, 0x3f04a597, 0x3f3bf424, 0x3cf68a80, 0x3ecaf7c4, 0x3f680a46, 0x3f0cd9b3, 0x3d9a6170, 0x3f74571d, 0x3f189457, 0x3f0fb14c, 0x3f32a257, 0x3e37c8a8, 0x3ee3f834, 0x3f1b9abb, 0x3f6c2eed, 0x3d81d488, 0x3f576f7a, 0x3e64d798, 0x3ea4c918, 0x3e0465f0, 0x3f10ee31, 0x3f49a007, 0x3e672bd0, 0x3f5ac69f, 0x3f4e398c, 0x3e66ea30, 0x3e819114, 0x3f35d445, 0x3d5f85c0, 0x3d9f6d18, 0x3e27ec0c, 0x3e95349e, 0x3e868136, 0x3f1a4348, 0x3e8b20d6, 0x3e4497f0, 0x3de0e670, 0x3c9df120, 0x3f266f3a, 0x3ec92d5e, 0x3e95f826, 0x3f6195ce, 0x3f6561ce, 0x3f32d7f1, 0x3f38602a, 0x3f744f23, 0x3f4c2594, 0x3dcf7210, 0x3db90100, 0x3f5f9ba4, 0x3de93160, 0x3db1ed90, 0x3e77e55c, 0x3e593b08, 0x3f3bd60c, 0x3f6a2099, 0x3f71fcfd, 0x3f432777, 0x3f526fea, 0x3f496542, 0x3ed3a442, 0x3d34b0d0, 0x3e7403f4, 0x3f6fef7c, 0x3dee3f40, 0x3dee2ba0, 0x3ce9a380, 0x3f2fbeb1, 0x3f1b8226, 0x3f2ce7bd, 0x3f242d28, 0x3f1f15bb, 0x3d15a8d0, 0x3ecf248c, 0x3f523e8c, 0x3f68f26e, 0x3f111dcd, 0x3f644868, 0x3f045a7c, 0x3cd52e40, 0x3e090228, 0x3e468aac, 0x3f5683b3, 0x3f1012b0, 0x3eea4c98, 0x3f4fa265, 0x3f599461, 0x3f72ce24, 0x3f54457a, 0x3e73f554, 0x3f31811f, 0x3f452b9e, 0x3f00ad20, 0x3f5e239e, 0x3dea9d98, 0x3e30e688, 0x3f1663cf, 0x3ef10362, 0x3eaf5b1e, 0x3e947300, 0x3f71bbe4, 0x3d271680, 0x3e7f71b0, 0x3f078c13, 0x3e3a54c0, 0x3f6d6c9a, 0x3f1f63db, 0x3f446f5a, 0x3f6d72bf, 0x3e371870, 0x3f66f42f, 0x3e8be2e4, 0x3f7bf867, 0x3ef936b6, 0x3eeeecae, 0x3f4ce3cc, 0x3f49ffd9, 0x3d9e5af8, 0x3f351566, 0x3efacb16, 0x3f19305c, 0x3eafecf6, 0x3ec8e93c, 0x3f77e805, 0x3d94bec0, 0x3e459a4c, 0x3e9cb5b2, 0x3eff2850, 0x3f1f0616, 0x3f27f7ac, 0x3f2049f2, 0x3de85d90, 0x3ec46a54, 0x3f6a5bf4, 0x3f22beb3, 0x3f476ea3, 0x3ef531ec, 0x3ecf4648, 0x3e63a008, 0x3e500980, 0x3dc9a988, 0x3f1f2875, 0x3f3d6ff0, 0x3f26476b, 0x3e4c7368, 0x3f79d8f9, 0x3f7163a8, 0x3f127746, 0x3e9acad6, 0x3f50416f, 0x3e0a3764, 0x3f407361, 0x3d863c60, 0x3f2aa2d2, 0x3efaecb4, 0x3f5e64d4, 0x3f3c2367, 0x3e456730, 0x3f2f91cc, 0x3f2f9a98, 0x3dce6770, 0x3ee98ae8, 0x3f4a12f8, 0x3e28fcdc, 0x3f3768b4, 0x3e2b0850, 0x3ed5462a, 0x3c33c800, 0x3f34576e, 0x3d99d928, 0x3efc18ee, 0x3f53b5cb, 0x3e6ff138, 0x3f593d23, 0x3bbd5400, 0x3f4e8810, 0x3e798830, 0x3f088dea, 0x3f25f6f3, 0x3e9a0dd6, 0x3f08c3ec, 0x3f0472d2, 0x3da2d0e0, 0x3f379feb, 0x3dce43b8, 0x3f0c2f75, 0x3cf2d820, 0x3edabe3a, 0x3f5492ed, 0x3d8458a0, 0x3f0159f9, 0x3eceb838, 0x3e99b766, 0x3f616097, 0x3ef170a4, 0x3e42ccb0, 0x3f0f828c, 0x3e5f56e4, 0x3f03cf3d, 0x3ecd7f68, 0x3e90cd66, 0x3e8d4228, 0x3f0370cc, 0x3ea8e362, 0x3f46f665, 0x3f310e94, 0x3ea651b8, 0x3db9f2e8, 0x3f7c709c, 0x3ed4b2f4, 0x3e9b356e, 0x3f16e8ff, 0x3f0de0ab, 0x3f63e075, 0x3d8be170, 0x3dd62588, 0x3f4a9656, 0x3eeaa6ae, 0x3f639f2b, 0x3f140ab8, 0x3f59faa2, 0x3e492ca8, 0x3f2e0ecf, 0x3e6a5404, 0x3d5142a0, 0x3e095f38, 0x3b06cb00, 0x3edeb7aa, 0x3f0248c7, 0x3e2a5bcc, 0x3f0fc87b, 0x3e43e100, 0x3e9552d4, 0x3f2c7ba7, 0x3f7ecf7c, 0x3d33aab0, 0x3d685c60, 0x3ec53d5e, 0x3e8d6620, 0x3f7f0ab4, 0x3ec0bdcc, 0x3f63fd18, 0x3dab59b0, 0x3f6bea4a, 0x3e7734a4, 0x3f529e4f, 0x3f1be6bb, 0x3f7435f7, 0x3e485f64, 0x3e966afc, 0x3f2923cd, 0x3f55761b, 0x3e93a548, 0x3f7e189d, 0x3f5e5618, 0x3f738a75, 0x3e96944e, 0x3ef4d644, 0x3f03db36, 0x3f3df7a2, 0x3ece0e08, 0x3f4624f6, 0x3eb398aa, 0x3f1bc3bf, 0x3f287e57, 0x3ec5f0da, 0x3f0f675e, 0x3e0fd6c8, 0x3f662cef, 0x3ea98894, 0x3b4d8000, 0x3e4c3fa4, 0x3f31763c, 0x3d4e91b0, 0x3f263f88, 0x3e26e93c, 0x3f5a3217, 0x3ba7b900, 0x3f1123cc, 0x3f2486d6, 0x3f251a39, 0x3f624d10, 0x3f3c0ac3, 0x3e9d338c, 0x3f30a70e, 0x3f577929, 0x3eb9511a, 0x3f3b7363, 0x3e9a3b0e, 0x3e1fc188, 0x3e77b2d8, 0x3ecd0964, 0x3f246d1d, 0x3f6e821f, 0x3e3afa50, 0x3eb97996, 0x3f228232, 0x3d7b7070, 0x3e91a548, 0x3f3ffb2e, 0x3e8a35f0, 0x3e173980, 0x3f63a28f, 0x3f2fa0c8, 0x3f1f55de, 0x3e4c82ac, 0x3f345672, 0x3e10f60c, 0x3c5c19c0, 0x3eaaedda, 0x3d8cdfb8, 0x3d408450, 0x3bfdcb00, 0x3ef9b4e4, 0x3f45e2b0, 0x3e86b840, 0x3d76dad0, 0x3f7e9142, 0x3e8928e4, 0x3e19d144, 0x3ec42918, 0x3f0ae221, 0x3f43a419, 0x3e0d8408, 0x3e1dc598, 0x3f0e0ec8, 0x3f492f98, 0x3f5fb339, 0x3f465f0e, 0x3eb6bf26, 0x3f715b5e, 0x3ef79e58, 0x3ec3e3be, 0x3d4e4d60, 0x3f50b567, 0x3e6be678, 0x3f463e1b, 0x3f6a34da, 0x3f1f2dd1, 0x3f1ccc19, 0x3e87800c, 0x3f305a79, 0x3b9ad580, 0x3f46943a, 0x3def1230, 0x3ef3bcb0, 0x3ed8abc8, 0x3f560325, 0x3da2e3d8, 0x3f370cca, 0x3eba530e, 0x3e20a1f8, 0x3e45f97c, 0x3edb8f50, 0x3e82c882, 0x3e29cd40, 0x3e88ff12, 0x3f6b4a53, 0x3e5c3df8, 0x3f131101, 0x3f64681b, 0x3f1a765a, 0x3dec0a60, 0x3ed95430, 0x3efe0a50, 0x3ef370ce, 0x3f5e58df, 0x3e5e6cbc, 0x3f21e634, 0x3f7a707f, 0x3ece85b2, 0x3e86eb6a, 0x3f454746, 0x3f4c0c0f, 0x3f774311, 0x3e13a5ac, 0x3f4b676d, 0x3f7c2b04, 0x3f2383a7, 0x3f75ea82, 0x3e02b694, 0x3f07cbba, 0x3f66b46f, 0x3f3cba22, 0x3de50fa8, 0x3dda54d0, 0x3f7e6bb7, 0x3ebc283e, 0x3f669e20, 0x3ebcc22a, 0x3ed48068, 0x3f6e57ba, 0x3f0e82d9, 0x3f1adb40, 0x3eaf97b0, 0x3e25b7a8, 0x3f6fa985, 0x3e443458, 0x3ca10900, 0x3c9317c0, 0x3f0260a1, 0x3e84a166, 0x3e4dc148, 0x3e958a98, 0x3eb75efc, 0x3f261269, 0x3ea3b3de, 0x3ebdad98, 0x3eb79c90, 0x3e5dd240, 0x3f53aa15, 0x3e6f350c, 0x3f17b9aa, 0x3f72c6e1, 0x3f554366, 0x3f296595, 0x3d9c2888, 0x3f47af71, 0x3cae2320, 0x3e932fec, 0x3ebe6b28, 0x3d7dd930, 0x3ed79088, 0x3e91fb4a, 0x3ece1b38, 0x3f0f2bb4, 0x3e5c4164, 0x3e458214, 0x3f78239d, 0x3efddbfa, 0x3ee7f49a, 0x3f4cdf09, 0x3e337188, 0x3f1466b1, 0x3eb1434a, 0x3de78d48, 0x3f1cc3a3, 0x3f00e0e5, 0x3e55763c, 0x3e82a3f0, 0x3f4b8499, 0x3e3719d8, 0x3f4211a3, 0x3f3aff13, 0x3d1ca000, 0x3f668513, 0x3ecd7990, 0x3f3ce6b0, 0x3ee89194, 0x3e825ce2, 0x3ee31ba4, 0x3ee91046, 0x3edd47ce, 0x3f723c6c, 0x3e860fe4, 0x3f024c5f, 0x3ef94040, 0x3f3194b7, 0x3e5c802c, 0x3f6aad09, 0x3f72d818, 0x3f0bfbed, 0x3f511cb4, 0x3f365213, 0x3f5faa57, 0x3db5dde8, 0x3ec7a944, 0x3f4b6844, 0x3e7e6b0c, 0x3e36d818, 0x3d70c5b0, 0x3eab8cfe, 0x3ed05dce, 0x3f691005, 0x3eb7cdfa, 0x3f6ab9f6, 0x3e2ebe40, 0x3f57e835, 0x3e5a4adc, 0x3e30116c, 0x3e18b34c, 0x3f536553, 0x3d58bc80, 0x3f326754, 0x3f3c8751, 0x3ec590cc, 0x3f7e3076, 0x3f2e3b1e, 0x3f10f414, 0x3f4786ad, 0x3f481efc, 0x3e4866d4, 0x3f015d2f, 0x3d2f6710, 0x3e4b5484, 0x3f740318, 0x3f46091e, 0x3f73b3d1, 0x3ca8cfa0, 0x3f7c01eb, 0x3f747219, 0x3eb9ba4c, 0x3f1276f4, 0x3f6c1f4e, 0x3f3aab14, 0x3e2c8170, 0x3f35994e, 0x3eaa01ee, 0x3e1cebb8, 0x3f611969, 0x3f4643db, 0x3f6a617f, 0x3f514489, 0x3f0a4a23, 0x3f764ae4, 0x3f2c6748, 0x3f56c6ac, 0x3f763b87, 0x3f0e1b99, 0x3d3e57c0, 0x3f56c4bb, 0x3eb551a2, 0x3f7fa8f0, 0x3efc0212, 0x3f678ac4, 0x3ec8cc8a, 0x3f4f855e, 0x3f2974d0, 0x3ecaa5ce, 0x3f37e2dd, 0x3e6ff598, 0x3f7933a6, 0x3f372480, 0x3db7be20, 0x3f1bee0e, 0x3e022cf4, 0x3eaa78c2, 0x3eeae1c6, 0x3f14aa90, 0x3efd21da, 0x3f611664, 0x3f56e65e, 0x3f6c08f4, 0x3ea216c8, 0x3f433e46, 0x3e5590a4, 0x3f1781a5, 0x3f099b7a, 0x3f1ae27a, 0x3f4fd0bb, 0x3ef14684, 0x3dd89030, 0x3f4f324a, 0x3eeb0542, 0x3edb9f22, 0x3e93ebb0, 0x3e66f1e0, 0x3f6970f1, 0x3e70e300, 0x3f3895e7, 0x3f597387, 0x3f0a9b1b, 0x3f3cc46b, 0x3f077686, 0x3ebd35bc, 0x3ef96736, 0x3dd0c998, 0x3dfd4988, 0x3f212a2b, 0x3eb7a320, 0x3b17b100, 0x3eb3c42a, 0x3f1582b1, 0x3f1c11b3, 0x3e8913fa, 0x3dbdeb30, 0x3df8fcb8, 0x3dc46af0, 0x3f352040, 0x3f589011, 0x3edc808c, 0x3e80d37c, 0x3d9236b0, 0x3e9f2e9e, 0x3f4d1f56, 0x3f08ccde, 0x3f34f622, 0x3e3d12cc, 0x3e223134, 0x3f44ff79, 0x3e6abc74, 0x3f144753, 0x3da02ee8, 0x3d764cb0, 0x3f2a681d, 0x3f3491f1, 0x3f0ba337, 0x3f6bd6ac, 0x3f12be1f, 0x3eaa3680, 0x3e553a74, 0x3f3d6fe9, 0x3f2611e3, 0x3f0463db, 0x3f1b3942, 0x3f5e14fd, 0x3c59a740, 0x3e2dd320, 0x3e8016e8, 0x3e9dd2ea, 0x3c22b540, 0x3d66d830, 0x3d0a2720, 0x3c96bce0, 0x3e843762, 0x3f61c34c, 0x3f127569, 0x3f64d6da, 0x3db25a28, 0x3ed2912e, 0x3f0f72b5, 0x3e0d5b28, 0x3dddbfd0, 0x3f21c60d, 0x3f23f63b, 0x3d6dda30, 0x3e85953a, 0x3f3c5bc9, 0x3d538620, 0x3f47704f, 0x3ea30326, 0x3f181936, 0x3f7fd50c, 0x3f530489, 0x3f7060a9, 0x3ee2e3fc, 0x3f044180, 0x3f3b70f7, 0x3f1f4a58, 0x3efd69da, 0x3f41cd24, 0x3e86283c, 0x3f3497e9, 0x3f3a71b3, 0x3eaa79c8, 0x3c131f00, 0x3f5ba1a1, 0x3f398f4f, 0x3f681381, 0x3de61d90, 0x3f1e5aae, 0x3f398ee4, 0x3f720039, 0x3f5d9df1, 0x3e442bbc, 0x3f1cc518, 0x3e920260, 0x3f511177, 0x3e6c3b04, 0x3f242e0c, 0x3f5c1cd5, 0x3f4eed1a, 0x3eec875c, 0x3ee452f6, 0x3e92b064, 0x3f3dfa7f, 0x3f3a4e23, 0x3ebfbc38, 0x3f22a1c9, 0x3f560a99, 0x3efff830, 0x3f7ff95d, 0x3efeceae, 0x3f78704e, 0x3f32e8de, 0x3f323d9c, 0x3f336afa, 0x3f178a2a, 0x3ea009d8, 0x3f483fce, 0x3f153090, 0x3f1c58d3, 0x3f0d2b3b, 0x3e809562, 0x3f255d6e, 0x3e2041ec, 0x3efff0f4, 0x3f7673c3, 0x3ee88ec8, 0x3f44190e, 0x3f0322d9, 0x3f1d55d4, 0x3e948cf0, 0x3e8534be, 0x3f7fe700, 0x3e69c60c, 0x3f2e0ebe, 0x3f6c03ae, 0x3d64f890, 0x3f146a56, 0x3e831b86, 0x3f6c3c3a, 0x3da9b8e0, 0x3eab7e4c, 0x3f603bf8, 0x3dfd1f68, 0x3f3a7662, 0x3f14a931, 0x3e98cbac, 0x3f2c15c3, 0x3ec342b8, 0x3f6f735d, 0x3f34e540, 0x3f3af08a, 0x3ee0eb1a, 0x3f0e338f, 0x3c8e3bc0, 0x3f28ebe0, 0x3e84250c, 0x3f13aa39, 0x3c61c100, 0x3f320917, 0x3f5e4614, 0x3f71c360, 0x3f48d744, 0x3f6cc4b8, 0x3e13ccb4, 0x3edf03c8, 0x3f670c60, 0x3dd16130, 0x3f583099, 0x3f4486fa, 0x3f24565a, 0x3df547f0, 0x3ec30c1e, 0x3f6f621d, 0x3ecd683c, 0x3f57bbd0, 0x3d2d3680, 0x3f10a4bd, 0x3f01f7f2, 0x3f501432, 0x3e25a45c, 0x3e864886, 0x3f48fe1f, 0x3f41e4d8, 0x3e23be98, 0x3f6f746f, 0x3f4ea9ed, 0x3f16a40d, 0x3f75d25b, 0x3eae07a2, 0x3f51766c, 0x3e8e9d3c, 0x3f60d151, 0x3f57ec87, 0x3efa1856, 0x3f2d3b5e, 0x3dafb860, 0x3db85348, 0x3f30155e, 0x3f59d2f3, 0x3ed13064, 0x3f029fd1, 0x3f5fc472, 0x3ed3041c, 0x3f0fcfa3, 0x3eaccfa4, 0x3ee427fa, 0x3e76d244, 0x3f2b864f, 0x3f654967, 0x3f3e733a, 0x3f60df6f, 0x3eac9918, 0x3e3524e8, 0x3f6cde8b, 0x3f7d9825, 0x3f2757ca, 0x3d37ee70, 0x3f7acfa9, 0x3e77aa98, 0x3e755d2c, 0x3ee84108, 0x3eb10a4e, 0x3f624610, 0x3e614f68, 0x3f5405b3, 0x3eee393a, 0x3f0e8e69, 0x3e06d1f8, 0x3e999c3a, 0x3df80670, 0x3f0ab050, 0x3efe2d26, 0x3ee8bc76, 0x3e9029bc, 0x3e1f1118, 0x3e954f74, 0x3f36d02f, 0x3f2f7c67, 0x3eeb9028, 0x3f2d43e7, 0x3f6b49e1, 0x3ee2bb78, 0x3f1bc70a, 0x3f21895a, 0x3f15c497, 0x3e98612c, 0x3efc8c6a, 0x3e54f3fc, 0x3e77f614, 0x3f1cf80a, 0x3f3beb10, 0x3f30d914, 0x3e9be6bc, 0x3ebf606c, 0x3f01c4c2, 0x3f7f623c, 0x3ec4ca68, 0x3e7636d8, 0x3f436c2b, 0x3eb0c2a2, 0x3efa261c, 0x3f200bea, 0x3de9b0b0, 0x3dfcff90, 0x3f5b7881, 0x3f693652, 0x3f2a5ae5, 0x3e52a3c8, 0x3ef8840c, 0x3f5ac69c, 0x3f0f4988, 0x3e8f3aae, 0x3d385340, 0x3e85b5c2, 0x3f46a618, 0x3e3c46b4, 0x3e113e64, 0x3f0b9306, 0x3e8a0b80, 0x3f48e8e7, 0x3dc768d8, 0x3f272abb, 0x3e8d5b7c, 0x3ef5aa78, 0x3f50361d, 0x3f7769dc, 0x3f77e957, 0x3f6c763e, 0x3e66579c, 0x3ee5f23a, 0x3d677940, 0x3d2f6c00, 0x3f2daff7, 0x3f077be5, 0x3f2d9ce3, 0x3e0924f0, 0x3f16ebc5, 0x3dbe7a68, 0x3f3c5b2a, 0x3f4ffcb0, 0x3cfa0760, 0x3f2f6364, 0x3f46d903, 0x3dcd8e50, 0x3f3df586, 0x3ebc4bca, 0x3e6d0a14, 0x3f52aa2c, 0x3f3573f4, 0x3f633133, 0x3f58229d, 0x3d8cda18, 0x3c9352c0, 0x3efa765c, 0x3f33bfca, 0x3e46c45c, 0x3f703e85, 0x3e8592e6, 0x3efd79f6, 0x3ec3d824, 0x3f2be1ce, 0x3f47fee3, 0x3e8f1ba0, 0x3eb138f2, 0x3f740733, 0x3f2d475b, 0x3e862a0a, 0x3e9a2daa, 0x3f21946d, 0x3e564fa8, 0x3f291afc, 0x3f04b722, 0x3f127996, 0x3f4c846a, 0x3f4ced47, 0x3e4c3bd4, 0x3f0d3585, 0x3ee064ce, 0x3f3e2443, 0x3ef5def4, 0x3ba20000, 0x3f383b0f, 0x3f3b2372, 0x3f23e5bc, 0x3e13ac30, 0x3eaf03fa, 0x3f4a22ba, 0x3f76bc54, 0x3e389b38, 0x3f410ba1, 0x3f6a336c, 0x3f5a8d80, 0x3ca3a940, 0x3f51a407, 0x3ec6d6c8, 0x3f3bd982, 0x3e7f5800, 0x3f7c3988, 0x3e31fcb0, 0x3f2b0471, 0x3f63f395, 0x3e71851c, 0x3f0048a0, 0x3e97dc4c, 0x3e53adf8, 0x3dd20ed0, 0x3da668a0, 0x3f2014d9, 0x3eddf04c, 0x3f5ccc7b, 0x3e23011c, 0x3ed57f9c, 0x3c3ae140, 0x3e945d80, 0x3efaecf8, 0x3dbd3af8, 0x3e1016b4, 0x3f2f15e9, 0x3eabbafc, 0x3f195dde, 0x3f7f98c4, 0x3df5f4d8, 0x3f4b85a3, 0x3f709498, 0x3d547530, 0x3ea4f138, 0x3f008bd8, 0x3f0238e0, 0x3d8bf808, 0x3e82c1e4, 0x3ec9f61c, 0x3eface24, 0x3f667ede, 0x3f6be85d, 0x3e83a310, 0x3f4bd848, 0x3f54fa2e, 0x3f2297dc, 0x3e0badd0, 0x3f05ecad, 0x3d0391b0, 0x3f498876, 0x3efd1096, 0x3ef6071e, 0x3ed7f250, 0x3f5fa873, 0x3e9abed6, 0x3ec8276a, 0x3f21602e, 0x3da602c8, 0x3c880fc0, 0x3f4c880d, 0x3eff0c3a, 0x3d2a8100, 0x3f116087, 0x3e0df66c, 0x3e5ea110, 0x3f500cd7, 0x3f2b0de5, 0x3f3b00ba, 0x3e201a14, 0x3eb102ba, 0x3f65e38a, 0x3f2cae99, 0x3e77fc98, 0x3f41727f, 0x3e7ebe48, 0x3e48ea6c, 0x3e5d3b70, 0x3c8b90a0, 0x3f16a40f, 0x3dd3a640, 0x3f0efb14, 0x3ce40dc0, 0x3f4b2b1d, 0x3df14440, 0x3f3e342b, 0x3f63b8bc, 0x3f6fed88, 0x3deaff38, 0x3e7f4a40, 0x3db4b090, 0x3f67b32b, 0x3ef0d598, 0x3e091444, 0x3e93bdfa, 0x3f6921d4, 0x3f1deac9, 0x3ece6476, 0x3dff8118, 0x3f543339, 0x3e3c701c, 0x3ee65820, 0x3f142426, 0x3e246830, 0x3f0b1ba5, 0x3e46c48c, 0x3f3dd169, 0x3ec4c396, 0x3f11ddf2, 0x3f4e810c, 0x3f47d649, 0x3d898da8, 0x3f352aaa, 0x3f774f54, 0x3cf165e0, 0x3ea3cf54, 0x3f04a59b, 0x3f1823fc, 0x3c866480, 0x3ed64912, 0x3f21c63d, 0x3cb0e280, 0x3de75608, 0x3f5b635f, 0x3eef44a4, 0x3f5bf695, 0x3e5004ec, 0x3e9e49ac, 0x3e6cb4f0, 0x3f13e360, 0x3ee84642, 0x3f170a7e, 0x3c98b440, 0x3ed8434e, 0x3f4b6a8d, 0x3f4e1c12, 0x3f017445, 0x3f602c52, 0x3f1d98ab, 0x3f1c39e0, 0x3f36b91e, 0x3f099460, 0x3f3f473c, 0x3eaa309c, 0x3ef40028, 0x3f614cb0, 0x3f51f29d, 0x3edc5382, 0x3e9817ba, 0x3eebfaee, 0x3dfe9798, 0x3f513324, 0x3f2f18bc, 0x3f1eaee4, 0x3f7ec9cf, 0x3e9a5f6e, 0x3f02c823, 0x3e926c4e, 0x3f52e716, 0x3f1f4e7f, 0x3f4699de, 0x3e5e306c, 0x3f37202a, 0x3f67b6c3, 0x3ec800ec, 0x3ebc5468, 0x3c4cb380, 0x3d8713f8, 0x3caa03c0, 0x3f2f2036, 0x3f3b96be, 0x3f1da0bb, 0x3f162c47, 0x3edf0b52, 0x3ef739c6, 0x3f20fc82, 0x3f23c33f, 0x3f07db38, 0x3f3c6951, 0x3f7d9df3, 0x3f6716d5, 0x3e0a1e28, 0x3f1643ac, 0x3d48e910, 0x3ef0e90c, 0x3f12d5c9, 0x3f6e4c6f, 0x3ed4912a, 0x3f722240, 0x3f5df927, 0x3f2566e8, 0x3f2ec523, 0x3e969378, 0x3f2db7d4, 0x3e9bedd0, 0x3d083d30, 0x3eeabfbc, 0x3ec5ff7e, 0x3ea059f6, 0x3eb4bbae, 0x3f616a75, 0x3f28ff1f, 0x3f413800, 0x3ee24bee, 0x3e72c494, 0x3f363b25, 0x3e9bda30, 0x3de09550, 0x3e1883f4, 0x3f5a9853, 0x3df29198, 0x3f3bc2f9, 0x3f66ab27, 0x3ece770e, 0x3f0fa0ea, 0x3d6d73a0, 0x3e83c22e, 0x3e1ad670, 0x3ed5d654, 0x3f3ab35e, 0x3f791af7, 0x3ef7a014, 0x3f53a835, 0x3f67b69e, 0x3f605bb0, 0x3f2e9544, 0x3f4bc5da, 0x3ddfb1a8, 0x3f5a50e0, 0x3f0d3923, 0x3eac19d4, 0x3f614842, 0x3ccd6160, 0x3e63bb00, 0x3eac9742, 0x3eeef5e6, 0x3f0a7bb0, 0x3ea15e76, 0x3f41d738, 0x3f5d7a96, 0x3f102db6, 0x3eeca428, 0x3f7019ee, 0x3f274fc1, 0x3f106608, 0x3f4187e6, 0x3e4cb700, 0x3eec45e2, 0x3ee9acc4, 0x3f393026, 0x3eb3c5b8, 0x3e55a6ac, 0x3ed7f8e8, 0x3ee304cc, 0x3eeaf74e, 0x3d190800, 0x3f518a7e, 0x3f342f7e, 0x3f51e039, 0x3eaa4dde, 0x3e944224, 0x3e5737d8, 0x3f50cb33, 0x3f4ddbc8, 0x3f4fbe94, 0x3f12d4b3, 0x3f5bbdde, 0x3f426e0c, 0x3f44b4f7, 0x3e54832c, 0x3ed3b7a6, 0x3ebbaea0, 0x3f43590d, 0x3f16857b, 0x3e2dd944, 0x3f3a245d, 0x3dcede78, 0x3f67a2d8, 0x3ec786ea, 0x3ed5cd6a, 0x3e0cc294, 0x3db674e0, 0x3ef709a2, 0x3ea8623e, 0x3ebbbcfa, 0x3ebd075c, 0x3f12e024, 0x3ed05d68, 0x3e821974, 0x3d28b000, 0x3f723c1b, 0x3f32a521, 0x3f6c2ffb, 0x3f145080, 0x3f1e5875, 0x3f7ee410, 0x3f4da8b3, 0x3f59e2d9, 0x3e767498, 0x3eec5f82, 0x3f74ecf3, 0x3f4b9316, 0x3f67ba98, 0x3f5ef6a7, 0x3f5726e4, 0x3e8e00a2, 0x3f031959, 0x3e1380ac, 0x3e722d8c, 0x3f483aea, 0x3f01ca43, 0x3e207030, 0x3ecf009e, 0x3f6513de, 0x3e9f542e, 0x3f23e5d6, 0x3ec9f980, 0x3ec0a858, 0x3edbf588, 0x3d846290, 0x3e3065c8, 0x3ddfe360, 0x3e5e9414, 0x3e6a7f7c, 0x3ef7a910, 0x3e809ff6, 0x3e0634e0, 0x3f49b10d, 0x3f4c9395, 0x3e257acc, 0x3f1da635, 0x3e76b5c8, 0x3ee3c3ae, 0x3e903e0e, 0x3f2ecd34, 0x3f23b2e3, 0x3efc3bae, 0x3f153f7e, 0x3ef5b9cc, 0x3f492e81, 0x3d7e3ba0, 0x3f27bf69, 0x3d352820, 0x3f22bf1e, 0x3e7e2248, 0x3e19b688, 0x3f59b74c, 0x3dcf0850, 0x3f751ea5, 0x3e9784f2, 0x3eb03d4a, 0x3f29ea13, 0x3e96fda6, 0x3e973df2, 0x3e55e8b8, 0x3ea99e82, 0x3f0ab311, 0x3ef8b48e, 0x3d5c8aa0, 0x3e5afaf0, 0x3f7d1f59, 0x3e6d6098, 0x3ecdbb70, 0x3f5caa96, 0x3f09f986, 0x3e91acd2, 0x3eef4158, 0x3f621726, 0x3de9ad60, 0x3f0dfa1f, 0x3f648800, 0x3f0b34ac, 0x3ef10064, 0x3f3e5453, 0x3f6945f9, 0x3f3f1ca2, 0x3f728858, 0x3e4e1a4c, 0x3f3ee4a5, 0x3f0b496a, 0x3eaa8d1c, 0x3d0ac270, 0x3e65b030, 0x3f7c843d, 0x3e8f817e, 0x3f06f535, 0x3f15fb72, 0x3f269adc, 0x3f212037, 0x3f2645b2, 0x3f0132d6, 0x3f07f69b, 0x3f3d3e7b, 0x3c08a240, 0x3f2fcfda, 0x3f319dba, 0x3ea14dac, 0x3ec52376, 0x3d295380, 0x3d2ec5e0, 0x3f42613f, 0x3f240e75, 0x3e1a82d4, 0x3e8c0a1c, 0x3eded670, 0x3b6f8700, 0x3e1a18ec, 0x3e2e1cf0, 0x3f50749b, 0x3f7344d2, 0x3decf740, 0x3e0ea45c, 0x3d6bd740, 0x3efa76f4, 0x3f5d8683, 0x3e9bfdda, 0x3f6f9a3d, 0x3e9544ce, 0x3e499b28, 0x3d896360, 0x3f39f9c7, 0x3e4494b8, 0x3e8ad98e, 0x3f210a7b, 0x3edff444, 0x3e6b664c, 0x3f7d3c8a, 0x3ee675e8, 0x3f577b63, 0x3f10e622, 0x3e6e8158, 0x3f36f6e6, 0x3f40c951, 0x3f276d71, 0x3f081dc8, 0x3eb4944c, 0x3f551eb2, 0x3de54648, 0x3f6c21e5, 0x3d94f1a8, 0x3e931b0c, 0x3f2f6149, 0x3cf02720, 0x3f702f0d, 0x3ec4e20c, 0x3f22fc7d, 0x3f338426, 0x3d186c70, 0x3f52b64e, 0x3f35da4e, 0x3f600a27, 0x3ef3cd62, 0x3dceb1b8, 0x3f73e064, 0x3ebb3e40, 0x3f080b45, 0x3f205635, 0x3e8903a2, 0x3ea2dd12, 0x3e6e3c5c, 0x3f606cdb, 0x3f03a4f3, 0x3effbf00, 0x3f101011, 0x3ee0c556, 0x3e9500c8, 0x3cc977e0, 0x3ea7abda, 0x3f5f2f83, 0x3f0cc395, 0x3f7b7b06, 0x3f046580, 0x3ee6f630, 0x3f1598f3, 0x3de3f398, 0x3c9258a0, 0x3d82fcf8, 0x3e9df156, 0x3e26fc7c, 0x3f34f4f1, 0x3ef6e51e, 0x3f3c3011, 0x3f2f7b3e, 0x3f2f77a8, 0x3c391300, 0x3e98f174, 0x3e8bdefc, 0x3f30c783, 0x3f7e96c6, 0x3ee68bcc, 0x3f34f143, 0x3e829ce8, 0x3f7e51ec, 0x3e599c8c, 0x3ec88726, 0x3f3e3fbc, 0x3f6fd35a, 0x3ec13da6, 0x3ee144a0, 0x3f286fb7, 0x3e6fd0b0, 0x3ed9cc4c, 0x3ea2d060, 0x3e955556, 0x3f2d06cf, 0x3e720e38, 0x3e2fd8ac, 0x3e9d9a9c, 0x3ea6b2ae, 0x3de723e0, 0x3f5a8c80, 0x3f5f3173, 0x3ecc026e, 0x3f114ce9, 0x3e8c8674, 0x3df6e308, 0x3f42c120, 0x3e8db458, 0x3f67cd9e, 0x3f30eaed, 0x3d64dc00, 0x3ea9c648, 0x3e9b1c00, 0x3f2dd324, 0x3e3b5bbc, 0x3f4504a5, 0x3f5c1b0a, 0x3f55056c, 0x3f031a8b, 0x3f295404, 0x3f79fe7e, 0x3f004533, 0x3f02251d, 0x3f552ee3, 0x3e92b6e8, 0x3ebc8276, 0x3f3b09a9, 0x3d832f88, 0x3d883ec8, 0x3f39313c, 0x3f79229e, 0x3f29359d, 0x3f2a06a1, 0x3f72c6d9, 0x3e472458, 0x3f3e730e, 0x3e7e72e0, 0x3f4a247a, 0x3f3d4c9c, 0x3f7548eb, 0x3f06acff, 0x3f38e4a1, 0x3f05bcf8, 0x3f4fec3e, 0x3f6ee7ac, 0x3f4ae502, 0x3f79fa3f, 0x3f74cb35, 0x3f77b600, 0x3f0ebe64, 0x3e1dab58, 0x3f3a0bb6, 0x3f7c8f45, 0x3ec8cb28, 0x3f1b8b9d, 0x3ed94b06, 0x3ecea096, 0x3f54fe0b, 0x3ea5ea86, 0x3f56c7ee, 0x3e8115f6, 0x3f5cb782, 0x3e03f00c, 0x3f070772, 0x3ecff4dc, 0x3ed39aa0, 0x3f1c8d73, 0x3f60bb81, 0x3e7fdbb8, 0x3f09dcec, 0x3e07d3f0, 0x3f645836, 0x3da27348, 0x3ea00164, 0x3f356582, 0x3efeae18, 0x3e8f9a26, 0x3f4f505e, 0x3f29a161, 0x3f12258e, 0x3f69c2b3, 0x3d874650, 0x3f1f6a46, 0x3f00ff2a, 0x3de7d058, 0x3ed437ee, 0x3f2c6f5b, 0x3ed248d6, 0x3e60a4cc, 0x3f3e748e, 0x3f600b31, 0x3f3d84e6, 0x3ec4d5cc, 0x3f4bafee, 0x3e386644, 0x3e318dc8, 0x3eb17c54, 0x3e31e274, 0x3e8983d4, 0x3ef7f19e, 0x3f79fd37, 0x3f46ab95, 0x3ef4fa0a, 0x3e45ff94, 0x3e29b3e8, 0x3bdda000, 0x3e4c0640, 0x3e5cbc1c, 0x3ecfe312, 0x3ece25ca, 0x3f1ed6e3, 0x3f2912cb, 0x3b579900, 0x3e69f2e4, 0x3d2799b0, 0x3f69ddbd, 0x3dc83ab8, 0x3f26740b, 0x3f6cc1fc, 0x3ea15e64, 0x3f6e6eae, 0x3f1a2698, 0x3f669642, 0x3f2ffa0f, 0x3f70c1e2, 0x3f5ee0b9, 0x3f48f8ab, 0x3f2a2697, 0x3ef3d882, 0x3f3147a7, 0x3f3024b6, 0x3e1b1a84, 0x3f5c060f, 0x3f30a1d8, 0x3f0d2dc0, 0x3f3a2052, 0x3edd3952, 0x3f5dbf09, 0x3f73ddbf, 0x3f796f28, 0x3e79afd8, 0x3f4303b6, 0x3e591f44, 0x3f435101, 0x3f7b47a3, 0x3e846f08, 0x3e94f9f0, 0x3f2ab23d, 0x3f113f6c, 0x3f706bc8, 0x3f74e40a, 0x3ef13f1c, 0x3f2a33b6, 0x3e6584e0, 0x3f032998, 0x3eb39b0a, 0x3f364f87, 0x3f339940, 0x3f18226c, 0x3e8a80e0, 0x3e821214, 0x3f06546e, 0x3f268e0e, 0x3f0b5f1b, 0x3f3fe2bf, 0x3f5b0d6c, 0x3f729e72, 0x3d2562c0, 0x3d0ca500, 0x3f68fc82, 0x3f5366e4, 0x3f3568ef, 0x3e87fad4, 0x3f75729b, 0x3f24e8a3, 0x3d6abaa0, 0x3e294464, 0x3ee48360, 0x3cd4a340, 0x3f079096, 0x3f04b48a, 0x3eccbce8, 0x3f74479d, 0x3f5798f2, 0x3f177ffb, 0x3f468703, 0x3ede83d8, 0x3e33576c, 0x3f079f61, 0x3ebbedf4, 0x3ef9986e, 0x3f1ee33b, 0x3f100c86, 0x3f1d754f, 0x3dacc6d0, 0x3ea3ee3e, 0x3f6148f7, 0x3e59ebe0, 0x3eb57436, 0x3f36b9d7, 0x3f48a837, 0x3eb09c80, 0x3f4af664, 0x3e62ef4c, 0x3f780af1, 0x3e594e4c, 0x3e5f4328, 0x3f667cf8, 0x3f01ad7c, 0x3ed7d95e, 0x3ee471de, 0x3f6f8cc3, 0x3f626796, 0x3e2bb88c, 0x3eb539bc, 0x3e9d1e70, 0x3d04af60, 0x3f0dc769, 0x3e8509ea, 0x3f2d3dca, 0x3f0eaf70, 0x3f14c9cb, 0x3f1d0796, 0x3d2e9980, 0x3e91e186, 0x3ef9dea2, 0x3eaf3da4, 0x3ee2b866, 0x3f74d4df, 0x3c97ad20, 0x3f3501e4, 0x3eb685bc, 0x3f683e80, 0x3f3064eb, 0x3e4850c8, 0x3f299c76, 0x3f7a2df3, 0x3d9d8918, 0x3f2e0403, 0x3ee87888, 0x3ee1c118, 0x3f20afd2, 0x3e0a36a0, 0x3f4f002e, 0x3f2004be, 0x3ec0ea64, 0x3ee5e8fe, 0x3e3b0098, 0x3f360ae8, 0x3f2f745a, 0x3de86310, 0x3f172288, 0x3d0bdb90, 0x3f2dc56c, 0x3dd51778, 0x3f4c2f67, 0x3f7d1f1c, 0x3f697864, 0x3f2b0d22, 0x3f53298b, 0x3f69653e, 0x3f65295a, 0x3e8a03fe, 0x3e0ec28c, 0x3e2d7d60, 0x3f5fc080, 0x3ef7bc34, 0x3ddf8a60, 0x3f59eeff, 0x3f353235, 0x3ebd4fe2, 0x3edc9062, 0x3f485eb6, 0x3f4a01a5, 0x3ef23f14, 0x3dd82e78, 0x3eab4254, 0x3eacd2da, 0x3e483ad0, 0x3f17ab53, 0x3f794651, 0x3f5e7411, 0x3f4a7dce, 0x3f2e1c71, 0x3f26887f, 0x3eb9448c, 0x3ec6bc90, 0x3f2d4776, 0x3d30df00, 0x3e621c80, 0x3f674051, 0x3da442d0, 0x3f01afbd, 0x3da56ea8, 0x3f1b26d0, 0x3d3b1de0, 0x3f463b7c, 0x3f5c5a36, 0x3e82972a, 0x3f6cb23b, 0x3f4f466e, 0x3ec2e70a, 0x3f5856e9, 0x3f0e5043, 0x3f2429af, 0x3f4d2142, 0x3f3882b1, 0x3f0f5c7d, 0x3f597aa7, 0x3f50529a, 0x3dab32d8, 0x3f6e5fdb, 0x3e81cd28, 0x3f26a4f2, 0x3ec57b76, 0x3ebc7f04, 0x3f62884e, 0x3f0bea47, 0x3f1a8299, 0x3f640dfd, 0x3db05d48, 0x3efc1a52, 0x3f753998, 0x3dc9acd0, 0x3f2c5310, 0x3edb896c, 0x3f0f220d, 0x3f624244, 0x3e82dea4, 0x3f1cc000, 0x3f6d70f2, 0x3e40a000, 0x3de915d0, 0x3ea79dd6, 0x3f6c3322, 0x3f3a5260, 0x3f2fafe6, 0x3f0220ba, 0x3c442f00, 0x3ead4e94, 0x3f5e0bef, 0x3f31c108, 0x3f0758ae, 0x3f23a01b, 0x3f357fc9, 0x3ec12ce6, 0x3f71ebfa, 0x3f54693f, 0x3e498b00, 0x3f76fe33, 0x3f5c7f35, 0x3e1a0d8c, 0x3be7bb80, 0x3ea85f74, 0x3f3501f1, 0x3f564dea, 0x3f1c1785, 0x3f54121f, 0x3dd2fe98, 0x3eaf108e, 0x3f137b55, 0x3d38b7a0, 0x3d8d7ad8, 0x3f0682c8, 0x3b82b780, 0x3ed94374, 0x3f6a6d68, 0x3f1947be, 0x3f09945e, 0x3f12a126, 0x3f211a5c, 0x3a417000, 0x3f73859c, 0x3f45166e, 0x3f5ebe59, 0x3f4bcb13, 0x3e9c5f96, 0x3f75736f, 0x3f51c1c5, 0x3ea9ee7a, 0x3f10e063, 0x3db5d480, 0x3f160ed2, 0x3f7cc91b, 0x3f10cd60, 0x3f3bf56b, 0x3dd68df8, 0x3d9faa98, 0x3f51ab40, 0x3f0c3d4d, 0x3e460d30, 0x3eed3cbc, 0x3ecc0972, 0x3d93c318, 0x3f2ee9a6, 0x3f085594, 0x3f78f9dc, 0x3e961498, 0x3e1e79c0, 0x3f25770f, 0x3f007cea, 0x3e5cfafc, 0x3dd02650, 0x3e91ff76, 0x3f07e6a2, 0x3eb84a80, 0x3f2cdfef, 0x3e22a594, 0x3eea89f0, 0x3f492e26, 0x3e85078e, 0x3f5bbaef, 0x3eb3905a, 0x3f54cc91, 0x3e93bf94, 0x3f6a45ae, 0x3cc7ade0, 0x3f549dbc, 0x3f0bb524, 0x3f418b70, 0x3f51f4fb, 0x3f70a11f, 0x3f21af9d, 0x3e3d5918, 0x3de43008, 0x3f028458, 0x3f6a153a, 0x3f14d2f6, 0x3ebb065e, 0x3f0f8d0e, 0x3e54b0a0, 0x3f26c7d4, 0x3e283e68, 0x3ef86164, 0x3d2a2ac0, 0x3e24efec, 0x3f5e896c, 0x3edb8888, 0x3f2bb5b7, 0x3f4e5a25, 0x3f7129ea, 0x3f30e0a6, 0x3e42d17c, 0x3f418e0c, 0x3f656084, 0x3f653727, 0x3eb9f338, 0x3f0c8312, 0x3f6ad76b, 0x3c6202c0, 0x3e21bfd0, 0x3eed70d8, 0x3d8ed008, 0x3f173534, 0x3f486671, 0x3d2b60a0, 0x3e89b5f6, 0x3eb618e6, 0x3f2ce2fa, 0x3f1381de, 0x3f1d9160, 0x3e9a7c70, 0x3db77628, 0x3e40f778, 0x3f69f880, 0x3f00cf19, 0x3f23b598, 0x3f08174d, 0x3ea918a8, 0x3f37c571, 0x3e820f62, 0x3d9b0ad8, 0x3f6d08c0, 0x3f7e543a, 0x3e8ce988, 0x3d861c00, 0x3d9b1840, 0x3eedd152, 0x3e485274, 0x3e6e882c, 0x3f595212, 0x3f2d1eb1, 0x3ee28b92, 0x3f393f6c, 0x3e5e0ef8, 0x3e2c3a80, 0x3f0e7d9c, 0x3d9d3400, 0x3f7c9d2b, 0x3e66c4e8, 0x3f1009f7, 0x3e7bf370, 0x3e87f8d0, 0x3f788965, 0x3f7e73a4, 0x3f7c8526, 0x3dfb2360, 0x3f02793c, 0x3e070eec, 0x3cdc3e20, 0x3f32d2dc, 0x3f098e7b, 0x3e4a9388, 0x3f00bbcb, 0x3f17cf5c, 0x3e4ecfdc, 0x3ec449ba, 0x3eb8c960, 0x3ef8abde, 0x3e24469c, 0x3f170541, 0x3edbb978, 0x3f4d6120, 0x3ef277ae, 0x3f4e43f2, 0x3ec9478a, 0x3e6e5808, 0x3ebde8d6, 0x3f082d70, 0x3e87f052, 0x3e29bfb0, 0x3eda91e2, 0x3f202a5d, 0x3ed63c34, 0x3f0fa677, 0x3f0775e8, 0x3ea35558, 0x3dc8b398, 0x3e2002bc, 0x3e697b90, 0x3f19a280, 0x3ec93b6c, 0x3e44b508, 0x3ea13342, 0x3c90ad40, 0x3ed610d2, 0x3e87b876, 0x3eda1da8, 0x3f64ea12, 0x3c29b900, 0x3e4cb500, 0x3e294f00, 0x3e936792, 0x3f73d94b, 0x3da75668, 0x3cd397a0, 0x3d369470, 0x3c97c5e0, 0x3e6d00a8, 0x3f4f6edb, 0x3efa83ea, 0x3f5bad61, 0x3f514571, 0x3ca64680, 0x3eae2800, 0x3ef8ceaa, 0x3f6370c8, 0x3f440ca1, 0x3f7a74c5, 0x3f65d024, 0x3f1767f7, 0x3dd46c08, 0x3f6f9204, 0x3f5e1606, 0x3f6ab19b, 0x3f1f20d7, 0x3f06952e, 0x3d5fb890, 0x3ed6ba26, 0x3f0ad89e, 0x3e740f08, 0x3f7428e9, 0x3f1b0d20, 0x3daba2b0, 0x3e172e24, 0x3a779800, 0x3efbf780, 0x3f0fc439, 0x3f6f80fd, 0x3ed131e4, 0x3ec6e8ba, 0x3f5cb35b, 0x3e615610, 0x3eab48c6, 0x3f0ac3db, 0x3c813180, 0x3f6a6240, 0x3f58f98e, 0x3ea44696, 0x3edb1334, 0x3f47e4a5, 0x3f4de0e1, 0x3edbf24c, 0x3d544610, 0x3f2426aa, 0x3cd486e0, 0x3ed9ccd4, 0x3d640b00, 0x3f620ff1, 0x3e9f4fb4, 0x3f6bc59f, 0x3f74ab39, 0x3e0ab1f0, 0x3f11b2b5, 0x3f65e216, 0x3eb0b7c6, 0x3f2c35dc, 0x3f5321d2, 0x3f3d4365, 0x3f6b1eee, 0x3f38c399, 0x3ec4deae, 0x3f0f7454, 0x3e91c52a, 0x3f7bf797, 0x3f5aa345, 0x3e62886c, 0x3f3a35d4, 0x3ecbf950, 0x3f214f6e, 0x3f4c49e8, 0x3f322e38, 0x3e3caa44, 0x3ea79586, 0x3f360305, 0x3f5223fc, 0x3f085114, 0x3f10d3bb, 0x3e8da57a, 0x3ed097ac, 0x3ede38c8, 0x3e898dfa, 0x3ed10910, 0x3f33ba5c, 0x3d8475d0, 0x3f4bf145, 0x3daf4e18, 0x3e4975f8, 0x3d73ea90, 0x3f6b831d, 0x3d4b8f60, 0x3f39970d, 0x3f0a2217, 0x3e2c9714, 0x3f62858e, 0x3d02c820, 0x3f2f9d59, 0x3eae793e, 0x3f6cc09d, 0x3c3a98c0, 0x3f5c15c0, 0x3f17a57d, 0x3e1401d8, 0x3f2372f3, 0x3f599774, 0x3f7d5836, 0x3f1a7a50, 0x3e487078, 0x3eda58ec, 0x3f5ed2cf, 0x3eea7eba, 0x3f023c54, 0x3eea7fea, 0x3f6f4922, 0x3f1f446b, 0x3e9ed28a, 0x3e38c488, 0x3edde92a, 0x3f3a1bd0, 0x3f41363a, 0x3f469bcb, 0x3eed8668, 0x3e9badae, 0x3f0b67fc, 0x3e42a6cc, 0x3e2b63c4, 0x3f68f9c6, 0x3ba62880, 0x3ef6f17a, 0x3e035950, 0x3f513d0f, 0x3e91a298, 0x3d7e5440, 0x3f439366, 0x3e98604c, 0x3f6137ec, 0x3dc44c58, 0x3f199655, 0x3e90b53c, 0x3f3cf9df, 0x3e8cdb66, 0x3c7f9cc0, 0x3f7e21b0, 0x3ec2df98, 0x3e3c6a20, 0x3f682873, 0x3f492deb, 0x3f63bda8, 0x3e7dae2c, 0x3d8e8280, 0x3f18eb3c, 0x3f798158, 0x3d366370, 0x3e3c25dc, 0x3e79ed0c, 0x3e8a14ae, 0x3d23e8f0, 0x3f442f56, 0x3ee36cc0, 0x3f375a0e, 0x3f0cfd62, 0x3f41deca, 0x3f371e13, 0x3f7df3b9, 0x3f641d47, 0x3eff708a, 0x3eb5ac70, 0x3eeb1ea0, 0x3f2dd090, 0x3f5b1711, 0x3f2c9c50, 0x3c9b5d00, 0x3f21ce76, 0x3f0b3455, 0x3e721780, 0x3debd3d8, 0x3ee69ad0, 0x3f6a3e92, 0x3e44370c, 0x3cd70b20, 0x3f67e35c, 0x3ebec97c, 0x3f5f8319, 0x3f4b96a2, 0x3eaf1298, 0x3e4e204c, 0x3eaf0214, 0x3d2d3440, 0x3e56d6b8, 0x3f217618, 0x3f047754, 0x3f3ce9e2, 0x3f791eba, 0x3f3da46b, 0x3f0cf931, 0x3f3b2bca, 0x3eaebb44, 0x3f2c2f97, 0x3f7a789d, 0x3f498bd1, 0x3f7e30b0, 0x3d0fb0e0, 0x3ebad65a, 0x3e0cd240, 0x3e18fb34, 0x3e99995a, 0x3f031f8e, 0x3f2074ca, 0x3efe0d1e, 0x3e7ba5b0, 0x3f789ea7, 0x3e81216c, 0x3d150440, 0x3f31c10f, 0x3f1c1ff7, 0x3e7aaa80, 0x3f5d13e3, 0x3f7562bf, 0x3e002ef8, 0x3f548e97, 0x3f43d011, 0x3f6cbe41, 0x3e1dd5c4, 0x3f0455e9, 0x3d7a8840, 0x3bffb480, 0x3f4a53cc, 0x3d6d95a0, 0x3dbf4398, 0x3e1f5d18, 0x3e73f26c, 0x3efc6682, 0x3f49593a, 0x3f20560d, 0x3e6684ac, 0x3f1c2fec, 0x3f2928fd, 0x3f62c2be, 0x3e86282e, 0x3f10711e, 0x3f72c1ba, 0x3cb91760, 0x3e891758, 0x3e05b87c, 0x3e32b134, 0x3f5300a3, 0x3f72a7eb, 0x3ce5daa0, 0x3f05dc44, 0x3e389e00, 0x3ea3a2c6, 0x3f323be9, 0x3f41aa86, 0x3e56f618, 0x3c152180, 0x3f74b62c, 0x3d6b5cf0, 0x3d80c960, 0x3f704c6a, 0x3d903960, 0x3ece4754, 0x3f1b0eb6, 0x3dd1c908, 0x3d4aa1f0, 0x3e6c8818, 0x3e7bac78, 0x3f31e5fb, 0x3ecae886, 0x3f3fb539, 0x3f40c8a9, 0x3f21b7b3, 0x3f3f1634, 0x3f35d098, 0x3e653504, 0x3e4b3124, 0x3c0bee00, 0x3e768770, 0x3f4c8996, 0x3f6bad38, 0x3f14dcf6, 0x3ef6198e, 0x3e21a758, 0x3e981052, 0x3ea62be0, 0x3f3b0534, 0x3f11f168, 0x3f487ab5, 0x3e47f804, 0x3f26b6cd, 0x3e791c58, 0x3e00e8bc, 0x3f6899fd, 0x3f6541f4, 0x3d5b9fe0, 0x3e389b90, 0x3f2b13aa, 0x3f4d9730, 0x3eca8a50, 0x3f278121, 0x3f39e2ff, 0x3f3e4aa6, 0x3f400835, 0x3e130ddc, 0x3f35d27b, 0x3ecc9640, 0x3f69018f, 0x3f0082f1, 0x3f452131, 0x3ed5793e, 0x3f419e18, 0x3eb9201e, 0x3e2f867c, 0x3dc4b4a0, 0x3d9042d0, 0x3f420e18, 0x3f2a985f, 0x3f5b1303, 0x3ee870fc, 0x3eaaa0e2, 0x3f465da8, 0x3f67e8d4, 0x3e31306c, 0x3e974a36, 0x3e9aa284, 0x3eae3e36, 0x3e56dfdc, 0x3f1246ef, 0x3f2efa26, 0x3f47c8a5, 0x3ef8259a, 0x3f1383d5, 0x3f68cb4d, 0x3f33b5ed, 0x3ed86a62, 0x3f41b36e, 0x3f115e00, 0x3f3af463, 0x3ee41e10, 0x3f473c66, 0x3e261b4c, 0x3e8d4fb2, 0x3f159f00, 0x3e508c38, 0x3f32392f, 0x3f7e21b6, 0x3ea3b734, 0x3f005931, 0x3d6700a0, 0x3e51df88, 0x3ef213fa, 0x3f5f7884, 0x3ebac918, 0x3f2e4c2f, 0x3f25a310, 0x3e95f6e4, 0x3f384f8c, 0x3ea1734c, 0x3ed012aa, 0x3ddd03c8, 0x3ede75f0, 0x3f441bf2, 0x3e8a57b0, 0x3f281be8, 0x3eec1672, 0x3f432bee, 0x3f2b360b, 0x3f4c1fe8, 0x3e8a23de, 0x3d45dba0, 0x3f65ef97, 0x3f3f60db, 0x3dca8de0, 0x3c366400, 0x3f5fe7ff, }; // 15,10,6,7 uint32_t kernel_vals[] = { 0x3cdb73c2, 0x3c526030, 0xbc26191a, 0xbcb1ae92, 0xbc7bf83c, 0x3c2f1530, 0xbb4ac0f0, 0x3c97fb2a, 0x3c31873c, 0x3c980e58, 0x3cd67cbe, 0x3c31b9c0, 0xbc834918, 0xbd06e50d, 0x3cb9e752, 0xbc363616, 0x3cb73d78, 0x3c47f97c, 0xbc82b898, 0x3c2760f0, 0x3cea7da8, 0x3c3b0884, 0x3cc7c39c, 0x3ce3a586, 0xbb3c9b58, 0xbcab4bb2, 0xbc0cf1da, 0xbd009685, 0x3b513b20, 0x3d007089, 0x3b707a20, 0x3d01ff61, 0xbaf24ae0, 0x3c9255d2, 0xbba7a480, 0x3bef72b8, 0x3bb80a70, 0x3a3aeac0, 0x3cae4cfe, 0x3b9f1930, 0xbbe18824, 0xbcb4bf92, 0xbd03344e, 0xbc1e3f8a, 0xbce4b6a9, 0x3be7c068, 0xbbe5ddf8, 0x3bd8db80, 0x3cf41fde, 0x3c584bac, 0x3ce409a0, 0xbcbbbaa3, 0xbc93c292, 0xbc35fb5e, 0x3ad80ba0, 0x3c9e5f78, 0x3c9dd550, 0x3cad6cec, 0xbb59bac0, 0x3c4fa608, 0xbcd34638, 0xbc321fce, 0x3ca213be, 0x3cf9969a, 0x3cfd9836, 0xbbef3644, 0xbd06dde2, 0x3c96f69c, 0x3cd102ec, 0xbc7d8c30, 0xbd0836d6, 0x3c0fc210, 0xba84f760, 0xbbdf353c, 0xbb44f878, 0xbb84fa68, 0x3cd2f472, 0xbc5b2b5e, 0x3ce85990, 0x3cf00b22, 0xbc094c40, 0x3b4ef580, 0x3ce62008, 0xbb48f8f0, 0xbc6ffb34, 0x3cdec706, 0xbb674aa8, 0xbc8525c7, 0xbb7547c0, 0xbcff6214, 0xbade41a0, 0x3c3b0a78, 0xbcdd38fe, 0x3c805196, 0x3cb22bbe, 0x3d086e91, 0x3b0b5450, 0x3b3921e0, 0xbcde18f8, 0x3ce8a88e, 0xbc889949, 0xbc40e830, 0x3cf78466, 0xb9423100, 0xbd0224d4, 0x3d0861bf, 0x3cc13370, 0x3d018ce1, 0xbce7a2ee, 0x3c9463c2, 0x3bcf3c78, 0xbb9c0de0, 0x3ca52d6e, 0xbb45ea00, 0xbccccf4c, 0x3c9e357a, 0xbce0f487, 0xbcf80901, 0xbc67b1da, 0x3cd12a12, 0xbd033d54, 0x3c9cba84, 0xbcfb5fc1, 0x3be3fd08, 0xbccba260, 0x3b1da040, 0xbcc7f0c5, 0x3c928254, 0x3cab85ee, 0x3c954e84, 0x3cc7f242, 0xbcb3b7b6, 0x3c25e534, 0x3ccf0e5a, 0xbc91e9c9, 0xbc73e8ca, 0x3c9e0676, 0x3cc00de2, 0x3c098bb0, 0x3c8a0e6e, 0xbb8acaac, 0x3cdfa214, 0xbc354dd6, 0xbc6ba928, 0x3cdf1b8a, 0x3caf2c38, 0x3c249960, 0x3ce113fa, 0x3c612318, 0xbb61fb20, 0xbccfe7f0, 0xbbd52a78, 0xbbb25e10, 0xbc956ee5, 0xbca6dd38, 0xbca1c894, 0xbcf8c96e, 0x3cfaba02, 0xbcda72e9, 0x3b746490, 0xbc54cdce, 0x3d027979, 0xbccb1618, 0xbce43af6, 0xbc5df28a, 0xbb6369f0, 0xbba6cd08, 0x3ca5150c, 0xbcc54076, 0x3cae99b6, 0x3cf34a76, 0x3cc7246e, 0xbaecf3a0, 0x3cf48276, 0x3c70c220, 0x3b89cd00, 0xba265080, 0x3cc80524, 0xbcd12c7a, 0x3c3b7b84, 0x3cab054c, 0xbce9b3d0, 0xbcdf41a3, 0xbbedc0b4, 0xbcdc5af2, 0x3cd5c4a0, 0xbbce6bb4, 0x3cc4958e, 0x3be1da90, 0x3bfacb08, 0xbc99371a, 0xbca37ee5, 0xbb0455f0, 0xbc363b68, 0xbc92b249, 0xbc551568, 0xbc37cc92, 0xbc72ba9a, 0xbcd2b25a, 0x3bd20c48, 0x3c80ff92, 0x3bdfffd0, 0x38c8a600, 0x3c070c94, 0xbcdd1e81, 0xbaf0de40, 0x3cec0380, 0x3cd32e18, 0x3cd5deda, 0xbbdc0634, 0xbc9f18a5, 0x3cd5b556, 0xba5fe580, 0xbbc1fa9c, 0xbc2c6ac4, 0xbb775968, 0xbc9bee18, 0x3cf68936, 0xbc29e44a, 0xbc05fd9a, 0x3ca907c0, 0x3c823938, 0xbbbbe134, 0x379fd800, 0x3ce5dd14, 0x3c3eff30, 0x3c86194c, 0x3cc253e2, 0xbd067b50, 0xbc9feee5, 0xbb145248, 0x3d06162f, 0xbc848272, 0xbbf61da4, 0x3cd025f6, 0xbca65985, 0x3c935de4, 0xbc761240, 0xbce2224c, 0xbcb8c0e7, 0xbcca2f36, 0xbcc5dfce, 0x3c06b534, 0x3c631320, 0x3c9920ce, 0xbc37217c, 0xbceb8db0, 0xbc738646, 0xbcde5e2e, 0xbcd6a0b4, 0x3cc074b6, 0xbc8e59cd, 0x3c31f2b0, 0x3b113410, 0xbca06300, 0x3ca48f16, 0x3ca885fe, 0xbc827b12, 0xbc448e00, 0xbba60d44, 0xbcbce2c0, 0x3c71c9e4, 0x3d039d41, 0x3cb6e8d4, 0x3c680c30, 0xbcdb4bf6, 0x3b6a1710, 0xbbab9d34, 0x3cff1eae, 0xbc8b0ba7, 0x3ca95a46, 0x3bea8810, 0x3cda3dd8, 0xbbd334a4, 0xbbc88d80, 0xbcfe6a7d, 0x3c0d0b30, 0x3ca7866a, 0xbc298abc, 0x3cf81c36, 0x3c20ea54, 0x3ba54a70, 0xbce0ad30, 0xbacf5e80, 0x3b4bff10, 0xbc6f5fe2, 0x3cfbeeb6, 0xbc14f49e, 0x3b2fc1f0, 0xbac974a0, 0xbc43e8a8, 0xbb0e4de0, 0xbd04e6ea, 0xbd042bef, 0x3cd31c08, 0xbaa9caa0, 0x3c1df88c, 0x3ce01630, 0x3bd3ca30, 0xbcc6d7b2, 0xb979e500, 0x3c91ef76, 0xbc676540, 0x3c100668, 0xbbffb008, 0xbba2f1e0, 0xbd041ee4, 0x3c8123ee, 0xbcbbd0b6, 0x3c26b13c, 0xbb88d7cc, 0x3c4248bc, 0x3c332370, 0x3c8c954e, 0xbcc31360, 0xba90d1c0, 0x3c984162, 0x3ca679be, 0xbbb18d88, 0x3d062691, 0x3b859268, 0xbb056a10, 0xbc6d34bc, 0x3d017cd3, 0x3c800880, 0xbc9f02c7, 0x3ce1f8ce, 0xbca4cb8b, 0x3c7fb720, 0x3cce7622, 0x3c96871a, 0x3b472a20, 0x3c68f488, 0x3bc68a60, 0xbcd24547, 0xbab6da00, 0x3b0f53d0, 0xbbd7a9bc, 0x3ccd74f4, 0x3cbe3b2c, 0x3c600240, 0xb8fcb800, 0x3ce7968e, 0x3cd7a0f4, 0xbcf17852, 0xbc392c00, 0x3cebb946, 0x3bc06630, 0xbcc378fe, 0xbcacecc7, 0x3cee1276, 0x3bbfc718, 0xbc9f908e, 0xbc686c00, 0x3caee9a0, 0x3c18c964, 0x3cff88ee, 0xbcbb91a7, 0xbb34c848, 0x3c819278, 0x3ca7ced8, 0xbc109352, 0x3cf20012, 0x3cdb2506, 0x3b1f4d50, 0xbc36af4a, 0xbcd04c8c, 0xbcde58ee, 0xbd087c84, 0xbc0a0b8e, 0xbc758822, 0xbbd7ae58, 0xbcebff76, 0x3b862a48, 0xbbfc8180, 0xbc707e16, 0x3c86bc88, 0x3ce3ea2a, 0x3b38ab00, 0x3cfe37a6, 0xbca4a3d2, 0x3ca1c802, 0xbc810747, 0xbcceb178, 0xbb2c6dc0, 0x3ad1d640, 0x3cf32c3e, 0x3b69acc0, 0x3d018aff, 0xbc29adb4, 0xbc2bacc0, 0xbc985f25, 0x3cb9b5ce, 0xbce45252, 0x3d079ecd, 0xbd00b00b, 0x3bd9a998, 0xbcfacd52, 0x3cd7b432, 0x3c632aa4, 0xbb7c1c20, 0x3bc66918, 0x3c72de5c, 0x3c7f6f48, 0x3c23d93c, 0xbcbf6e94, 0xbca65718, 0xbc62ad46, 0x3c82db7a, 0x3cc31a50, 0x3cc49d1c, 0x3c94d1a2, 0x3b15b110, 0x3c844dd6, 0xbba9761c, 0x3ca76c5e, 0x3d00a875, 0xbb1ea078, 0xbc56518a, 0xbcfd8b9f, 0xbb665798, 0x3cbbba3c, 0x3bf89fe8, 0xbcfed0d0, 0xbc633e6c, 0xbc3980a2, 0x3d06fdfd, 0x3cceb832, 0x3c994c32, 0x3c829982, 0x3c092dbc, 0xbc2b6c44, 0x3cc4d2ce, 0xbcb16cc0, 0xbbeec568, 0x3cd72d26, 0xbc503d92, 0xbabf45a0, 0x3c66d204, 0x3cf23036, 0x3c10ae80, 0x3c5560c0, 0x3c0b9c24, 0xbcef18d6, 0xbcbbede3, 0x3ca1fd72, 0xbb8bb6c4, 0x3c840274, 0x3c8cd982, 0x3bf27fc8, 0x3cb5b230, 0xbc4e3f0a, 0x3c859f14, 0x3ccb5b14, 0x3cb55d6c, 0xbcc16dbc, 0x3c0ab0f0, 0x3cbc3fd8, 0xbc261bde, 0xbd03a753, 0x3cc23830, 0xbbdbae4c, 0xbd03dd28, 0xbcd040c3, 0x3c985ef0, 0xbcdff2a1, 0x3c85f30e, 0x3ccf4274, 0x3cf8077e, 0x3cada580, 0xbce5017a, 0x3cae75ae, 0x3a3cda80, 0x3aaaa060, 0xbbfe0290, 0xbcacd3a9, 0x3c89fadc, 0xbc980c65, 0xbbd7c1bc, 0xbce83f0e, 0xbb0a9000, 0x3c1e56dc, 0x3ce86290, 0x3c5d3720, 0x3c4cabec, 0x3c2ffcc4, 0x3bf320e0, 0x3c3ca4e4, 0x3ce2190a, 0xbcf6bf45, 0xbcc675a9, 0xbcff935a, 0xb90d3700, 0x3cdb6000, 0xbcd76f67, 0xbceba5da, 0x3cd9d4ca, 0xbbc4663c, 0x3c1b1280, 0x3ae7d280, 0x3cc33eec, 0x37476000, 0x3c1e3270, 0x3cd543f8, 0x3d0788f1, 0x3c18f048, 0xbb9aa8e8, 0x3cdab5c2, 0x3c9daad8, 0x3d052e2f, 0x3c8ada02, 0x3c4b6438, 0xbcb6def6, 0x3bf10dd8, 0x3ce2a0f4, 0xbcb73638, 0xbc9d7076, 0xbb67a998, 0xb9fda680, 0xbb4a26e0, 0xbcb7e2fa, 0xbc80fffc, 0x3d06ab9f, 0xbcbd2ea3, 0x3bcc1dd8, 0x3cc49b38, 0xbbcf2934, 0x3c9b12de, 0x3b131c10, 0xbcef8ed8, 0x3ce385b8, 0xbc33e434, 0xbce2f021, 0xbc39a216, 0x3c016178, 0xbc9ebf52, 0x3bea4878, 0xbb81a378, 0x3cc40aaa, 0x3c7a4b30, 0x3c6a541c, 0xbc4d1b96, 0x3c935182, 0x3ab8a8c0, 0x3cc4d618, 0x3cf00b96, 0x3c58767c, 0xbc15fc30, 0xbcdf6170, 0x3c4d03dc, 0x3c2cbd74, 0x3ce0de8e, 0xbcff0603, 0xbc4babb4, 0x3cf1d252, 0x3c8186f8, 0x3cbcc842, 0x3cf2abea, 0x3cdbdcf6, 0x3c081b9c, 0xbb1efe88, 0xbca0ef98, 0x3cddd9fe, 0xbb239d20, 0xbbc9f978, 0x3ca4763a, 0xbc6dddd2, 0x3cec2e36, 0xbc9d0eba, 0x3cea7d12, 0x3c5e268c, 0x3cb285ca, 0xbbca0ebc, 0xbc5ef63c, 0xbd00b5aa, 0xbcbdfcf6, 0x3caa6e92, 0x3c62437c, 0x3c240b8c, 0x3c5fd878, 0x3c383ff8, 0x3cc0b35e, 0xbbfa7960, 0xbc87ecd8, 0xbcf85c98, 0xbbbd76a4, 0xbc7274d2, 0xbcb3d669, 0xbce9ca70, 0x3ce726ae, 0xbc8eb800, 0xbcd6179a, 0x3c201370, 0xbc0ac07c, 0xbc29858e, 0xbccc8e76, 0x3ce08baa, 0x3c2681b0, 0x3d01ec3b, 0xbcb64a34, 0xbbc730f8, 0x3cbda8b2, 0x3c675478, 0xbc39a268, 0x3bb67608, 0xbcaea76c, 0x3c7ec200, 0xbb0391f0, 0xbcb73d32, 0xbd01021b, 0x3cf52186, 0xbc66134a, 0x3b621ff0, 0xbbd6c370, 0x3bbd1c30, 0xbcfe6af4, 0x3cedab66, 0xbcc48a90, 0xbcf79fc5, 0xbb130f30, 0xbce03b0c, 0x3c8403b6, 0xbb8690f0, 0xbaf30d80, 0xbc1b3292, 0x3c8d792a, 0x3d037777, 0xbd055679, 0x3b9a3a08, 0xbcedfd94, 0x3bfdc8d8, 0xbc9d6c6b, 0xbd05151d, 0x3cea4bce, 0x3980a900, 0xbcf3e49a, 0xbce8b7b6, 0x3c584198, 0x3bf91a08, 0x3cd96e1a, 0xbcaf1b90, 0xbcaf24fc, 0x3c3762ac, 0x3d06627b, 0xbb3aea88, 0x3cd10bfa, 0xbd07ca4c, 0x3c9ecb7a, 0xbd04a7ca, 0xbce6d4e1, 0x3cff3e62, 0xbc1ac1e2, 0xbc9354e7, 0x3c5bc734, 0xbc22977c, 0xbd00844e, 0xbce5b0e7, 0xbccb86ba, 0x3c8098de, 0xbc24e4d6, 0x3cebde02, 0xbb733238, 0x3c779648, 0x3cf6bfba, 0x3cbad862, 0x3b7b7600, 0xbca75200, 0x3c45bc48, 0xbcab4989, 0x3c700fa4, 0xbcc7729e, 0x3d077b59, 0x3cbbcda4, 0xbcd4a4c3, 0xba5fdbc0, 0x3b123de0, 0xbcddc521, 0x3c8ae7e0, 0xbd0109a5, 0x3ca10d04, 0xbc64955e, 0xbcbb8752, 0x3c3a4384, 0xbb97972c, 0x3c510624, 0xbc1a2612, 0xbc5e2b52, 0x3cc81ec2, 0x3d00660b, 0xbc219604, 0xbb9cf3bc, 0x3bbd5930, 0xbbc07908, 0xbcda499a, 0x3cf15722, 0x3c7f94dc, 0xbc785ada, 0xbc66224e, 0x3cfbf0da, 0xbcb7833c, 0xbcbf6432, 0x3cd409f6, 0x3d06735d, 0x3c9db84e, 0xbc381bca, 0x3ca26d34, 0x3c371554, 0xbc192fa6, 0xbcfc9a3d, 0x3ce755b6, 0x3ca6a260, 0xbc5f1ad2, 0xbcea7852, 0xbc82f598, 0x3ca71ffc, 0x3bf22490, 0x3cc5f3da, 0xbcf65cda, 0x3ba4c700, 0xbc26825e, 0xbab1c220, 0xbcf4e716, 0x3c67d8d0, 0xbc6b8b38, 0x3ca6af32, 0x3cb24316, 0x3cff1a36, 0x3bf3a160, 0x3c221cb4, 0x3ce98b3c, 0x3ca64ea0, 0xbcd5567e, 0x3b675320, 0xbce106ff, 0x3be95578, 0x3ccf83fc, 0xbcf785a5, 0xbb8a2578, 0x3cd41e8c, 0xbbd38060, 0xbcec5e89, 0xbbbe17d4, 0xbc06ae16, 0x3c6859a4, 0x3d024923, 0xbcf7403d, 0xbc723b9a, 0xbc6225a2, 0xbcec07df, 0xbc7dafe8, 0xb9adad00, 0xbce63365, 0xbcac3d65, 0x3d015505, 0xbc38a204, 0x3c15a10c, 0x3cf4a96e, 0xbcbaf058, 0xbb28b930, 0xbc5b50f8, 0x3c001f00, 0xbcc1f280, 0x3d03cd45, 0xba18dc40, 0x3c26efa8, 0xb8944600, 0xbcb1c058, 0xbc871178, 0x3bd5bf48, 0xbc686996, 0xbc35c234, 0xbced4fb4, 0x3c47efc0, 0x3bb829e8, 0x3cdf2256, 0xbca60f07, 0xbbe60188, 0xba88d7a0, 0xbcd30e89, 0x3b44a3d0, 0x3c2d328c, 0x3cb49e70, 0x3cb94a8c, 0xbc34637c, 0x3cd14968, 0x3c17e430, 0xbc55323c, 0x3ce435b4, 0xbb14a148, 0x3cd41972, 0x3d05b025, 0x3d0229b3, 0x3c288b84, 0xbcd0770c, 0xbc49c738, 0x3d015ea5, 0x3cfd81da, 0xbd07777b, 0x3cef3a1e, 0x3cee03e8, 0x3cd07716, 0xbce633ff, 0x3c993754, 0x3c0829dc, 0x3cc072ca, 0x37071000, 0xbc49d01e, 0x3ca89022, 0x3bb9ce68, 0xbb138a00, 0xbb5d23c0, 0xbd027647, 0x3c9f8134, 0x3ce12816, 0x3d0704cd, 0x3c067b2c, 0x3c938550, 0xbc9bc0a0, 0x3ca180ae, 0xbcf2cbc7, 0xbc22144a, 0x3cac96a4, 0x3cafc46c, 0xbd04b8a2, 0xbca675b8, 0xbcfbf845, 0x3c276504, 0x3ce398d0, 0x3ca7a224, 0xbbdff44c, 0x3c4d8db0, 0x3b8c1510, 0xbb1fe988, 0xbc67048a, 0x3b700fd0, 0xbca368ab, 0x3c5e92ec, 0x3cebcf46, 0x3cc91a6e, 0x3c7a446c, 0x3cde3ca6, 0x3cfe02e6, 0xbcdab10e, 0xbc3f8000, 0x3b91f660, 0xbbc1d508, 0x3bdcfc30, 0xbbe94e80, 0x3c0086f8, 0xbd0611d8, 0xbc9450a9, 0x3c98d27e, 0x3ca10f0e, 0xbc0b78bc, 0x3cf39c8a, 0xbcaf7d56, 0x3be738d0, 0xbc11fcda, 0x3d04a341, 0xbc070e5e, 0x3b02dbe0, 0x3c67cd80, 0x3ca63e0a, 0x3b355fc0, 0x3cd4b738, 0x3c0d9bbc, 0x3d06a273, 0x3bb0efd8, 0x3cf7bfae, 0x3c9f7218, 0xbc48e062, 0x3c76a55c, 0x3c907bce, 0x3cc87c44, 0x3d029e47, 0xbc3f6b16, 0x3cddab66, 0x3c710c24, 0xbbc3fde0, 0x3cdd1a02, 0x3cc357b6, 0xb977d900, 0xbbe3b89c, 0xbcbec37e, 0x3d028bbf, 0xbb4e3c20, 0x3d076067, 0x3cffd22e, 0xbcb0b545, 0x3ca03178, 0x3cd86462, 0x3c729b88, 0xbcc4cd5e, 0xbceee7d0, 0xbb7d0d48, 0x3cd2f1dc, 0xbc86cd2b, 0xbb1e1868, 0xbc840023, 0xbcce608c, 0x3b8a11d8, 0x3a095040, 0xbb8e70f8, 0xbca76038, 0x3c69b384, 0xbc2140b0, 0x3c5f0e00, 0xbcd8b59e, 0xbc243cda, 0x3c6cac28, 0xbba19788, 0xb9ce1380, 0x3ba9e828, 0xbca20ed2, 0xbd03ba43, 0xbcd568d4, 0x3ca1d658, 0x3cc785cc, 0x3d02cf0d, 0x3cd45810, 0xbcb7acde, 0x3cd56f94, 0x3ccf021c, 0xbbcf0df8, 0x3c13d4c8, 0xbbb87490, 0xbc182be6, 0xbb3aa1f0, 0xbb78c010, 0x3bf0c898, 0xbcc94d5a, 0x3cea3908, 0x3cdc9df4, 0x3d0298ff, 0x3d062153, 0x3cfdc31e, 0x3cc8462e, 0x3c4160a8, 0x3c154fc8, 0x3cd95e3c, 0xbc54367c, 0x3c730b1c, 0xbc334584, 0xbb377010, 0xbc869a6d, 0xba21e1c0, 0x3b61d0d0, 0x3c523b9c, 0xbcd9e6da, 0x3cc05fe8, 0xbcaf60e9, 0x3bbc00e8, 0xbb52ee48, 0x3c074ce4, 0x3ce45c50, 0xbc8e6eab, 0x3aa5b0a0, 0xbbdeda60, 0xbb09b6f0, 0x3ce01e20, 0x3c18bea4, 0xbb3013f0, 0x3cbcca08, 0x399cfd00, 0xbd00b20b, 0xbc87ddfa, 0x3c3e5648, 0xbb8b2578, 0xbcb8e974, 0xbb98cab4, 0x3ca893ca, 0x3c60ff50, 0xbc793762, 0xbc3eebd6, 0xbce48194, 0x3cb074f8, 0xbcdd5bfa, 0x3c93372a, 0x3d04f033, 0xb96f5b00, 0x3bc81fd8, 0x3b93c8a0, 0x3c8c7340, 0xbc384022, 0x3ae723e0, 0x3beb9540, 0x3cf7406a, 0x3c91a4e6, 0x3b8861c0, 0x3b126200, 0x3b825998, 0xbcbc6bf6, 0xbc83fe1e, 0x3ccf744a, 0x3ccb8cb4, 0xbb96ba08, 0x3be4d728, 0xba4a9dc0, 0xbcfe37f6, 0xbcf9004c, 0xbce94c07, 0xbc3b98bc, 0xbc81edcb, 0xbce48a6e, 0x3c208ff0, 0x3c76d3ac, 0x3cbe305e, 0x3c6d8560, 0xbce826ee, 0xbcfd777f, 0x3cda06ca, 0xbb5a4498, 0xbcf19732, 0x3c193cc0, 0x3c5eb010, 0x3c5d80d8, 0x3c488e00, 0x3cf148d2, 0xbcf9ee85, 0x3c38741c, 0xbbcf39c4, 0xbce251df, 0x3c876fe4, 0x3c44f844, 0xbc978e98, 0xbc6054a2, 0xba43f440, 0x3c64ab2c, 0x3d0473ad, 0x3c97e1bc, 0xba3396c0, 0xbc370752, 0x3ca3df36, 0xbcc8f15e, 0xbd051a4e, 0xbb3d8468, 0xbab439c0, 0x3c8583d8, 0x3c47b868, 0xbc02b54e, 0x3c026d14, 0x3c8e1818, 0xbd02c07b, 0xbc4a8efc, 0x3c85949c, 0x3badd498, 0x3a1f3040, 0xbc20b43c, 0x3cd6d7de, 0xbc5a4480, 0x3c358af8, 0xbccec1da, 0xbbea6f68, 0x3cde5058, 0xbba4149c, 0x3c338fc8, 0xba8371c0, 0x3ccb02ec, 0xbb051390, 0xbc4385bc, 0x3ce366ac, 0x37e63000, 0xbc98d389, 0xbc88ae3a, 0x3a609d40, 0x3bf81c88, 0x3cb28efc, 0x3cdcec78, 0x3c232060, 0x3cac4102, 0x3c90d24c, 0x3ca9b482, 0xbcd228da, 0xbb5d5f20, 0xbc1a980e, 0xbc3a6640, 0xbc8951ab, 0x3cd96a1c, 0xbce888bc, 0x3bf4ebe8, 0xbc1164c0, 0xbc5dfe38, 0xbbd0bbc4, 0x3c0d117c, 0xbc82f2fa, 0xbcc73cbc, 0x3c6a1c30, 0xbceadbf2, 0x3ce19188, 0xba129880, 0xbc0a8d4e, 0xbc72873c, 0xbca63de2, 0x3cfe3336, 0xbb598810, 0x3cbe8a0c, 0xbcb0355e, 0xbd032fb5, 0xbcbba729, 0xbb2c3d78, 0x3c6f677c, 0x3b687420, 0x3ca18b34, 0x3ca06c76, 0xbc0c9fac, 0x3c106838, 0x3a9f6720, 0xbce0f62c, 0xbc9897b2, 0xbc99cdd8, 0x3bce3950, 0xbc5f8006, 0xbace8260, 0xba1e0b00, 0xbc276174, 0x3c9eda36, 0x3cd0f708, 0xbc3d0ef4, 0xbcaba8c0, 0xbb0d3ad0, 0xbbf87a70, 0x3c5a1e40, 0xbc819ea3, 0x3c93c35e, 0xbb8936e0, 0x3cc0ec64, 0x3c638138, 0x3c85e4bc, 0xbbb3bf80, 0x3cae71ec, 0x3c5457a8, 0xbcc25292, 0xbce3c265, 0xbcac987a, 0x3d0473f7, 0x3cc8f57e, 0x3c7c3fe0, 0xbcfa8a47, 0x38283400, 0xbb2c6a78, 0x3c84591c, 0x3c92d74c, 0xbc83c58b, 0x3ceba726, 0x3bf58360, 0xbc1a0ab4, 0x3cf38b7a, 0x3d00757d, 0x3c0a1d50, 0xbc7236e8, 0x3cdf5ef6, 0x3c9b80b4, 0xbc756d7c, 0x3d07b20b, 0x3cb913e2, 0xbb54d920, 0x3bf79af8, 0x3d06fc93, 0xbc80b485, 0xbc0fda62, 0xbc14574a, 0xbb2009f0, 0x3cca5496, 0xbcff7647, 0x3cdec87a, 0xbb6e7f78, 0xbce2a198, 0xbb8189e8, 0x3b288340, 0xbbd2e944, 0xbce2ca74, 0xbcccf7d0, 0x3cf8fb9e, 0xbb875f78, 0xbc15be56, 0x3cdefde0, 0x3cba7f7e, 0xbc4207de, 0xbb8099cc, 0x3bff01f0, 0xbcf34298, 0x3c2e1740, 0xbce95f9f, 0x3d04936f, 0xbc4fb03c, 0xbca6a58e, 0x3cc579c4, 0x3b3af630, 0xbcf3e7d6, 0xbadcffe0, 0xbce1ff9c, 0xbc29049e, 0xbbd78180, 0x39b82e80, 0x3c6c76c8, 0xbc22dc9a, 0x3ceb6498, 0xbac9cf40, 0xbc7c4870, 0xbc102e96, 0xbcfee66c, 0xbce39c49, 0xbbec429c, 0xbafc4ca0, 0x3c624a9c, 0xbb940e9c, 0xbcf671e1, 0xbc6023fc, 0x3c96c674, 0x3ccdb124, 0x3b560c10, 0xbc6148bc, 0xbcf1117a, 0x3b9eace0, 0x371f5000, 0x3b1702f0, 0x3cd7ee40, 0x3a6fb5c0, 0x3cf50782, 0x3c4fcb20, 0xbad398c0, 0xbc8bf7f6, 0xbc80ac9c, 0xbcace4a5, 0x3b9b7e00, 0xbb1f1148, 0x3cd1152c, 0xbbdc57c4, 0x3a843cc0, 0x3ccb4a14, 0x3c122e44, 0xbc9ec47a, 0x3ba24088, 0xba458680, 0x3ccedc74, 0xbbec7bc4, 0x3b6b6c20, 0xbcfb1801, 0xbc22e970, 0xbd068d96, 0x3d0217df, 0x3cd3ee0e, 0x3d080413, 0xbc91acae, 0x3c88e316, 0xbc5b5dda, 0xbbde2a88, 0x3c9130c4, 0x3bbf0378, 0xbb799600, 0xbca85385, 0x3cb98a2a, 0xbcde983a, 0xbce53336, 0x3cdfb316, 0x39c27d00, 0xbce8d374, 0xbbae52b4, 0xbc894a47, 0xbbad4d70, 0x3ce7d2d0, 0xbbee31c4, 0x3c80c000, 0xbbce64f0, 0x3cd7d3ee, 0x3ce571fa, 0xbc1c3284, 0xbcfea7b2, 0x3cb238b0, 0xbc723b5a, 0xbc2e711e, 0xbc984a05, 0x3c2bff90, 0x3c76a230, 0xbd06b800, 0xb981e100, 0xbc98b220, 0xbcaa8182, 0xbcc1c9fc, 0xbcab7792, 0xbccefab2, 0xbc421916, 0xbbba61b4, 0x3d03c6eb, 0x3cb024e4, 0xbbe25c1c, 0xbc62eb0e, 0xbc524868, 0xbd05b88a, 0x3c4c6d64, 0xbb533bf0, 0x3cf49a4a, 0xbb8d6af0, 0x3d034e95, 0x3c9656d8, 0xbc2337f4, 0xbcbffbe3, 0x3c8977c6, 0x3c9f03f2, 0xbcfc0aee, 0xbc73092c, 0x3bd739f0, 0x3cf7bd1e, 0x3baa3f00, 0x3d01db81, 0xbc56289e, 0x3c5f56ec, 0x3b6713b0, 0x3d05d4dd, 0xbcf150b2, 0x3c28d864, 0x3cce871e, 0xbba182d4, 0x3b127200, 0x3c8c9dee, 0x3b60fa40, 0xbb7fdac0, 0xbcae9f89, 0x3c1feb88, 0x3d041bc1, 0x3a7af540, 0xbacc52c0, 0xbcf828d4, 0x3ccfce22, 0xbbffeb1c, 0x3ca072e4, 0x3cdfe5fe, 0x3c8846d4, 0xbc409d16, 0x3c03b980, 0x3cc896ae, 0x3c082068, 0xbc19d440, 0xbcdfe130, 0xbcf0ecb6, 0xbc8e4a14, 0xbc07444e, 0x3c301d40, 0x3cf9087a, 0xbcbd2bd8, 0xbcd98945, 0x3bccadf8, 0xbc9ec78b, 0x3cb8d058, 0xbd05ff5b, 0xbb119f20, 0xbc7365f0, 0xbc8a07b8, 0x3ccf3b88, 0x3b79d640, 0xbcfd2ece, 0x3ce106ce, 0x3ce81996, 0x3be782e0, 0x3bcc7580, 0x3cc2b156, 0xbcd8c070, 0x3c7ce6bc, 0x3c9e0cc0, 0x3cb48f3e, 0x3cc262da, 0x3b55d8e0, 0xbcc15565, 0x39946780, 0xbc64f422, 0x3c8bbab2, 0xbc953aa7, 0x3c863780, 0x3ca7e1ea, 0x3beac828, 0x3be755b0, 0xbc956369, 0xbbed2c78, 0xbc5e180a, 0xbd0560a3, 0xbbb5c768, 0x3cc2d328, 0x3bf84868, 0x3c8f50d8, 0xbce6e03f, 0xbce40316, 0x3c751da0, 0x3c456c98, 0xbb66bbd0, 0xbc88117a, 0xbce4e538, 0xbce70252, 0x3c3fe14c, 0x3aa19bc0, 0xbc937442, 0x3c624c84, 0x3c3a0238, 0x3ce65722, 0xbcb0e9a0, 0xbcc2ec34, 0xbcf4b6f2, 0xbd028280, 0x3b41ed50, 0x3caba662, 0xbb82a71c, 0xbc86a9c0, 0x3b31ed80, 0x3bfe5ce0, 0x3b9bd280, 0xba35e340, 0x3d021d1f, 0xbcb5b66c, 0xbcf9d47f, 0x3c8b17d8, 0xbce67927, 0xbce8378c, 0x3ccc25aa, 0x3c04994c, 0x3c3ca310, 0xbbe559d8, 0x3cb0d90c, 0xbca26047, 0xbbaadb78, 0x3bd805a0, 0x3c212190, 0xbcde54e7, 0x3c820ef2, 0xbc75bc2c, 0x3a727900, 0xba00d540, 0xbc5fb1e8, 0xbc155d04, 0x3cb2bab0, 0xbce88ee1, 0xbc9302fc, 0xbc1abb04, 0xbd070c5f, 0x3ca67796, 0xbc4e2a5a, 0xbbcc1c1c, 0x3cfb92f2, 0x3cf43336, 0x3cc967dc, 0xbcf7c134, 0xbca300fe, 0x3c0479c4, 0x3c9e093e, 0xbb933278, 0x3c592e64, 0xbb8d7570, 0xbcd99bda, 0x3c158144, 0x3c8a6aec, 0xbc3b4e44, 0x3c0839d4, 0x3d03d73d, 0xbc7c628e, 0x3c27d26c, 0xbc6b8fbc, 0xbcc1136e, 0xbcda85f4, 0x3cf80d3e, 0xbbe9d390, 0xbc9bdc00, 0x3c84f3ee, 0x3b4c5510, 0x3cc32202, 0x3a160580, 0xbccf5010, 0xbb3e7ef0, 0x3b8573e0, 0xbafc4e20, 0xbc5ef50a, 0x3b68db00, 0x3c7a38e0, 0x3cd94edc, 0x3cebb86c, 0x3b009760, 0xbc508ec0, 0xbc93afa9, 0x3ca4c752, 0xbccad740, 0x3bd251d8, 0xbd037efd, 0x3ce126ac, 0xbc444f00, 0x3bc8fef0, 0xbc8773ab, 0x3c8f8a44, 0x3cdfea4a, 0x3c186c6c, 0xbca5cb49, 0x3cc193ca, 0xbd0874ce, 0x3ca9d586, 0xbbe956ac, 0x3cfae08e, 0x3cf17372, 0xbc614856, 0x3cfbe4da, 0xbbe03c70, 0xbcf0db56, 0xbb853690, 0x3c94ce26, 0xbc943114, 0x3ba49e78, 0x3ce11a52, 0x3ccbe3d6, 0x3bd42b00, 0x3c8a4e0c, 0x3d03168f, 0x3cfab03e, 0xbcb93b54, 0xbc72f3ca, 0xbc61ea52, 0x3c9b9678, 0x3c933c80, 0xbc8fd13e, 0xbbbd9d54, 0x3ca6ba12, 0xbbd3a29c, 0x3c46c248, 0x3c7bf530, 0xbc187684, 0xbcd3ff70, 0x3c850b4e, 0xbae7abe0, 0x3b77f920, 0xbbe86e34, 0xbced401c, 0xbcb71340, 0x3c4243c8, 0xbd028d65, 0xbc7ee786, 0xb9b09b00, 0x3cbf051e, 0x3babd340, 0xbccaa152, 0xbcd92201, 0xbcf7c16e, 0x3d04eb79, 0xbc9ae42e, 0x3c95eee0, 0x3cedea06, 0xbb9dfe00, 0x3c28e33c, 0xbcc3013c, 0x3c5503e0, 0xbcab76ba, 0x3b85bac0, 0xbcf9e0f0, 0x3c21e944, 0xbcbbc8c9, 0x3bb96428, 0x3d00fed1, 0xbca0ed4e, 0x3ca3f8d0, 0x3a4dfc80, 0xbb8b93bc, 0x3cb8b96e, 0x3d068f0b, 0x3cc4b868, 0xbcfb1207, 0xbd011463, 0x3c7661bc, 0xbba73b70, 0x3d051491, 0x3c8f4ffa, 0x3cfb6062, 0x3cb4c542, 0xbcea0814, 0x3b63ddf0, 0x3bf17388, 0x39867580, 0x3b977398, 0x3c531c4c, 0x3c7378b4, 0xbc77a492, 0x3bfec698, 0x3cab60ec, 0xbb5ae458, 0xbb3e9aa8, 0x3bad48f0, 0x3bb83bd0, 0xbc3d94f0, 0xbba027f8, 0xbc747aca, 0x3c38bea8, 0x3999c800, 0xbcf83516, 0xbbca5a60, 0x3cbf2568, 0x3ce82c4a, 0xbd07cf83, 0x3cf883fa, 0xbcb019fc, 0xbbc520e0, 0xbcec7c5c, 0x3c01a078, 0xbceaf723, 0xbca2f14b, 0x3c581308, 0xbc97943e, 0xbbd7efb4, 0x3c2cc478, 0xbcc7b300, 0xbc9c64c9, 0xbad26000, 0x3cd0a022, 0x3cc5f888, 0xbcf6a9f6, 0xbc80ab27, 0x3a2c1ac0, 0x3ce5b2e8, 0x3bcaf110, 0x3b49afb0, 0xbd008b8e, 0x3ce1c3e2, 0x3cb933f0, 0xbbc654f8, 0xbbd1dd70, 0x3ceed6e6, 0xbc92c338, 0xbbee5670, 0xbce82970, 0x3c177538, 0xbd001ef6, 0x3c45dd78, 0x3cc30bce, 0x3a241040, 0xbcd79ede, 0xbc52040a, 0xbcfe23bf, 0xbccc6e29, 0x3ba9a0e0, 0x3ce5cb08, 0xbbb8bcac, 0x3cc72efc, 0xbc9f1c18, 0x3bfc8e18, 0xbb7d54c0, 0x3ccdcc6e, 0xbb0f8178, 0x3d064b73, 0xbbc32110, 0xbc96b494, 0xbc9087e7, 0xbcff701d, 0xbb92b3b4, 0x3c28f054, 0xbc1d313c, 0x3ca2a5ae, 0x3b301940, 0xbce6244c, 0x3aa48600, 0x3cef975a, 0x3ce93b72, 0xbc7e7070, 0x3bee4e10, 0xbc990b2e, 0x3c024440, 0xbbfa03d8, 0xbcf3b856, 0x3cef0a4e, 0xb9fb7e80, 0xbc089470, 0xbcf27ed4, 0xbcf25630, 0xbcfb8b6c, 0xbce5cb61, 0xbcdd3307, 0x3b252f30, 0x3caad482, 0xbd02302e, 0xbcc9f17e, 0xbb714478, 0xbc7903b4, 0xbccb3ea5, 0x3c9e1696, 0x3bf65510, 0xbc1905b8, 0xbbb197bc, 0xbc48950e, 0x3a146f80, 0x3d0418d3, 0xbc86a367, 0x3cc492ba, 0x3c81e09c, 0xbc1cbb74, 0x3ca1fe6e, 0x3c30e93c, 0x3ce7f838, 0xbbc89108, 0x3cbb1f90, 0x3b89aa00, 0xbcf530ec, 0x3cb11ed8, 0x3c43df68, 0xbce19434, 0x3b9e2490, 0x3cf89f56, 0xbc849774, 0x3c9fc5d2, 0x3cd40aac, 0x3c7a737c, 0x3c7d2ea4, 0xbc6e32d2, 0xbcf60c58, 0xbceac681, 0x3b5cc6f0, 0xbcb24d05, 0xbc50ea44, 0x3c825ef2, 0xbc8e625e, 0x3b913ee0, 0x3cbabd98, 0x3c4cc200, 0xbc927f40, 0xbaa63d80, 0xbcfb9adf, 0xbb255d48, 0xbcb4b2be, 0xbc223dec, 0xbca329c0, 0x3996f300, 0xbc4b28a8, 0xbca2024e, 0x3bc93218, 0xbcfb261d, 0xbcc07b70, 0x3c5b7edc, 0x3c29eec0, 0xba877a60, 0x3bcaaaa8, 0xbc985c60, 0x3cdabce2, 0x3c05e470, 0xba12b580, 0xbace2ce0, 0x3cf43386, 0x3cc77856, 0x3cdac336, 0x3bcc9858, 0xbca85360, 0xbc7dfc74, 0xbca8f6f2, 0xbcebb929, 0x3c54ddf4, 0x3cef30be, 0x3d086381, 0xbcc61963, 0x3c4933a0, 0x3bd0e390, 0xbcd9286e, 0xbcf52a29, 0x3c41a090, 0xbbe75208, 0xbcfae2f0, 0xbb6de348, 0x3c371660, 0xbca5ee80, 0xbcbd551a, 0xbc87a0cf, 0x3d07b59b, 0x3d07c167, 0x3cf04702, 0xbcb3c79e, 0xbcd251d2, 0xbce30070, 0xbce0f9a9, 0x3bf6c1d8, 0xbd0731b5, 0x3d0370b5, 0xbcaa443a, 0xbc56cda8, 0x3cb7792e, 0xbc8f5829, 0xbcf93b5f, 0x3c839fac, 0xbcaae5d4, 0xbcc4e849, 0x3cb66a44, 0x3b199630, 0x3c468f30, 0x3c77b788, 0x3b168fb0, 0x3c64b68c, 0xbd06ecbd, 0x3b8c23c8, 0xbce2b2a3, 0x3c8dc6a0, 0x3cdd1d38, 0xbca4e910, 0xba55c9c0, 0xbcf4d532, 0x3c2cdfc8, 0x3ca1fbc4, 0x3c86ddc6, 0x3cec0c5a, 0xbb921d80, 0x3cca2cec, 0xbd01a764, 0x3c65cc38, 0xbd015bd0, 0xbbb9c09c, 0x3ce1ab58, 0x3cc7f21a, 0x3cbb4f7e, 0x3d083d27, 0x3baef860, 0xbc0828bc, 0xbcdd867c, 0x3c7b03c0, 0xbc644a06, 0x3c82be4e, 0x3b24bff0, 0xbbb0e154, 0xbcd2baa5, 0x3c0c5f34, 0x3cf15a7e, 0x3c38b8b4, 0xbbf001cc, 0x3ceda660, 0x3c007a10, 0x3b9db930, 0x3d064f59, 0x3c60ed70, 0xbc6bf90e, 0x3c5f42c4, 0xbcfb25e3, 0x3a1da400, 0x3ada6b40, 0xbbd3a34c, 0xbcc02c69, 0xbc91701c, 0xbce28e14, 0xbbdfb1bc, 0x3c7d7424, 0x3d011235, 0x3c93de26, 0xba18af80, 0xbb9be300, 0xbb4fd198, 0xbc1ab75a, 0x3d038375, 0x3c476580, 0x3c61dba0, 0xbaed0000, 0x391a4400, 0x3beba058, 0xbcc32eba, 0x3c35a408, 0x3c5e8790, 0xbcffa045, 0xbac834a0, 0xbcc64ee0, 0xbcca8e32, 0x3cee84e2, 0x3c44d5e0, 0xbc86f4c9, 0xbaf97260, 0xbc4accb4, 0x3cffb27e, 0xbcb03482, 0x3be7bc00, 0xbbff9e78, 0x3c218ce0, 0x3c97a8b4, 0xbbc192b4, 0x3c3c5bbc, 0x3c89a4e2, 0x3c7881e0, 0x3cfd65c2, 0x3ce6165e, 0xbcec7dae, 0x3cac24bc, 0x3ccaffde, 0x3c8b2324, 0xbd081384, 0x3c8e6bdc, 0xbbff50f8, 0xbc8a41fc, 0x3b812fc8, 0xbc95b9c5, 0xbc795b12, 0x3b0e21b0, 0x3cc139f2, 0x3ccdcd8a, 0x3c919a58, 0xbadf4040, 0x3d0388bb, 0x3c126440, 0x3c73270c, 0xbce2c5c1, 0xbcd90be1, 0x3ca06d9c, 0xbcd0e34c, 0xbcba1c89, 0x3cc59b90, 0xbc9a236b, 0xbc8a836b, 0xbcd48874, 0xbcb74023, 0x3c268c1c, 0xbc994032, 0x3c761ec0, 0xbc192b30, 0x3c9233c6, 0xbce39dd8, 0xbbced258, 0x3a8747e0, 0xbc4cb138, 0xbc35a752, 0xbc40e068, 0xbcf891fd, 0x3bf3ce18, 0xbc914e4e, 0xbc210292, 0xbc601c40, 0xbce2742c, 0xbc2e3b66, 0x3c23d840, 0xbb20b9c0, 0x3afc74c0, 0x3cb3033e, 0x3cc42b52, 0xbc3427a2, 0x3d07da63, 0xba00c9c0, 0x3cdb947c, 0x3cf3b55a, 0x3c9bbc24, 0xb94a5300, 0xbb8e6168, 0xbced349c, 0xbcd450c3, 0xbb34d8e0, 0xbc17c062, 0xbcb5627a, 0x3c63403c, 0xbb5d8630, 0xbcbbb84e, 0x3d08704b, 0x3c1b21d0, 0xbbecbbf0, 0xbcef113c, 0x3bcd7dd8, 0xbc363f2c, 0x3ca48530, 0x3d073acf, 0xbcb2fd52, 0xbba4513c, 0x3b33cc10, 0xbc11bc84, 0x3c98d7c6, 0x3ba25528, 0xbc456d0a, 0x3c807874, 0xbb66bd88, 0x3cf9298e, 0x3cfb2672, 0x3c2b2e3c, 0xbc465530, 0xbc7ffd8e, 0xba7fd240, 0xbb0b10c0, 0x3bb898f8, 0x3c69a6a8, 0x3b675ab0, 0xbc53e2ec, 0xbd0407e0, 0x3c3ff124, 0x3a8811c0, 0x3b33baf0, 0x3b805ec8, 0x3cc979d6, 0xbcc31bb2, 0x3c93e704, 0x3bd1c500, 0x3b2cfd80, 0x3c82f4ac, 0x3bf7a6e0, 0x3c477180, 0xbcd269e1, 0x3c4d62dc, 0x3cff0602, 0x3c53d124, 0xbd0157b5, 0x3c655cb0, 0xbcbed309, 0x3cc7e680, 0xbcc89f70, 0xbd01e10f, 0x3c8156c4, 0x3cc82ac0, 0x3cf3b95e, 0x3cee6b4c, 0x3c8451d0, 0x3cf4d9d6, 0x3d01d7d3, 0x3c12fc68, 0xba812800, 0xbbf9c700, 0x3ac36080, 0xbcfd4958, 0x3c8af64a, 0x3c9ce8f4, 0xbc9f2ac2, 0x392d5b00, 0x3c8e7cdc, 0x3caeed1e, 0xbca5ae47, 0xbcb10f92, 0xbc128774, 0x3c4e5084, 0xbb9ff568, 0x3bc59390, 0xbd03c71a, 0xbd05f08f, 0x3c3516fc, 0xbc11882c, 0x3cdaec22, 0xbd04e1b9, 0x3c8bbeee, 0xbca7fd69, 0xbb944388, 0x3cc9e5cc, 0xbcea46fa, 0x3c0981ec, 0x3cc1eac4, 0xbcd82e09, 0x3c2c7ff0, 0x3cc37514, 0xbc102a0a, 0x3ccab560, 0x3aab6800, 0x3c7fce90, 0xbc8970e0, 0xbc857b94, 0x3a25c480, 0xbceec3a1, 0x3b805da0, 0xbc5cbc28, 0x3c8e9366, 0xbcdc9a0e, 0x3acb6aa0, 0x3cebd676, 0x3cd21384, 0x3b0405d0, 0x3becd640, 0x3cf9c51a, 0x3cc07f88, 0x3b32f0a0, 0xbca56c38, 0xbcb835f8, 0x3be691e8, 0x3cb4a372, 0x3c35ccd0, 0xbb4813f0, 0xbca5f77e, 0xbc8eee78, 0xbbcc143c, 0xbce5f749, 0x3c90daec, 0xbca1a6e9, 0x3bf37240, 0x3cff7b2e, 0x3cf37c9e, 0x3ba8ab90, 0xbbe27768, 0x3be9b410, 0xbcff2392, 0xbc51adbc, 0xbaa99120, 0x3cd5f0bc, 0xbb80d9bc, 0x3ce34b16, 0x3c1c5950, 0x3cec9788, 0xbcebf9a7, 0xbb65bd98, 0x3d07f071, 0x3be2cb90, 0xbc3ae3ac, 0xbca740a7, 0xbb080260, 0xbc48507c, 0xbcc31098, 0x3c0e56d4, 0xbc65f9b0, 0xbc05f622, 0x3c97a35c, 0xbcd1b627, 0xbc8863a7, 0x3bf91fc8, 0xbc77b5da, 0xbcbecc3c, 0x3c29339c, 0xbc6124ac, 0x3d033551, 0xbccea7f0, 0x3cc14b62, 0xbceb1b27, 0xbb7bdf98, 0xbc437e1e, 0x3c2a67e0, 0x3cb5d8da, 0x3be8e108, 0xbcae5596, 0x3bda5500, 0x3c3e70b4, 0xbb56ae88, 0xbcaf602c, 0x3c2bc4f4, 0xbcd81a72, 0x3caa69fa, 0xbc5a8e46, 0xbcb7a360, 0xbc8b4f8f, 0xbcfc7add, 0xbc968b49, 0x3b96a450, 0xbb516348, 0x3c5b38f8, 0xbcf4b78e, 0x3d00afa9, 0xbb861934, 0xbc225f3c, 0xbc722068, 0xbc52d470, 0xbc81109c, 0xbcd19e69, 0x3cf15eee, 0x3b3f7f40, 0x3c86fde4, 0x3c841d52, 0xbc3fc934, 0xbb981878, 0x3ce9c266, 0xbd0757c2, 0xbc310934, 0xbbba682c, 0x3c226ff8, 0x3cc1aef8, 0xbc99dfba, 0xbc51c2da, 0xbc194f70, 0xbc94858b, 0xbc0be334, 0x3cc96dd4, 0x3cab7d3e, 0xbb4d4800, 0xbbcd1110, 0xbc9e8d5e, 0xbc79985a, 0x3ccba72e, 0xbc49e9de, 0x3aec0ca0, 0x3cfbde2a, 0x3cc54062, 0x3c5cc4f4, 0x3be1b058, 0xbc9d79f0, 0xbcce4198, 0x3c895c2e, 0xbd02ae7d, 0xbc41749a, 0xbcfa24b4, 0xbcd941a9, 0xbcfca8ae, 0xbcbbb854, 0xbc205552, 0x3d03416d, 0xbc2c3266, 0x3cd1be9c, 0xbc78dc8a, 0x3c0a7dbc, 0x3cdcba4e, 0x3c4f7d18, 0x3ccbe278, 0xbc964cd0, 0xb957cf00, 0x3c7a4ca0, 0x3c9bfd10, 0xbb29a4e0, 0xbab92800, 0xbbea93f0, 0x3c01c884, 0x3c4e1bfc, 0x3ca1405e, 0xbd04a8dd, 0x3c97623c, 0x3ce4e09a, 0xbbaca234, 0xbc4bb730, 0xbcd13356, 0x3c176238, 0x3cbcada2, 0xbc919b45, 0x3c620020, 0x3ca76d18, 0x3c81756c, 0x3cb5b014, 0x3b8cad50, 0xbcaf6732, 0xbc2bfbb8, 0xbb82979c, 0xbcd79ed8, 0xbba46e9c, 0xba3c0d80, 0x3bf32790, 0xbccd0363, 0xbcfeb2d0, 0xbc7db252, 0x3ce3bbb0, 0x3cf11c6e, 0xbb10a498, 0x3cdaf408, 0xbba954f8, 0xbbfac770, 0xbcb84c47, 0xbaa2cca0, 0x3c6ea924, 0x3c0871ac, 0xbc072378, 0xbc5c908a, 0x3c57b600, 0xbc216d8a, 0x3c2fea2c, 0x3ba4a400, 0xbd083ef3, 0x3d00cfb5, 0xbc657028, 0xbcc1a685, 0x3b54d820, 0xbc144db4, 0xbbbe6254, 0x3ca97a1a, 0x3cb42dc4, 0xbc99521c, 0x3cd05c10, 0x3c367044, 0xbcb84358, 0x3a2aeec0, 0xbd0451ab, 0xbcfd23d6, 0x3cd36c8a, 0xbcd8a67a, 0x3bf86e78, 0xbcf56c07, 0x3a3f4d80, 0x3bdcd350, 0xbcf53e67, 0x3d00f3cb, 0x3a984440, 0xbc4f9d8e, 0x3b366650, 0x3cb74bec, 0xbc8b6ecf, 0xbc8f8a54, 0x3c328ba0, 0xbb32cd68, 0x3ca9a316, 0xbc8a87e3, 0xbc1eb4f8, 0x3cdd0c96, 0x3c1b1080, 0xbcf105c9, 0x3c9712d4, 0x3c7c721c, 0xbc6e1122, 0x3c0f9f2c, 0x3be70530, 0xbcfc1e7f, 0x3b8a9d00, 0x3cfbe32a, 0x3cd39d64, 0xbc6bc71e, 0xbcba1256, 0xbc2a8b38, 0x3bc427a8, 0x3b356e60, 0xbc856ada, 0xbc98bf2e, 0x3c831ab8, 0xbc87afbe, 0x3b178930, 0x3bbbddb0, 0xbc69e9b8, 0xbcc361f8, 0xbc504e2c, 0xbcb9d2be, 0xbc9f1b30, 0x3b7bc740, 0xbbb9d234, 0x3cfd5696, 0xbcd3fec3, 0x3b7f5a90, 0xbb764668, 0xbc55cc22, 0x3c9cc034, 0x3c54e4e8, 0x3b32f0c0, 0x3b4eabe0, 0xbabc2e40, 0xb923a200, 0xbad81480, 0x3ca45c6c, 0x3c6c9f44, 0x3b5d6f20, 0x3cc5c13c, 0x3cbef83e, 0x3ca1ccae, 0x3c1fced4, 0xbb840c00, 0xbbeb5b2c, 0xbc5854ac, 0x3c3ed580, 0x3ca2d572, 0x3d001821, 0xbcfd058e, 0xbc9c31e7, 0xbcd0513e, 0x3cbf8fd6, 0x3c141c34, 0x3cda3850, 0xbc99e2d0, 0x3d0631af, 0x3bf1ece8, 0x3c4b2df4, 0x3cb62e62, 0x3b43c0d0, 0x3c2bc42c, 0xbc05da80, 0x3cdc6088, 0xbce1ea56, 0xbce4b754, 0x3d0325b5, 0xbc1d286c, 0x3d03210f, 0x3cd20ef8, 0xbb98a0e8, 0xbc724886, 0x3990fe00, 0xbca9d589, 0xbd061335, 0x3ce563fc, 0xbcf42150, 0xbd06d273, 0xbc1a1d2c, 0xbba770a4, 0x3ab20820, 0x3c11c7ec, 0xbc4aab00, 0xbcc23ae3, 0x3c18e3e8, 0x3cba4b1e, 0xbcd0ad32, 0xbc82fab8, 0x3cf3a5a2, 0xbba4bfbc, 0xbc53dea2, 0xbb60a568, 0xbb9544a4, 0x3c4482a4, 0xbd022ff9, 0xbc70062c, 0x3bc5c6f8, 0x3c70e28c, 0xbc8fb583, 0xbcd33961, 0xba58d840, 0xbbb95e08, 0x3c781470, 0x3ca178c6, 0xbc4cc830, 0x3c5fae0c, 0xbc70129e, 0xbc56003c, 0x3cc643e8, 0xbc0f8cc4, 0xbc61bb06, 0x3b4bdf10, 0x3c5f44f0, 0xbc9ab350, 0x3c3f0adc, 0xbcb88bbc, 0xbb687d30, 0xbc8b0087, 0xb9c57500, 0x3c3d2f74, 0xbac66460, 0xbc1a1ace, 0x3c3e85bc, 0x3adb54e0, 0x3c88a206, 0xbce59fc5, 0x3c1d3fdc, 0xbc8e51b6, 0xbc08c38a, 0xbc9c1c36, 0x3ce2ee86, 0x3b8a11f0, 0xbc41dcec, 0x3caf8bf4, 0xbce48701, 0xbcab3300, 0xbb89681c, 0x3cb0231a, 0xbba1bdf0, 0xbc9cd35a, 0xbcf7a6b4, 0xbc4b7e4a, 0xbcfc3da3, 0xbce375ac, 0xbc0cad5a, 0x3bd99a88, 0xbd010fa3, 0xbc8e4f45, 0x3cf2f416, 0x39bdfb00, 0xbcf61814, 0xbc9dadd6, 0xbcec76c7, 0x3b63d250, 0xbc3d5a68, 0xbca98b4e, 0x3c532870, 0xbc891160, 0xbb82ab78, 0x3d05d893, 0xbcb4aafa, 0x3cabd366, 0x3cadef44, 0x3cf8e1e2, 0xbcf69896, 0xbc6b242c, 0x3c83ab98, 0xbcd96dc9, 0xbc5cf51a, 0x3c99d3d4, 0x3beb7cd8, 0x3ce729d2, 0xbc3bc430, 0x3a378d80, 0xbc3b44d6, 0x3c5909d8, 0x3cff20b6, 0xbcfebc2e, 0xbce4d2ba, 0xb9f32300, 0x3b9a8ea0, 0x3c85d8f4, 0xbd00121b, 0x3c7c43a8, 0x3cee57ca, 0xbc0c51ce, 0xbd0361fa, 0x3d0490b3, 0x3c64c36c, 0xbcad1fac, 0xbb1534e0, 0xbc844a6f, 0xbcae8670, 0xbaa58120, 0x3c15d028, 0xbb641f20, 0xbbdfe934, 0x3b0e7820, 0xbcff2025, 0x3cf6812a, 0xbcc6873e, 0x3cad7ca4, 0x3ceb95dc, 0xbcd5c158, 0x3cf7feba, 0x3c55b5c0, 0xbccfc980, 0x3cffb27a, 0x3b741d10, 0xbce142dc, 0x3d05e58b, 0xba3f8d80, 0xbd008da3, 0x3ce25cf4, 0xbb0e5ce0, 0xbbb0b5e8, 0x3ceee2e8, 0x3d057d6f, 0x3beed588, 0x3cc1d5b6, 0xbcf7c752, 0xbcb96b7a, 0x3cf6a0aa, 0xbc60a652, 0xbcb54eb4, 0x3c9f3698, 0xbce42ff2, 0xb8ad1600, 0xbcdf26e5, 0x3cf2c1a6, 0x3bcf89a0, 0xbbc7d5cc, 0x3c240b9c, 0xbcb2f600, 0x3bef1888, 0xbcd39687, 0x3cf4c39e, 0x3c29e8b4, 0x3cb3df62, 0xbc68a530, 0x3c05442c, 0x3cd53d1a, 0x3cc7c256, 0xbcdc8a2e, 0x3ce5b7b6, 0xbbe30b78, 0xbc8bddde, 0xbd048c9e, 0x3ab8d040, 0xbcf1b270, 0xbca48fe2, 0x3c48db6c, 0x3c61e860, 0x3c2b1e8c, 0xbcbe2dd4, 0xbcbaa53c, 0x3c1fdfd0, 0xbcf1ebd8, 0xbca668b6, 0xbb8c7100, 0xbc04cc84, 0x3ca11246, 0xbc83da2b, 0xbc34d780, 0x3cc96580, 0x3bf0f480, 0xbccb4ec0, 0xba9cfba0, 0x3ca1e24c, 0x3c5659ac, 0xbb0f6b30, 0xbcc21663, 0xbb912b54, 0x3c90beea, 0x3c4f32f8, 0x3b765a30, 0xbcfc58e7, 0xbc318ac4, 0xbd0644a7, 0x3c937c86, 0x3afb3fc0, 0x3cb73b0c, 0xb7c26000, 0xbb699530, 0xbcf043b2, 0xbc2215a2, 0xbc9e713a, 0xbbabffcc, 0x3d075a2f, 0xbd005a1d, 0x3c1f5124, 0xbc8ecbde, 0x3bc09798, 0x3cc5bb80, 0xbbd6e768, 0xbd014cd0, 0x3c4f5c80, 0x3cb3800e, 0xbcf17241, 0x3c9a5b24, 0x3d061bdd, 0x3ba66960, 0x3c39eedc, 0xbbb5efd4, 0xbc67a0ac, 0xbcabff78, 0x3ce71656, 0xbbdb2508, 0x3ce9e56c, 0x3cbdb776, 0x3ab1cda0, 0xbd031962, 0x3c88b13e, 0xbcbd6a98, 0x3c52e68c, 0xbcc5541c, 0x3c58af70, 0xbc8aa10d, 0xbaa88bc0, 0x3cf1b37e, 0x3cefde26, 0x3ceef896, 0xbbab2624, 0x3cbec2be, 0xbcdb6b34, 0x3c89d472, 0xbc5ab87c, 0x3cee7aae, 0x3c071668, 0x3cb1fee4, 0xbbbaf770, 0xbbb33ccc, 0xbcfa02dd, 0x3b88b5b0, 0xbbacec08, 0x3c4c7078, 0x3a533940, 0xbb93bd88, 0x3cdc79a8, 0x3d026b9b, 0xbc58cfca, 0xbd027e47, 0x39b43200, 0x3bb25e20, 0x3cb83290, 0x3caa280c, 0x3d08510b, 0x3c333000, 0xbc9b5b72, 0x3c90a6e6, 0x3c769bd0, 0x3c8f6ee0, 0xbc127ebc, 0xbce680f8, 0xbc067a3c, 0xbcda0f2e, 0xbc13b496, 0xbc3ae8b0, 0x3ca9727c, 0x3aeed180, 0x3c3204d0, 0x3cfc8cca, 0x3cc53674, 0xbcb47360, 0x3c5a9fdc, 0xbc691774, 0x3cab724a, 0x3ca55d6a, 0x3ca0cbfa, 0x3c397c24, 0xbc14075a, 0x3c1a7448, 0xbc73c378, 0xbca40365, 0xbcceed76, 0x3c83111e, 0x3c16b72c, 0x3b410060, 0xbd01924a, 0xbcaaf102, 0xbc59517c, 0xbc565b9a, 0xbcee76c5, 0x3c4747a8, 0xbc647d56, 0x3c9787ec, 0xbb72fea8, 0xbc4e057c, 0x39ed4500, 0x3cee9ac2, 0xbc0596e2, 0xb9f84800, 0xbcfb4f09, 0xbc4dcb68, 0xbcc20765, 0x3c9267b8, 0x3c69add0, 0xbbe132f0, 0x3b33e8c0, 0xbcd84309, 0x3c3adaf4, 0x3be8a278, 0xbc2a9744, 0x3b3003a0, 0x3c26b764, 0x3a7bbac0, 0x3bb76430, 0xbc584b92, 0x3b4c1390, 0x3ce6161e, 0x3ba96ba8, 0x3ce31d1c, 0xbc374df8, 0xbc731596, 0xb9437c00, 0x3cd9500a, 0xbcb266d2, 0x3c9e60ac, 0xbcc69550, 0x3ce4606e, 0xbc45f5c0, 0x3c96f756, 0x3c94550a, 0x3c53ef88, 0x3bf1d488, 0xbc46b02c, 0x3ca98d24, 0x3cf092a6, 0x3c6d5b20, 0x3c2cd21c, 0xbc4c64c4, 0x3c3010ec, 0x3bf333f8, 0x3c7e2550, 0x3ce84bb6, 0xbc95c87a, 0x3cefc47e, 0xbb963a34, 0x3bdfa580, 0x3c8f7bce, 0xbc682d4e, 0xbcfc9045, 0xbbc1b02c, 0xbb6739e0, 0x3bbc8bc8, 0x3bfe00c0, 0x3ca10ff4, 0x3bfbbf90, 0xbd076589, 0x3cc5eb02, 0xbc1d3b1a, 0x3c10a760, 0x3c5d67fc, 0xbbe5159c, 0x3cf10b0e, 0x3cc769a4, 0x3cd60c02, 0x3cc997c2, 0xbc8311f8, 0xbcf171e1, 0x3c4f4ba0, 0xbb8aaa3c, 0xbc326400, 0xbcf261d4, 0xbcd6541a, 0xbd07bbe6, 0x3b6e3cd0, 0x3b0a9030, 0x3ce36768, 0xbccdda09, 0xbcfdc752, 0xbd054829, 0x3a141cc0, 0x3c0c6b48, 0xbb949af0, 0xbc51638e, 0xbd07759c, 0x3cba70c0, 0x3cd7013c, 0xbbc33288, 0x3cef3a36, 0xbc627328, 0x3c918272, 0x3cc07d32, 0xbbb1064c, 0xbceea610, 0x3b189e50, 0x3cf292ca, 0xbcad085c, 0x3c511718, 0xbcf6b363, 0xbc8c3ada, 0xbac24260, 0x3cd05774, 0x3abc26a0, 0xbc693b56, 0x3cf0cd5a, 0x3bc29f90, 0xbc9beef4, 0x3cb18942, 0x3cd37d4c, 0x3c3dba5c, 0x3cf0106a, 0x3c99f240, 0x3c701eec, 0x3ccb8c6c, 0xbc579bb8, 0x3cde0450, 0x3cbf11bc, 0xbbe146ac, 0xbc2a5922, 0xbc3b8f8e, 0x3ce13fe2, 0xbc82a743, 0x3c76e5b0, 0xbcd67aac, 0xbbcda03c, 0x3c801036, 0x3bbf57f0, 0x39884100, 0xbcb5169e, 0xbcca37ba, 0x3c716cf0, 0xbc05b844, 0x3cd7b4fe, 0xbc28fdf0, 0xbca14a74, 0xbc1ba43c, 0xbc520640, 0x3d031b4b, 0xbcf8b3f6, 0x3ca639a6, 0xbcc63a49, 0x3caceaea, 0x3cc0a818, 0xbc124816, 0xbcfe1963, 0x3cb51a1a, 0x3ccfeb04, 0xbc65d6a8, 0x3a98a3a0, 0x3ce07b8e, 0x3ca3c49e, 0xbce333ae, 0xbc84e6be, 0xbc81e5d4, 0x3d087a8d, 0xbce9af4c, 0x3cccf4f2, 0xbc902272, 0xbcfc35ff, 0xbc9bee87, 0x3c9b95e6, 0xbb606558, 0x3cc2680c, 0xbbd6f708, 0x3cfe99e6, 0x3b575d40, 0x3ccd789e, 0x3c957b14, 0xbc7f4ff8, 0x3c99c940, 0xbb9b4310, 0x3c9cfc38, 0x3baf8ca8, 0xbc7d2b9a, 0x3bcc0388, 0x3cb47954, 0x3c9d434c, 0xbb5d5088, 0x3b830b78, 0xbc80bbe5, 0x3cf821c2, 0x3ca7ca72, 0xbcb63518, 0xbb06adc0, 0xbc4c0184, 0x3be5da30, 0xbcc41a1c, 0xbc23dea6, 0xbd029940, 0xbc9c843e, 0xbc9d29a0, 0x3ccd5438, 0x3cedfcec, 0x3cc17af8, 0x3cc77452, 0x3bb6ec48, 0xbc2d0d96, 0x3cafe94e, 0xbb8c751c, 0xbcec9fce, 0x3cc950c2, 0xbc4d007c, 0xbca16ada, 0xbbd06b24, 0xbc42afb0, 0x3be33c68, 0x3b45c1e0, 0x3c7652e0, 0xbc927a7e, 0x3b1e6ce0, 0x3caedb76, 0x3bcf77b0, 0xbcb5789e, 0x3cdeb7e6, 0xbc8ebc92, 0x3c1a7ad0, 0x3cdcb63a, 0x3c7faccc, 0x3d0699c7, 0x3c217944, 0x3be637f0, 0x3bacb788, 0x3c870712, 0xbd040b4a, 0xbb1eb6e0, 0x3cc4eb4e, 0xbc947985, 0xbca65ce5, 0xbc38e6ac, 0x3cf7a40e, 0x3bec0ba8, 0x3c8b3542, 0xba5ac280, 0x3ce15de2, 0x3cf57a0e, 0xbce80854, 0x3c6ef8b4, 0xbb7b8310, 0x3ce9e72e, 0xbc41c86c, 0x3c65a2bc, 0xbca8c174, 0x3c8dedb4, 0xbcf6252e, 0xbc66e10e, 0x3cab48b2, 0x3c5e095c, 0x3c7e8aa0, 0x3cd19b9c, 0x3ac46ae0, 0xbc7ac2de, 0xbc21edf8, 0xbc909280, 0xbbefeb3c, 0xbc8e3a69, 0xbc1f7984, 0xbb4b6678, 0x3be1bca0, 0x3c35876c, 0x3c48161c, 0x3cf930a2, 0xbcdc4d34, 0xbce476bf, 0xbbd82808, 0xbcb32905, 0x3c3b3928, 0x3c92022c, 0x3c8a843e, 0xbc29f3e2, 0xbce40be3, 0xbcb7ddae, 0x3c9f751c, 0x3c8fa44c, 0x3cb4c8be, 0x3cbeb818, 0x3a9c7160, 0x3c965892, 0x3bc1efe8, 0xbb9d37e0, 0x3ce3048e, 0x3c00c710, 0xbcea4f90, 0xbca42307, 0xbd0511e6, 0xbbd287ac, 0xbca2cb8e, 0x3cb39332, 0xbd0648a0, 0x3c2bd55c, 0x3bb01130, 0x3b341990, 0xbd05ab39, 0x3b9ce9e8, 0x3ba790c8, 0xbb7fbb58, 0x3c64f2b4, 0xbb654188, 0x3cfe6f6e, 0x3ce35eb6, 0xbcde0238, 0xbc19c252, 0xbcda5d05, 0xbca0b232, 0x3cbdde16, 0x3cfbbeb6, 0xbcbb4e80, 0xbcbf95be, 0x39afd500, 0x3c89411a, 0xbcc2a912, 0xbc04b97c, 0xbbecbe60, 0xbcaa17f0, 0x3d07ec8f, 0x3c7f21b4, 0x3cea800c, 0xbc8728b6, 0x3cec756c, 0xbc9976fa, 0x3bb3cc78, 0xbca3d17c, 0xbc625056, 0xbc99576e, 0x3b0c6000, 0x3c31e3e0, 0x3cf2ecc2, 0xbd07c5c9, 0x3c8db84e, 0x3cfb7a6a, 0xbcba9927, 0xbbf6c808, 0xbc880f58, 0x3caf62fc, 0xbcabf752, 0xbc7a409e, 0xbcfcae4c, 0x3c559ad8, 0xbcb1e827, 0x3cf59b5e, 0xbcfbec1d, 0x3c495370, 0xbc895303, 0x3cca674c, 0xbb833500, 0x3c5cbe30, 0x3c0525a4, 0x3d07908f, 0x3cf26032, 0x3c12350c, 0x3a7728c0, 0x3ca2ef34, 0xbcc36b3e, 0x3c66bf50, 0xbcdbd674, 0xbc30c4a2, 0x3ccdf0e4, 0xbcba54ae, 0x3c7783c4, 0xbc756bb4, 0x3c35c734, 0xbd0082fe, 0xbbe8eabc, 0x3c8c534e, 0x3ca7e76c, 0xbc943814, 0xbce8dab2, 0xbbf1a94c, 0xbcf752f2, 0xbaf0d860, 0x3ce16e08, 0xbce67374, 0xbcb21812, 0x3d0856bd, 0x3cd63bae, 0xbcf4424e, 0xbd032756, 0xbc9b20e7, 0xbb29a300, 0xbc410c12, 0x3ba1b2a0, 0xbad8b9a0, 0xbcb7e769, 0xbcb4cef2, 0xbba5801c, 0x3bd98f00, 0x3ceb023c, 0xbc9e5f0b, 0x3b7a2040, 0xbce05b5a, 0x3cd893fc, 0x3cb2dd1e, 0xbcecf863, 0x3c5a0464, 0x3c6fec38, 0xbbcb5268, 0x3c356314, 0x3cf3658a, 0xbc222b80, 0x3c6f9afc, 0x3c173990, 0x3c177e50, 0x3c8ba066, 0xbcc6d7d0, 0x3c77710c, 0xbccc4b96, 0xbb2b2068, 0xbb2e7e10, 0x3c2e8224, 0xba3db0c0, 0xbce7baee, 0xbc3856c4, 0xbd01b3c9, 0xbcb100e2, 0x3c6930f8, 0x3c20e47c, 0x3c9fbaf6, 0x3cd6647e, 0x3bb56368, 0xbcda525c, 0x3ce10a0a, 0xbc1ddbf8, 0x3c51683c, 0x3d060601, 0x3c9ad062, 0x3cd984f2, 0x3cfbbdc6, 0x3bde9258, 0x3b8f5c40, 0xbd04871d, 0x3aff46e0, 0xbc02d9fc, 0x3abc5b60, 0x3cef1636, 0x3ccd2cee, 0xbb7329e0, 0xbc84e5da, 0x3c7c35a0, 0x3cb35d8a, 0x3cd3a1f4, 0x3ce64e9a, 0xbc380740, 0xbcf60a67, 0x3c808e92, 0xbc87e1e9, 0xbcf06450, 0x3cbc3f52, 0x3c9c1d54, 0xbcbac820, 0x3aac32a0, 0x3d0001bf, 0x3c4997cc, 0x3c2571ec, 0xbc902d7c, 0xbbf935e8, 0xbcc7c245, 0xbccd7234, 0xbcc67900, 0xbc99b096, 0xbc3ca092, 0x3c2e42a8, 0x3cb7fa88, 0x3c88c8ea, 0x3c1c8644, 0xbca3c64e, 0xbd072028, 0xbca1fc12, 0x3c92bf5a, 0xbd012dc2, 0x3b676500, 0xbc5a7ab0, 0x3ce5dcd4, 0xbbb3acf8, 0xba726b40, 0x3ce12880, 0x3b897a08, 0x3c3a72f4, 0xbc5ab9e8, 0x3b3248e0, 0xbcd90201, 0x3bdb89e0, 0x3bdb8478, 0xbcd3d9ce, 0x3b3d4f00, 0x3b4f6530, 0xbb275de0, 0x3c6d0078, 0x3cdb8ba2, 0x3c3e2bd0, 0xbcdd07ce, 0xbc68dbb0, 0xbc20a6ec, 0xbb506fe0, 0x3c0b0dd4, 0x3c9bd2f2, 0xbc564c4e, 0x3b43d8b0, 0xbb3cbd00, 0x3b7c7ef0, 0x3bc4e7d0, 0x3ab0a1c0, 0xbc668d6c, 0x3c8b3f06, 0xbc880d2b, 0xba83bac0, 0x3bcbd9c0, 0x3cde0f18, 0xbbdfac68, 0x3c637e04, 0xbc96cc89, 0xbcfd880e, 0x3cddc174, 0x3cee9530, 0x3c813408, 0x3c4590b4, 0xb9962000, 0x3c11daa0, 0x3c9fd4be, 0xbcea5c09, 0x3836c400, 0x3bd2de68, 0x3b877b78, 0xbd02aeb9, 0xbcaf2c30, 0x3d05996f, 0xbc08af56, 0xbbe46e90, 0xbbfb8370, 0xbce53234, 0xbc93e20e, 0x3be51740, 0xbc90ac34, 0xbcf8e2ee, 0x3c87d5b6, 0xbc9ef13e, 0x3cbc9f8e, 0xbc7e5b4e, 0xbbf17aa4, 0xbc97f374, 0xbb6d7b58, 0xbb8b8cf8, 0xbc1b6d40, 0x3cfcde36, 0xbcb75f76, 0x3ca94bb6, 0xbb88fd44, 0xbc8c2069, 0xbcbc8194, 0xbb0c0920, 0x3b9af440, 0xbc8f0820, 0x3b1a32b0, 0x3c66eb1c, 0xbcae0554, 0x3bba47e8, 0xbce5f709, 0x3cbe3f94, 0xbc40c856, 0x3cb44652, 0x3c554058, 0x3ce3e866, 0x3cf63efe, 0xbcdcbb9e, 0x3cd34ae8, 0x3c67f5b4, 0xbca49229, 0xb8b72800, 0x3b795730, 0xba269680, 0xbb0a52f0, 0x3a1e5b40, 0x3cac9cb0, 0x3d05c0cd, 0x3b5b8a60, 0x3cb55ea8, 0x3d03d343, 0x3cccd850, 0xbb00aa30, 0x3c834fba, 0xbc1caef4, 0x3bca8860, 0x3cada96a, 0x3bec4c00, 0xbd01bcdb, 0xbc39132c, 0x3c624468, 0xbcb6d45a, 0x3cb188b2, 0x3be5a708, 0xbcdb135e, 0xbcc60e3e, 0xbc7c659e, 0xbce52421, 0x3c3ac530, 0x3c2f57ec, 0xbc4a0d2c, 0xbcb957a0, 0x3be8b768, 0xbbde881c, 0x3b112800, 0x3c6750d0, 0x3c411de4, 0x3cd5e450, 0xbc9acca2, 0xbaeddc80, 0xbb67e758, 0x3cf3c0f6, 0x3d05b2a3, 0xbc78e5f0, 0xbc86b3c3, 0x3c268c20, 0x3c25ff7c, 0xbc980ceb, 0xbbf54c70, 0x3d00f9e7, 0x3c8aebb0, 0x3c53a918, 0x3c2023d0, 0x3b67ec90, 0xbc27bcf4, 0xbb6e2138, 0xba7412c0, 0xbb703f68, 0x3c071b14, 0xba141180, 0x3cca355e, 0xbd0719d7, 0x3cef542e, 0x3c2769fc, 0xbd02ed8f, 0x3ceff102, 0xbc49d9ac, 0x3c201944, 0x3a8797e0, 0x3bb35010, 0x3c61fb10, 0xbb410cd0, 0xbca7526e, 0x3aff70c0, 0x3cfabada, 0x3c6966a4, 0x3c21ce28, 0x3c8139c0, 0xbc88b823, 0xbcf53ee1, 0xbce3d583, 0x3cbc9ab4, 0x3cdb5076, 0x3bad9208, 0x3b8754c8, 0x3c1f79a4, 0x3c719390, 0xbc006762, 0x3cf31bbe, 0x3b4cb160, 0xbca374a0, 0xbcbc0e5e, 0xbcfc6b8e, 0xbccdcd1e, 0x3cc65ba8, 0x3b04b310, 0x3ccb4b2e, 0xbcbf553c, 0xbcc3ef94, 0x3bb47060, 0xbccf8e09, 0x3ab70140, 0x3bddcdd0, 0x3cc88b4a, 0x3c8ac2e0, 0x3d049ebf, 0xb9e41e80, 0x3c88d992, 0x3ca17420, 0xbc9e413c, 0xb95b4f00, 0x3c918796, 0xbb9e2a78, 0xbcd912a9, 0xbcb3ae74, 0xbc7c4dc6, 0xba96bc80, 0x3c9f1104, 0x3c2418c4, 0x3c42f3a8, 0xbcc5c938, 0xbc2270de, 0xbc3923ca, 0x3aab76e0, 0x3c2aab04, 0xbcf740a1, 0x3b775bf0, 0x3c928e92, 0xbc27098a, 0xb90e6000, 0x3c7625e8, 0x3b5eb9b0, 0x3b9afda0, 0x3cf5c6ae, 0x3c15adbc, 0xbc99da40, 0x3b7aa610, 0x3c8a9aea, 0xb9eec880, 0x3c75f54c, 0x3c41dcf0, 0xbc97cca7, 0xbb1be0e0, 0x3cc6812c, 0xbcd90949, 0x3c6238fc, 0x3c8fc6a4, 0xbc68ac5a, 0xbc7c2c1a, 0x3a26b840, 0x3ca012b2, 0xbca76638, 0x3cbeeaf8, 0xbc9cd3b8, 0xba8667e0, 0xbc86ab8d, 0x3c8c9b76, 0x3bf1c4e8, 0x3bbff6b0, 0x3c600800, 0x3c99e3aa, 0x3c890a4a, 0x3d04969f, 0xbd04baf5, 0x3cd59b58, 0xbcab04d2, 0xbd029f20, 0xbbdf3eac, 0xbc9ac0b6, 0x3acd0780, 0xbc2711c4, 0x3cd3f5fe, 0x3bb13e68, 0xbb692b48, 0xbc1d010a, 0x3ceed050, 0xba1fb980, 0x3c9b9f40, 0xbc46bfa8, 0xbd0237b6, 0xbce5c576, 0x3c89e490, 0xbc6e70f0, 0xbceb481a, 0xbca1088e, 0x3bcf9718, 0x3c85c988, 0x3c8f38a4, 0xbc837a8b, 0xbd084977, 0xbcc45a25, 0x3c26d850, 0x3d080d2f, 0x38ea2600, 0xbb8b5e60, 0xbb610a30, 0x3ca34eee, 0x3cbced10, 0xbc728ff0, 0x3c323508, 0x3c772628, 0x39261600, 0x3bcf35d0, 0x3ceff45a, 0x3be2bcc0, 0xbacc4800, 0x3cc3b5e8, 0x3cee2ab8, 0xbc9d042e, 0x3d0487a7, 0xbc8b69c0, 0x3cc214ee, 0x3c582cd0, 0x3c09bed0, 0x3c355288, 0x3d07cb3d, 0xba28efc0, 0x38e55800, 0xbc9eed30, 0x3cc53d4a, 0x3ccee898, 0xbc8325d6, 0xbcb64d29, 0xbcfb1b89, 0xbcc3eeb6, 0xbb63f8d0, 0x3b5d0920, 0x3c7f3260, 0xbc7eded6, 0x3b92da00, 0xbcd09772, 0xbc1aaeca, 0x3b887af8, 0x3b30f9c0, 0xbc1271de, 0x3c7bf480, 0xbbacc7c4, 0x3bf94050, 0x39eef700, 0x3cfe6be2, 0x3ba6fd48, 0x3cf0c08a, 0x3c864ec4, 0x3c3d8adc, 0x3c39ec04, 0x3c559018, 0xbcf57d98, 0xbb3b4998, 0xbc8bebe5, 0x3ce85a80, 0x3cd94612, 0xbc9c54eb, 0x3c863dd0, 0xbb1b4258, 0x3c520734, 0x3ca4d7f6, 0x3c23a534, 0xbcfd1249, 0x3c136ff8, 0x3c363e40, 0xbc0f48ac, 0x3cacbb8c, 0x3d002fe9, 0x3c3188b0, 0x3ca883a6, 0xbcecd078, 0xba64b400, 0x3cba0cd8, 0x3c2d21a4, 0xbcc0e6f2, 0x3cd5764c, 0xbbaa6ba4, 0x3a229640, 0xbc6aceda, 0x3c2807fc, 0xbc0424d2, 0xbc7c0b7c, 0x3d03326b, 0x3c9c079e, 0x3d0692e9, 0xbc815bed, 0x3bcbd930, 0x3ce50d8c, 0x3b92e060, 0x3b7653b0, 0x3b54a100, 0xbb925abc, 0xbcae2f30, 0xbc49f204, 0xbd041cb9, 0x3c25398c, 0x3c02e064, 0xbbb6a7b4, 0xbcd2ab4c, 0xbb3b6810, 0xbd062bf0, 0x3c831b96, 0x3cb250f4, 0xbace1f20, 0xbd063cb8, 0xbd04f07d, 0xbc5c98ca, 0x3cd69f0c, 0x3cab93d8, 0xbca46390, 0x3ae56760, 0x3c82fb20, 0xbb7d0920, 0xbb598410, 0x3ced847c, 0xbcf9a16c, 0xbbf6d2a4, 0xbb5fc100, 0xbbf5ec70, 0xbc289f9e, 0x3ccbd2b4, 0x3cb125fc, 0xbcc87a74, 0xbcad2560, 0x3ae0a400, 0xbc46ea3c, 0x3bdbeb90, 0x3ccab62c, 0x3d085bd7, 0x3c8defee, 0x3a4ab140, 0x3bae9858, 0x3cac64ac, 0xbc0f6640, 0x3c48f0f8, 0x3b58d8c0, 0xbca89036, 0xbae91ca0, 0xbca5905c, 0x3d021283, 0x3cc9d1bc, 0xbb641230, 0x3cb019ac, 0x3c3106f8, 0xbba6462c, 0xbcb789f6, 0x3b0e20c0, 0xbd028913, 0xbc54c412, 0xbcc32ef2, 0xbc24a00e, 0xbc842a83, 0xbc560b70, 0xbc80f1f4, 0xbcd5a765, 0xbce8c83a, 0x3cd8b576, 0x3d0865c3, 0xbc89f578, 0xbb8213e8, 0x3c7a3ef0, 0x3c9a6d98, 0x3ccfd996, 0x3d0845b9, 0xbc81acfa, 0xbc2001d2, 0x3ce472ec, 0x3cb135c2, 0x3b0551d0, 0x3cc4c242, 0x3cd884d6, 0x3b3b1850, 0x3c7c5150, 0xbc7517ca, 0xbc21301a, 0x3c7bc704, 0x3d08556f, 0x3bb73d70, 0xbb211778, 0x3cac175e, 0x3c6b1df0, 0xbd04d460, 0x3cd28a76, 0xbc868687, 0x399dd180, 0xbc807a20, 0x3ac527c0, 0xbc811eba, 0xbcb3afc7, 0x3cfc0b46, 0x3bb40008, 0xbc7a8480, 0x3cfa7bee, 0x3ce051c2, 0xbcc7c13c, 0x3cc39354, 0xbccf8f92, 0x3cfec29a, 0x3ae72640, 0x3c913058, 0xbcbfbdd6, 0xbccf56ba, 0xbc0d2c34, 0x3c181fd4, 0x3cfedab2, 0x3c32d850, 0xbc686362, 0xba947f20, 0x3cf212ea, 0x3ce684ac, 0xbc8232b6, 0xbc611812, 0xbb1a0558, 0x3cde538c, 0xbca671d6, 0x3c6983b0, 0x3b982af0, 0x3cd71bbe, 0x3ce264dc, 0xbccc30b0, 0x3d07925b, 0xbb888cd4, 0x3c1a6750, 0xbc925e05, 0x39cde380, 0xbcca592c, 0x3c993e04, 0xbbd516e0, 0xbcd39436, 0x3c3f6948, 0xbcb53bde, 0x3c217a80, 0xbc734b9e, 0x3bc88528, 0xbd001508, 0x3c6ddefc, 0x3cc3da62, 0x3c8492e0, 0x3baa9d08, 0xbcd78e4e, 0x3ccdddf6, 0xbd076d9f, 0xbca14969, 0xbc89477c, 0xbc7c7d5e, 0xbb3e9b78, 0x3cba6fd8, 0xba1ed040, 0xbc9f92a2, 0xbcdc14b8, 0xbc12d940, 0xbca06225, 0xbb73b498, 0xbcf71387, 0xbca9c7e7, 0xbc401bde, 0x3d027ebd, 0xbce5ac21, 0x3bb2dd60, 0x39b74e80, 0x3cac36a6, 0x3cee8dc6, 0x3ca42f80, 0xbca80fb8, 0xbca1a9ce, 0x3cd02acc, 0x3cff8f36, 0xbcb035a7, 0xbc86df36, 0x3c895d9e, 0xbb010d50, 0x3c3fbe24, 0xbca37372, 0xbbd679f8, 0x3c0e3900, 0xbcded5f8, 0xbc362b28, 0x3cfb7202, 0xbc224740, 0x3c6f4b60, 0x3b249ea0, 0x3ce1555a, 0xbc5efff8, 0xbc72b468, 0xbc0aef2c, 0x3cc4659a, 0xbaad4380, 0xbcc72a7e, 0x3b05b830, 0xbc906625, 0x3d03b25f, 0x3c8675d2, 0xbb020940, 0x3b870b18, 0x3c6ea2ec, 0xbc839ed2, 0xbc95022b, 0x3cdd0efe, 0x3c8e6b94, 0x3c6b2ae4, 0xbd01e45a, 0xbcd3c912, 0xbc4f0b16, 0xbcfbd26c, 0x3d012885, 0x3cf7cc6a, 0xbcc5f110, 0x3cfb654a, 0xbceb9478, 0xbd066a7b, 0x3cb263ce, 0xbd075302, 0xbca2b105, 0xbc8ae6b4, 0x3cdc000c, 0x3c99a3ac, 0x3c66e8ac, 0x3b73a580, 0x3c6f9658, 0x3cb3f92c, 0xbb1ac588, 0x3ae51580, 0x3c455478, 0x3b72a730, 0x3cc69b20, 0x3cf0bd3e, 0x3c2fc1b8, 0x3c881b76, 0x3c228438, 0x3c8202d8, 0xbc8f8cb4, 0xbc19790e, 0xbce8c5a9, 0xbc9bb7fa, 0xbd042ab2, 0xbc09cada, 0x3ceff31e, 0xbcc53527, 0xbc20125e, 0x3cfb50e6, 0xbc8a1f1c, 0xbcf064d2, 0x3c0a9a44, 0x3c2ffb74, 0x3d06df61, 0x3c85cb60, 0x3b0f1cf0, 0xbca1daa5, 0xbc626fc0, 0xbcf89569, 0x3ca82902, 0x3cfa151a, 0x3c4d1cb8, 0x3c95953e, 0x3c75e4c0, 0xbc96a1a5, 0xbcadb9e9, 0xbb564ad0, 0x3c9fd6ca, 0x3c11103c, 0x3c781618, 0x3d01b7cd, 0x3c9a5332, 0x3c81b95c, 0xbca25ecb, 0xbcd0462c, 0x3ba95b00, 0x3b100a60, 0xbc167680, 0xbc71a5b4, 0xbd05eace, 0xbc55eff8, 0x3bc1d7c8, 0xbcf8a26c, 0x3adf2040, 0x3c973cc2, 0xbc299eac, 0x3cd58596, 0xbc4936b0, 0xbbaf8210, 0xbcded001, 0xbd04c3fd, 0xbc5055f8, 0xbbde7dd8, 0xbcbcff9a, 0xbcd688a7, 0x3bc759e8, 0xbc715d1a, 0xbcdfe1c9, 0x3c59054c, 0x3d00e963, 0x3c310d6c, 0xbd00c913, 0x3ba053b0, 0xbc9ea8d2, 0x3cb64da4, 0xbc4c1f3c, 0x3c99e57e, 0xbce09e7c, 0x3c221940, 0xbcc2b3f8, 0x3c2f0d0c, 0xbc05d274, 0xbb07ae90, 0xb9f01500, 0xbbf8c744, 0xbc79be5a, 0xbcd1f01c, 0xbccee11a, 0xbcd6c525, 0xbcd31621, 0x3b5daec0, 0x3ad21080, 0x3b0bd470, 0xbbcdfb60, 0xbcfa1036, 0x3af4e9c0, 0x3c58bc58, 0x3cae1f16, 0xbb8ac8d4, 0x3cd874fc, 0xbcef4496, 0x3d077d85, 0x3c53131c, 0x3bb24160, 0x3c8f6ba6, 0x3c8789e2, 0x3c30b3a4, 0xbc92e285, 0xbcc14d50, 0x3c8ae082, 0x3bee3e48, 0x3b6be940, 0xbd0663dd, 0xbc26f4e2, 0x3b98eb48, 0xbcfdd825, 0x3c1208d4, 0x3cb6d790, 0xbbc5863c, 0x3cc3db4a, 0xbcc25c52, 0xbc8a5f9a, 0x3c512028, 0xbc88a30f, 0x3affbc80, 0xbcd9dae1, 0xbcea2bd4, 0xbd041e89, 0xbc510d9e, 0xbc331eb4, 0xbc83865e, 0xbcbaacc3, 0xbbe884a4, 0x3c7a9b78, 0xbc0aab38, 0xbc71dfca, 0xbcd10df4, 0xbc8911f8, 0x3c5b59e0, 0xbb2fa448, 0xbbcf8d34, 0xbcb92fbc, 0xbccb8ca9, 0x3a8387a0, 0x3c64f1b8, 0x3ba10cc0, 0xbc8f796d, 0xbbd9941c, 0x3d023095, 0xbaa41f80, 0x3c718c68, 0xbbf14b08, 0xbbe2ad60, 0xb9fde580, 0xbcc5e63a, 0x3cd9545e, 0x3ccd066e, 0xba9188a0, 0x3cb0637c, 0xbccafae9, 0x3ca6512c, 0xbcaf97b2, 0xbc9e2b67, 0xbbbe9c00, 0x3cefd74e, 0x3c44fad8, 0xbcbfd7e3, 0xbcf8ffb8, 0xbc0d3f80, 0x3c944bbc, 0x3d0284d5, 0x3cf31682, 0xbcf6e33a, 0x3becadb8, 0xbcdb1f76, 0xbca29585, 0x3cf70a36, 0xbce64ce1, 0x3cbf21f6, 0xbb86accc, 0xbb82d144, 0xbb86e2a4, 0x3cb144ee, 0x3c41b0ac, 0x3c29d500, 0xbd02ccfd, 0x3c295bdc, 0xbbd50ff8, 0xbc20074a, 0x3c1185ec, 0xbcb8bd8c, 0x3cc662ce, 0xbc02e3da, 0x3ba90f28, 0xbc7e4d5a, 0x3c7bb3e4, 0x3c7578c0, 0xbc8638f4, 0x3c8932e6, 0x3bcb98b0, 0x3cffe982, 0x3bd15de8, 0x3c11511c, 0xbb74d2e0, 0x3c397ec8, 0x3c5a8b5c, 0x3b4b3f10, 0x3c925614, 0x3bb4fdf0, 0x3b437ee0, 0x3bdca5c0, 0xbced3e05, 0x3cf667ba, 0xbc490970, 0x3c25bd30, 0x3ae84600, 0x3c3daa0c, 0x3cb48bba, 0x3c92b91c, 0x3ce8accc, 0x3c6806f4, 0x3c474b98, 0xbcbda465, 0xbc282952, 0x3ba98f00, 0xbd015790, 0xbb75dac0, 0xbc8958a0, 0x3ce9ecf8, 0xbc7ac2f8, 0xbc35c722, 0xbcd5724c, 0xbb970b70, 0xbcfac23f, 0xbc59223c, 0x3d064b6b, 0x3cd9edf0, 0xbc996b56, 0xbc87ae27, 0xbccc0b52, 0xbb9f8ef8, 0xbca4b58e, 0xbbe28f60, 0x3be20178, 0x3bd416c8, 0xbca49a65, 0x3b57e510, 0xbc5c1822, 0x3cf8b3fe, 0x3c725b78, 0x3ca8bad8, 0x3becbf40, 0xbc896c76, 0x3bcbe6c8, 0x3c882fb0, 0xbd06f482, 0xbc89658b, 0xbcf8d2b4, 0xbc6a5ef0, 0x3bf410c0, 0xbc91a6fe, 0xbcfaa2e5, 0x3cfa6bb2, 0xbcbf90fc, 0x3ce321b4, 0x3c8cd4e2, 0x3cb4ed6e, 0x3d07058f, 0xbb913f68, 0xbc30e016, 0x3cfba0be, 0x3cafb562, 0xbc7afca8, 0x3c760d78, 0x3cffd0b6, 0xbbfa40a4, 0xbb652320, 0xbca00bb8, 0x3cb2cf52, 0xbc2cb5e6, 0xbb24c730, 0x3bbf30f0, 0x3ca9129e, 0xbc110734, 0xbc95aa5c, 0x3b5d6200, 0xbb779658, 0x3c21a1e0, 0xbba74de8, 0xbc8114cd, 0xbc7a81f4, 0x3afc0960, 0xbbbe3368, 0x3cb80172, 0x3c5be36c, 0x3ccbf4f6, 0x3cfe4eea, 0x3d03d2c3, 0x3d010235, 0x3bdc42d8, 0x3cb27b2c, 0x3c97042c, 0x3bd8df90, 0xbc1548fc, 0x3cbc4482, 0x3c3557f8, 0xbc93bfc2, 0x3cdb6014, 0xbc4df98a, 0x3cc0033c, 0x3ba6f1e0, 0xbcdd3bc9, 0xbc0b12ce, 0x3c9b0eb2, 0xbba77be0, 0x3caffcbe, 0x3c5cad38, 0x3ccb8db2, 0xbc431178, 0x3a33fa40, 0xbc8160d6, 0x3bbcf268, 0xbc4bef80, 0x3d07b6b9, 0x3a0c3300, 0xbbeb6a80, 0xbcaf4190, 0xbcd16ca7, 0xbc6da080, 0x3ceb5bee, 0xbb9f38cc, 0xbc00d192, 0x3b785300, 0x3c06b97c, 0x3b93c240, 0x3c8bd8b4, 0x3cfa14fe, 0x3c568320, 0x3ca499da, 0x3c2a230c, 0x3c19eff8, 0x3c2482e0, 0xbb3d2220, 0x3c5f90a8, 0xbc56b300, 0x3c15a410, 0x3cbe3234, 0xbaed7980, 0x3ce88b92, 0xbca9491e, 0xbcee77f2, 0x3ca6fbfa, 0x3c29c8ac, 0xbbea649c, 0x3bb58118, 0x3cdb2380, 0xbc98d760, 0x3c42f7a4, 0x3d0277ed, 0xbc16893c, 0x3cfe39f2, 0xbcf99b8c, 0x3d030f63, 0x3cee1518, 0xbcf60b83, 0xbc48bcd6, 0xbd0517d7, 0xbcee31c5, 0x3c5551e4, 0xbcb993e0, 0x3c0a2330, 0xbca4f350, 0x3c697358, 0x3c3a4504, 0xbcad56dc, 0xbcdab9a9, 0xbca75e82, 0x3d06e983, 0x3c5a71a8, 0x3c9e62de, 0x3c1dd1e0, 0x3bf23190, 0xbc8f3a9a, 0x3cf537c2, 0x3c242040, 0x3a120040, 0xbbdd1ecc, 0xbca04b92, 0x3be20df8, 0xbc84a4b6, 0xbb8f3ec4, 0x3c83d1da, 0x3bb453c8, 0xbc24b8fc, 0x3cc4ba92, 0xbcb09eae, 0xbc2fc592, 0xbce635b0, 0xbcc36103, 0x3c2033fc, 0xbc80c620, 0xbc5c8a62, 0xbd00982d, 0xbc367e52, 0x3c94e682, 0xbb18a588, 0xbcf5cf30, 0xbcf262c5, 0x3cdd5952, 0xbc64d3e8, 0xbca6c907, 0x3cf0221e, 0xbcab3122, 0xbcc67483, 0x3cdbee8a, 0x3ab36c60, 0xbd055b2b, 0xbd0171ad, 0x3cddc1d4, 0x3c78b6cc, 0x3cb1c924, 0x3ce5a9b2, 0x3cf4562e, 0xbc7189ce, 0x3cc552be, 0xbc01984e, 0xbbcc9558, 0x3c82857a, 0x3ca8b45a, 0xbc0d5038, 0x3c8a2784, 0xbcd209ac, 0x3cbfac22, 0xbc903992, 0x3ce3dd7e, 0x3c4ade90, 0xbb8d8388, 0xbc0bf322, 0xbce40b12, 0xbc08d2c4, 0xbbcf3f10, 0xbc9dbcd8, 0xbb757868, 0xbc133c56, 0xbc3b3884, 0xbbc0ea44, 0xbbcc339c, 0x3bf3e970, 0x3c612c38, 0x3c9aea24, 0xbca0e329, 0xbc8f8ce5, 0x3b391e20, 0x3c0743d4, 0xbc7100b4, 0x3c64efc0, 0x3cbd34f2, 0xbc091d9e, 0x3b8f85d8, 0xbce1e112, 0xbcf83f38, 0x3c844576, 0xbb518158, 0x399b3200, 0x3ca199f0, 0x3cf71c4a, 0xbbd42b10, 0x3cbde68e, 0x3b3decf0, 0xbce11d87, 0xbb0cc078, 0xbce45c32, 0x3c43f468, 0xbb547598, 0xbbaadf00, 0x3cab0e3c, 0x3cce26f0, 0xbbb28100, 0xbaf39ec0, 0xbccbc369, 0xbae36720, 0xbc43dd6c, 0xbc3d8eb0, 0x3cf4d142, 0xbcbafd72, 0x3c32f6e0, 0xbb84964c, 0x3bbd58f0, 0xbb878990, 0xbce332e1, 0x3ca67338, 0x3cdf8a1a, 0xbcce5a47, 0x3ace26e0, 0xbb9b8b34, 0xbc85f0f8, 0xbcc4c730, 0xbca5c9d6, 0xbc952af6, 0x3c0ab3dc, 0xbb0f0878, 0x3cbd885c, 0xbb859890, 0x3cedb1ba, 0xbab99e80, 0xbc58f14a, 0x3bb51110, 0x3ce09932, 0xbcb5d9ac, 0xbc73df40, 0x3cd64410, 0x3cc52fc0, 0x3b025c20, 0x3bf84140, 0xbcd92003, 0xbc7f8a78, 0xbd04a714, 0xb8ed9800, 0xbc6b9700, 0x3c4903fc, 0xbcfe6c32, 0xba821420, 0x3c224138, 0xbcde6e72, 0x3bfcb690, 0x3c179a88, 0xbc94245a, 0xbcd2b4f8, 0xbc17d444, 0x3cdb2d12, 0xbd031c6b, 0xbcff77e7, 0xbbc303e8, 0xbcaef625, 0xbbfc5058, 0x3d077697, 0xbcc22e94, 0x3c5585e8, 0xb732e000, 0x3c51abb4, 0xbc60da30, 0xbcccd774, 0xbc90ca76, 0xbb8a7e70, 0x3cf46ba2, 0xbc615830, 0xbc1be238, 0x39ac7580, 0x3c451fa8, 0xbcdd102e, 0xbcddcf76, 0x3ceb918a, 0xbcedd2fc, 0xbba2954c, 0x3ce29b2a, 0x3cf9262e, 0xbcd8746e, 0x3c3c5b8c, 0x3d00f4b5, 0xbc7566ec, 0x3cf1e40a, 0x3cb4efca, 0xbd03898a, 0xbcbb4f43, 0xbc3fee78, 0x3cfefe7e, 0x3b98c750, 0xbd00a394, 0x3bead0d0, 0x3b8a2f80, 0xbca7883e, 0x3d03f5c5, 0xbcb2ada9, 0x3be4b8d8, 0x3cdd4c7e, 0xbc8a4bde, 0x3c054e94, 0x3ca5bba6, 0x3c0da66c, 0x3cb9a6da, 0xbc93ca69, 0x3ca89d66, 0xbbed9090, 0xbd02fca0, 0xbc7b4962, 0x3c16b6f4, 0xbc105e62, 0x3c88fb06, 0x3cee3aec, 0xbcda8176, 0x3b18c550, 0x3c6f9088, 0xbc7a4678, 0xbcdf5f03, 0x3d048979, 0x39974780, 0x3c1bafc4, 0x3c32731c, 0x3cdb015a, 0xbd072fcb, 0xbb909b70, 0x3caafcee, 0xbca9a702, 0x3ce50694, 0xbcb946ae, 0x3c5a4d8c, 0x3c776370, 0x3cb47aee, 0x3b144e30, 0xba2ecbc0, 0x3cdd2cfa, 0x3c0c5e8c, 0x3b90be48, 0x3ce13622, 0x3b60c960, 0xb9ad5200, 0xbccc3952, 0x3c839c24, 0x3cd6cd3a, 0x3c8a5350, 0xbc90c652, 0x3c273a8c, 0xbc496e04, 0x3ccec760, 0xbc3d8130, 0x3c9a5790, 0xbccf7927, 0x3c9850bc, 0xbc8c5036, 0xbc1998b0, 0xbccc6cb4, 0xbcabe992, 0xbc6b5956, 0x3cfa5006, 0x3c63f6ec, 0xbc03a9c0, 0x3c1c9514, 0xbc65e956, 0x3c811300, 0xbb8cdd08, 0x3cab34e2, 0x3ccf0678, 0x3c60903c, 0xbce9cab0, 0x3cff91ee, 0x3b0a9290, 0x3c909fe2, 0x3c01e3ac, 0xbcf09eb0, 0xbcc7fdd8, 0x3b25ac50, 0x3a787440, 0x3cf41662, 0x3c102f14, 0x3a304a40, 0x3b4fb7b0, 0xbd025e8e, 0x3cd64278, 0xbc0cf13c, 0x3bf58f40, 0xbd072855, 0x3cecd648, 0x3bbb0928, 0xbc2ce778, 0xbc309b12, 0x3b8c99f8, 0xbba8f370, 0x3cf43a86, 0x3bd94668, 0xbcaa5e18, 0xbbb6161c, 0x3b95dbf0, 0x3c6dbcc4, 0x3c8d5b24, 0x3c7c49f4, 0xbccf4cd0, 0x3bf82f70, 0xbce838f2, 0xbcc86ddc, 0xbcbbf870, 0xbc9286d8, 0x3cc315b6, 0xbc0d1ab4, 0x3d041bc1, 0xbcc2ced0, 0x3c898e6c, 0xbb01c8b0, 0x3c78fca4, 0x3c88b30a, 0xbb1d6500, 0xbcb29607, 0xbc55b7f4, 0x3b6541a0, 0x3c3adaa4, 0xbc4b6e0a, 0xba310b00, 0x3cad7e60, 0x3cd3bbea, 0xbd0710f3, 0x3bf99a28, 0xbcee6783, 0xbcd1fbc3, 0xbcff8c32, 0x3b2de760, 0x3c85e2bc, 0x3c225a0c, 0x3c7089ec, 0x3cfadfee, 0xbb39f700, 0xba9c4c40, 0x3cc2587a, 0x3ad98420, 0xbc891b3a, 0x3c929484, 0x3c5b714c, 0x3cb77140, 0x3c81fb3e, 0x3c1ddddc, 0xbc272b74, 0xbc8004d4, 0xbcf83f81, 0xbca40800, 0x3cee3c16, 0x3cdcf55c, 0xbc9bd5eb, 0x3b31c050, 0x3cc192ba, 0xbad2f7e0, 0xbc8bcad2, 0xbcabec49, 0x3c3e5cbc, 0x3ca47d1e, 0xbcb624b8, 0x3cacd350, 0x3c86b740, 0x3bcacca8, 0x3ce795fe, 0x3c865f94, 0x3c335cc0, 0xbc48b09e, 0x3c8c6676, 0x3cf56e2e, 0x3cfad54a, 0xbbd5094c, 0xbcb5f870, 0x3be0d910, 0xbc2003d6, 0xbcf35f85, 0x3c974afc, 0xbc11e692, 0x3cb93bf0, 0x3c8e9842, 0xbc777a22, 0x3ce3b1fe, 0xbc9649ae, 0xbcfd9416, 0x3cfb7b7e, 0x3c6dd6c4, 0x3ca5f416, 0xbc6846b4, 0xbc3d9430, 0x3c3a61c4, 0x3b080ee0, 0x3c854c2c, 0x3c86e442, 0x3ce59e08, 0xbcbf9792, 0xbcb9fb6e, 0x3c6674e8, 0xbca52d89, 0x3bef2858, 0x3c5ca048, 0x3c9328ea, 0x3c8429cc, 0xb9b56600, 0x3d017dbb, 0x3b80d380, 0x3cd5f764, 0xbcc2c9dc, 0xbb00f2c0, 0x3cbaf692, 0xbc4dc70a, 0xbc816274, 0xbbcffbac, 0x3bce7118, 0x3bc7da10, 0xbc9f8512, 0xbc97a6de, 0xbc1469da, 0x3c9269aa, 0x3cb89544, 0x3c9b692e, 0xbcb2dc30, 0x3cc03fda, 0x3ced6b48, 0x3c4be2cc, 0x3cd1fb1c, 0x3ca287bc, 0xbb83eef8, 0xbceaba38, 0x3cc1bcec, 0x3cc20e14, 0xbc09d316, 0x3c77650c, 0xbc87d1eb, 0xbc1040b4, 0xbc9dfc90, 0xbc46351a, 0xbcd19b52, 0xbd03ecdd, 0x3c53e170, 0xbcc6cfde, 0x3cdf14ee, 0xb942ba00, 0xbba498bc, 0xbaf51ac0, 0x3caf214e, 0x3c91eaca, 0x3c4d1248, 0xbb66c120, 0xbcffc134, 0x3cd3cccc, 0xbcc0de12, 0xbc3f1452, 0x3cdf777c, 0xbc153456, 0x3a8a4280, 0x3b5c5210, 0x3d063d21, 0x3c9819dc, 0xbba7f3e8, 0xbc98f1c9, 0xbb7237e0, 0xbc296ad2, 0x3cf493a6, 0x3cea3096, 0xbcd7aaf0, 0x3cdc22fa, 0x3c37b5e0, 0x3bc3b6f8, 0xbc6cef70, 0xbcbac443, 0x3cf74e7e, 0x3cbb6b94, 0xbcb887a0, 0x3caf44ca, 0x3d0586ed, 0x3cf087be, 0xbcf1b8c3, 0x3c409c94, 0xbc2ea070, 0x3c838c5a, 0xbcfd5a52, 0xbc9a106e, 0x3cad01e2, 0xba5887c0, 0xbcb81a8c, 0x3a28d4c0, 0x3c93d4cc, 0xbbec2890, 0x3c14e20c, 0xbbb3e588, 0x3b901de0, 0x3cb4c838, 0x3ce3cdaa, 0xbca2c660, 0xbca49e52, 0xbb3b1a10, 0xbc89c3a9, 0x3cc9e23a, 0xba077a40, 0x3c8dee9c, 0xbb0f8200, 0xbcca77b6, 0x3d01b6a3, 0xbc93a207, 0x3cd24e4a, 0x3b28fb80, 0xbcddc2c9, 0x3c81739a, 0x3c7d9378, 0xbc1b41d6, 0x3d0482fd, 0x3cdfd30c, 0x3c1b70bc, 0x3c8c97f6, 0x3cfc96f6, 0x3ce5d134, 0xbc86b83e, 0xbbde6800, 0xbbbc5390, 0x3c067db4, 0x3b36df80, 0x3c39c950, 0xbc8e241e, 0x384f4800, 0xbc8cca16, 0xbcc9d752, 0x3cc3ac4e, 0x3c58509c, 0x3cd915d8, 0xbb54c4f0, 0x3bca4118, 0xbac029c0, 0x3cfe645e, 0xbcbcafc9, 0xbc647f3c, 0xbc13e252, 0xbceb0dd6, 0xbc7c4280, 0xbcf4ee38, 0x3c9385e6, 0x3cc63156, 0x3c065614, 0x3bf66ce8, 0xbb219cd0, 0xbc8922e7, 0x3c2350c4, 0x3cfd73ce, 0xbb4c2648, 0x3d06b483, 0xbcc5490c, 0xbced9a3a, 0xbc5290e8, 0xbcc0f476, 0x3b033bd0, 0xbc2d1796, 0xbc10aed6, 0xbcf2762e, 0xbc2d2d2c, 0x3ceb5f4a, 0xbd072fe4, 0xbcf5f3f0, 0x3bf4c740, 0x3a7e76c0, 0x3ce2cf78, 0xb9c43800, 0x3c69976c, 0x3c07f838, 0x3ca754d8, 0xbbfd4890, 0xbcea7156, 0x3cfa4c52, 0xbbf6dc70, 0x3bf03178, 0x3ca5242c, 0x3cd0dfb4, 0xbbd57290, 0xb9ded580, 0xbbb8849c, 0xbc57defc, 0x3b0e5140, 0x3cf08bee, 0x3b6479b0, 0x3c19fc50, 0xbca7996e, 0x3cb4989e, 0xbca6f685, 0x3b905770, 0x3c943ad8, 0x3cb9a884, 0xbd02fb7f, 0x3c324520, 0xbced2467, 0x3c32c130, 0xbc45e6fc, 0x39c59100, 0xbcc75434, 0x3c33ddfc, 0x3cdd3ac8, 0xbb7d1b98, 0xbcaab509, 0x3ca6efb2, 0xbc932129, 0x3bacdb10, 0x3cc83ef4, 0x3c49206c, 0xbc913570, 0xbca464ab, 0xba8fd3e0, 0x3c53e098, 0xbd01d96e, 0xbbc080ac, 0x3bd3ec18, 0xbcdc0fac, 0xbccac752, 0x3cd04de0, 0xbcef8683, 0xbcc73d98, 0x3cd46090, 0x3c49129c, 0xbc90860d, 0xbb620900, 0xbce16cd6, 0x3c73b068, 0x3cc1cca4, 0x3c9f8cb0, 0x3c0ae7bc, 0xbd007e70, 0xbc6bf64a, 0x3c10ce40, 0x3c806842, 0x3c6b8f9c, 0xbb149d30, 0xbc943165, 0xbba8c2f8, 0xbc6602ca, 0x3bf70880, 0xbca78598, 0x3bd60950, 0x3c91b7b6, 0xbc028270, 0x3b95c258, 0x3bd31868, 0xbcb8cf4e, 0xbadefb80, 0x3cc43e7a, 0xbc60cb92, 0x3b84f658, 0x3c9a6fdc, 0xbc5bbd00, 0xbc0e2aca, 0xbc035cfc, 0xbc90d0c9, 0xbcaac33a, 0x3b30caf0, 0x3c295ce8, 0x3cb869b0, 0xbbf15acc, 0x3cd54d8e, 0xbbe3bbf0, 0xbb5b04d0, 0xbbe1b92c, 0x3c000814, 0xbceca496, 0x3b779400, 0xbbc76cb4, 0xbd00f6b4, 0xbc8d933c, 0x3b868df0, 0x3cf0f66a, 0xbc82fc69, 0xbcf99e34, 0x3cb27ace, 0xbcd55074, 0xbc1ab3ac, 0xbc8a19fa, 0xbce33b2c, 0xbca12f94, 0xbb80169c, 0x3cc3a4e4, 0x3c97d420, 0xbcc23a58, 0x3cb51f92, 0x391c5e00, 0xbcd65816, 0xbc2689ac, 0xbc8ffebc, 0xbcba6b65, 0xbcbdf2c0, 0x3c0cc57c, 0xbc5d92e2, 0xbac82ae0, 0xbc237ea6, 0x3b7791a0, 0x3cff167a, 0x3cb9dac0, 0xba552f40, 0xbc9a7367, 0x3b8c9528, 0x3b4f7f80, 0xbc5021b8, 0x3cf19bd2, 0xbc270cac, 0xbc10dfec, 0x3c3118c4, 0x3cfe03a2, 0xbb152ae0, 0x3af8a1c0, 0x3bbb4c88, 0x3c6dc43c, 0x3ca2f458, 0x3d0859ad, 0x3bd38108, 0x3caa3ba2, 0xb92fc900, 0x3ccf9f42, 0xba820b80, 0xba6fab40, 0x3c547820, 0xbc88d685, 0x3c03badc, 0x3cb5d768, 0x3c9820ac, 0xbca33189, 0x3c81175a, 0xbabef0c0, 0xbc8005de, 0x3cb58ad4, 0xbc8e5374, 0xbcf907ce, 0x3c606cec, 0x3cccb070, 0xbccdf9b4, 0x3a8ed440, 0x3bf221a8, 0x3d00eb85, 0x3cfb2316, 0x3cd031c4, 0xbc126e78, 0xbccac8e5, 0xbc092570, 0xbc08f39e, 0x3c94d7d0, 0x3c8ed01c, 0xbb08c9c0, 0x3c783380, 0xbca348d6, 0xbcdce90e, 0x3c296fa4, 0x3c19b4d0, 0xba72c1c0, 0x3c463cbc, 0xbb4e4c30, 0xbc9581e0, 0xbbe894ac, 0x3cc0110e, 0x3c567dd8, 0xbd079242, 0x3d02a0b9, 0xbcda7594, 0x3cc4a896, 0x3cd7a102, 0xbc31d4e8, 0xbc91580b, 0x3cbc3630, 0xbcd1b3de, 0xbce0b232, 0xbcd8a7b4, 0xbbfe6b68, 0xbc9a3e3e, 0x3c7cd780, 0x3cab28e4, 0x3bf67e00, 0x3bf45a98, 0x3b34c7b0, 0x3cac600e, 0x3cb8c0ee, 0xbc10e84a, 0x3c93942a, 0xbc835c69, 0xbc874abe, 0x3cfe586a, 0x3c55092c, 0x3c998860, 0xbcb7bb92, 0x3a398e40, 0xbbfb08b4, 0x3cc4bdfa, 0xbd0179c8, 0xbbbb879c, 0x3d04662f, 0xbc81349a, 0xbcadd850, 0x3c3bfcc4, 0x3cf4e94e, 0x3c92d9e4, 0x3cdae0e0, 0x3ccc4c10, 0x3cc2d3c2, 0x3bc41e98, 0xbc316b74, 0x3c9f2436, 0x3cb208f4, 0xbcc2c210, 0x39d52080, 0xbb1b35a8, 0xbc74493c, 0xbc94a0be, 0xbcac5010, 0xbc6cf9ec, 0xbd016825, 0xbcabafee, 0x3c6b4080, 0xbcae91d0, 0xbc87876b, 0xbb0e5278, 0xbc1e43d6, 0xbc89471e, 0x3a792040, 0x3cd39710, 0xbca856b4, 0x3ceb18ec, 0x3c2df9c0, 0xbce2eb89, 0x3cac9d54, 0x3c529e78, 0xbc4499a8, 0xbc73cca2, 0xbc3e9200, 0xbcb196e2, 0xbb5a73f0, 0x3c10d424, 0x3c4347e0, 0x3d052a21, 0xbbc07a10, 0xbccd0469, 0xbbbda124, 0x3c06a188, 0xbc9fca45, 0x3cbce2be, 0xbcba9fa0, 0x3d069fff, 0xbcdd768e, 0xbc2aabbc, 0x3d03628d, 0xbc821212, 0x3cd850ac, 0xb9a97d00, 0x3c9b54e4, 0x3cffa576, 0xbb306020, 0xbc97c870, 0xbc092178, 0xbc9a433c, 0x38fbba00, 0x3b6db9b0, 0x3cae3c4e, 0x3c868404, 0x3c77936c, 0xbcf4ad76, 0xbc9519d2, 0xbce868a7, 0x3d0258ab, 0x3caf0760, 0xbcbb6727, 0xbcefee87, 0x3bd6b558, 0x3ba51868, 0x3aa09dc0, 0x3cace854, 0x3bf1af00, 0x3c9d4d96, 0xb9e16600, 0x3aa309e0, 0x3bb5d0f0, 0x3ba5c0e8, 0xbc2706f4, 0xbc3c2d68, 0x3ca0c67c, 0xbcbc3712, 0x3cd7e892, 0x3c9a4ca2, 0xbbd3c9e0, 0x3ba71b10, 0x3cf872c6, 0x3cf8262a, 0xbc5d9af4, 0xbceeb1d0, 0xbd0851d6, 0xbcfebe38, 0xbcc19e69, 0x3c8e3404, 0xbce02aff, 0x3cf8cc2e, 0x3b927af0, 0xbbb2cec4, 0xbcd1db7c, 0xbc1d6752, 0xbb66ca20, 0x3c3d24b8, 0xbc901a78, 0x3d015185, 0xbba40fd4, 0xbc4b5168, 0xbc1cf6fc, 0x3c197c84, 0x3c536ea0, 0xbcd76f8c, 0x3b0af110, 0xbc8eefb6, 0xbb7e09c0, 0x3ce6a054, 0x3ce6187e, 0x3cb4d80c, 0x3bdaeb68, 0xbcd227d6, 0xbcb259a9, 0x3ad60f60, 0xbd0343aa, 0x3ce7f220, 0x3bd95478, 0x3ac64a40, 0x3b2accf0, 0xbca5b6f4, 0x3ca91db2, 0x3b36e9a0, 0x3acf0de0, 0x3cc7697c, 0x3cd4fe9c, 0x3cb96ec4, 0xbb7665e0, 0x3cfb295e, 0x3c8b574e, 0xbb197400, 0xbc0cd8d6, 0xbc2690da, 0xbc2709ec, 0x3c8f8f54, 0xbcdec5d4, 0x3c90eab8, 0x3cf5cd9a, 0x3c6a9ddc, 0x3cb00db0, 0x3c8b9f66, 0xbcd01c30, 0x3bfd2208, 0xbbc3d668, 0xbc8203b2, 0xbce0bf5c, 0x3cac1132, 0xbb484658, 0xbcbc193e, 0xbcadc67a, 0x3cb05378, 0x3b9e5580, 0x3c62ffac, 0x3c982f4e, 0xbb4ce1e0, 0xbc3c35a2, 0x3cab481a, 0x3b239210, 0xbbef0144, 0xbcd40950, 0xbc05a4b4, 0xbb3d0220, 0x3cc4a362, 0xbbc72970, 0xbcae4707, 0xbcb11310, 0x3cd1d7c2, 0xbceb50fa, 0x3ce35e8e, 0x3c96304a, 0x3c63585c, 0xbcd107c5, 0xbcc526cc, 0x3c93daae, 0xbcc40e29, 0xbc876763, 0xbb548cf0, 0xbad0e680, 0x3cda8d8a, 0xbcdb2967, 0xbc136a8e, 0xbcc601fc, 0x3c059438, 0x3c595b5c, 0xbc588d6c, 0x3cb2e0cc, 0xbcb73f9e, 0x3c11da08, 0xbcce542e, 0x3ca4aa78, 0x3bcda018, 0xbcf664e3, 0x3c658e78, 0x3c998bda, 0x3c2f8e3c, 0xbc975ec5, 0xbd013f3c, 0xbc564740, 0xbcb82ab0, 0x3d0812d3, 0xbcc6603e, 0x3c4f3978, 0x3cdf3bc8, 0x3ce7d418, 0xbc4d583c, 0x3ce67cb8, 0xbce87889, 0x3abff540, 0xbcf85d21, 0xbc7c30f4, 0x3c333be8, 0x3c6bec34, 0xb68b8000, 0x39771400, 0x3c1c3ad4, 0x3cf6e4ba, 0xbcbe77a0, 0x3ab0ede0, 0x3be31df0, 0xbd008ef5, 0x3cc83032, 0xbc6a01e2, 0xbd08206e, 0x3c0b457c, 0xbbd61be8, 0xbc7bf32c, 0xbcccbca5, 0xbb5d0058, 0x3b9ac520, 0x3b48d520, 0x3c5bd1d8, 0xbb9e8b08, 0x3cdefae8, 0xbce3210e, 0xbc76dede, 0x3cd2d6ae, 0x3c9298d0, 0xbc0b8a8e, 0x3c0d3ba4, 0xbce6c883, 0x3c9f80dc, 0xbcb7cdda, 0xbce736c9, 0xbcf4bc56, 0xbc6720fc, 0x3c9049d8, 0x3c16da64, 0x3c7d7d28, 0x3b99c380, 0xba0c1400, 0x3c8e58de, 0x3aea2600, 0x3ce129b6, 0x3c2671b4, 0x3ce6cb20, 0x3cf414e6, 0x3bc38258, 0xbb2cc788, 0xbcc67c90, 0xbc8b7a78, 0x3c2e65dc, 0x3c0352f0, 0xbd06d63c, 0x3c7a6644, 0xbc4022f0, 0x3cb5c6e8, 0xbc923efe, 0x3c479b9c, 0xbbb43554, 0xbb3e94a8, 0x3c714e5c, 0xbc82f3b6, 0xbcd2b745, 0xbcefa4cc, 0xbc95a210, 0x3d00ac87, 0xbd04a9fd, 0xbcb1b2a2, 0x3d01548d, 0xbc9ec1e7, 0xbcdbf316, 0x3c91ff46, 0xbc6642c6, 0xbb7ab610, 0xbbddad78, 0xbce87b5a, 0xbbd5d360, 0xbcc499f0, 0xbcf86821, 0xbc65160e, 0x3c4a65a0, 0x3c34d350, 0xbca790b0, 0x3cb698fe, 0x3b3b1bb0, 0x3cba0110, 0x3c894804, 0x3cc69c4c, 0x39df2600, 0xbc02c58e, 0xbbc667f8, 0xbc7c750a, 0xbb1f7f48, 0xb8d7cc00, 0xbc6b90fc, 0xbc965d74, 0x3cdd27e8, 0xbc22c1f0, 0xbb181c68, 0xbb0bcf88, 0xbc821b1e, 0x3bf115a0, 0xbcb2d9b2, 0xbc7ce8e2, 0x3c0d5f3c, 0x3ce6b0ee, 0x3c76580c, 0x3c87d3a8, 0x3cf60e7a, 0xbcc239b0, 0x3cb97dfc, 0xbc0c2fd6, 0xbc34453c, 0x3d01b7cf, 0xbcd54bf6, 0xbbf960f8, 0x3c7cbfa4, 0x3cd0a2ec, 0x3cde61da, 0x3c89fb82, 0xbb7a5178, 0x3cd6312a, 0xbc990d45, 0x3cfc53d6, 0xbc8246f4, 0xbcb5ef9e, 0xbb5396a8, 0xbd0331b4, 0x3c74ff60, 0x3c78771c, 0xbcb1e942, 0xbccdeb23, 0xbc663ec6, 0xbca7a238, 0x3c970758, 0x3bb9fbf0, 0x3d01a921, 0xba6682c0, 0xbc3b0368, 0xbd00ea8e, 0x3cf25042, 0x3cdd8a30, 0x3c5caf1c, 0x3d015f8f, 0x3ccdb6c8, 0xbc16039e, 0x3c686a00, 0x3b1c0530, 0xbb78ee88, 0xbc30d322, 0x3bff3ea0, 0xbba0f880, 0x3a8b4c80, 0xbce257ec, 0xbc801f3a, 0x3cb55980, 0xbc1f39ce, 0xbc988420, 0xbc211ae2, 0xbca88fc7, 0xbc9628a9, 0x3cb5fac0, 0xbc7acf74, 0xbc54d4a2, 0x3b6a6e10, 0xbc959eb8, 0x3ca89150, 0xbd017bae, 0x3cfe6956, 0xbcd49223, 0x3c60def8, 0x3b141eb0, 0x3d05f1a5, 0x3c25c610, 0xbcc62d89, 0xbc4fa5da, 0x3cca0248, 0xbb353698, 0x3cc27770, 0xbbf02760, 0xbc88fcf8, 0x3c4dbf28, 0xbce4795a, 0xbc7a6e9a, 0x3c833294, 0x3cc77a1c, 0x3ca92676, 0xbc7db18e, 0xbcca16be, 0xba0f4500, 0x3c830bdc, 0x3ca7ffb8, 0x3b89bea0, 0x3c22b0ac, 0xbcba6938, 0x3d04a6bd, 0x3d012b07, 0x3cd724fa, 0xbc57ec4a, 0x3c75f5fc, 0x3cc2c078, 0xbcb295f6, 0xbcfa7d8e, 0x3828f400, 0xbc845ce0, 0x3cb16880, 0x3b2645c0, 0xbc9efdb0, 0xbcefe3cc, 0xbcf5a90c, 0x3ce8afba, 0xbd01b1b8, 0xbc3dbaac, 0x3c96c3ac, 0x3b923e60, 0x3b9c4b90, 0xbc3ca5f4, 0x3b17cf90, 0xbc94a080, 0x3ca88be0, 0xbc95f7d0, 0x3cbc7a42, 0xbc697880, 0xbcefdff0, 0x3ca5127e, 0xbcb75db4, 0xbcc0d9c0, 0xbcbd1d63, 0x3a162300, 0xbc15aa44, 0xbb7e3dc0, 0x3c5476ec, 0x3bd01d88, 0xbb93cbe0, 0x3c4cbf28, 0xbb848660, 0xba55b1c0, 0xbd072216, 0x3b80cf00, 0xbc95fe14, 0x3cf997ca, 0xbd02b8ad, 0x3c68c3ac, 0xbc0e8ff0, 0x3ce3c41c, 0x3ca6954e, 0xbccb68b0, 0x3cd639fe, 0xbc9e0c2e, 0xbb0e12f0, 0xbc3295c4, 0x3bd48bf8, 0x3ce272b8, 0x3ceafbb6, 0xbcdbec25, 0x39c08980, 0xbcd13f58, 0x3c691224, 0x3cda4486, 0xbc8c1baf, 0x3c811d76, 0xbc941507, 0xbcee6978, 0xbcf777d2, 0x3ca78c30, 0xbc8fe2c0, 0xbcc1247c, 0x3b0c50e0, 0x3c962eac, 0x3b0983b0, 0xbd086f5d, 0xbbfabcb4, 0xbcbb954c, 0x3ccd797c, 0x3c3f6e40, 0xbaf64280, 0xbc4df5ce, 0xbc7ff25a, 0xbc9ceb1a, 0x3c54e5e4, 0xbc7d635e, 0xbc60e4b8, 0x3b8901f8, 0x3d05c733, 0xbcda7545, 0x3ce0f936, 0x3b853218, 0x3c3b9bc8, 0xbb400ba8, 0x3ca93066, 0x3bd8f650, 0x3c976b9c, 0x3c6e5b44, 0x3c9588b2, 0x3cd7e08e, 0x3c9c0d04, 0x3c4a9208, 0x3cdf445c, 0x3c9c475a, 0xbce6f71c, 0xbcf2c7b8, 0xbcadf7b6, 0xbbd02480, 0xbcebd9fc, 0x3cb37056, 0xbcc0157c, 0x3cfc1d0e, 0xbc766028, 0x3c170cf8, 0x3c33f4e8, 0x3ca2ede6, 0xbb96631c, 0xbcd56087, 0x3cdbe8be, 0x3cf235fe, 0x3c1e8564, 0x3c989d7a, 0xbca5dda9, 0xbcc5e9fc, 0xbcbbf0b6, 0x3cf0cd2a, 0x3b26e860, 0x3bc16ff0, 0xbc2b1f04, 0xbcbbfeb4, 0xbce34010, 0x39b52b00, 0x3d06c2e7, 0x3c4c9f10, 0x3cc9808a, 0xbca949e7, 0x3cd4d572, 0xbce2c890, 0x3d07fdb7, 0xbc885d69, 0x3cf9c136, 0x3cdae38a, 0x3cb90130, 0xbb280730, 0x3c984e78, 0xbbbea2c4, 0x3ad55a20, 0xbb2a5c48, 0xbcc7a4dc, 0xbab8ddc0, 0xbc23c838, 0xbbf56e10, 0xbcdfb5c9, 0xbd01f440, 0xbc8fe040, 0x3cb35202, 0xbcd6d65c, 0x3cafb4d4, 0x3bf83fc8, 0x3cc0e8c4, 0x3a9cfc40, 0xbbf5de2c, 0xbc86ba7e, 0x3c612e80, 0xbca7e7c2, 0x3c951086, 0x3a7f3100, 0xbc222ba2, 0x3a2b3f80, 0xbd02cb75, 0xbc761a38, 0xbccb73f8, 0xbb654d58, 0x3cf8f39a, 0xbc59d8da, 0x3bc73088, 0xbcbb77ee, 0xbcaac3c2, 0x3b2f3de0, 0x3c99f858, 0xbcaf3ef8, 0x3cf272f6, 0x3cc7bb00, 0x3c9583b6, 0x3d000193, 0x3c8a597a, 0x3d06ba1f, 0xbcbc1127, 0xbc716128, 0x3cff6a26, 0xbd00cef0, 0xbcdea778, 0x3c637cd8, 0x3cba48a8, 0x3b97e3d0, 0xbc3d0756, 0x3cfada2a, 0x3aa26620, 0xbc9ee5fe, 0xbcaea500, 0x3b922a98, 0x3b514990, 0x3cf00f8a, 0xbcc87fbe, 0x3cfb788e, 0x3b68ca30, 0x3cb700f2, 0xbb83b5f0, 0x3ccb2974, 0x3b1d7a20, 0xbc6a7830, 0xbb523e10, 0xbcd7564c, 0xbc88e6c7, 0xbcc10e87, 0x3ca9ddd8, 0xbc97a34e, 0xbc657cb4, 0xbcfd32ba, 0xbcfd053a, 0xbce81c36, 0xbca7be80, 0xbc823292, 0x3cb80ea4, 0x3d0515e7, 0xbc494468, 0xbc20589e, 0xbcc50a50, 0xbc31deec, 0xbcc4e52e, 0xbc9a18d6, 0x3cae06e2, 0x3bb56e50, 0x3ce89de6, 0xbce493ce, 0xbc842f60, 0xbac761a0, 0x3cd87ece, 0xbccc198e, 0xb9db1700, 0x3cca6094, 0xbcd88987, 0x3c4f96e0, 0xbbb33800, 0xbbd6e59c, 0xbbd72f80, 0x3c5aa5bc, 0x3d012807, 0x3d08738b, 0xbd02a798, 0x3abc77e0, 0x3c6706dc, 0x3ca6f97c, 0xbc3bee9a, 0xbce09fd0, 0xbd0728c8, 0xbcb1f654, 0xbc441f16, 0xbca4e430, 0x3c127260, 0xb952eb00, 0x3cb4170c, 0x3cd570a0, 0x3cc889de, 0xbb114810, 0xbcbf652c, 0x3cddec56, 0xbc8a2027, 0x3d001313, 0x3b4dca30, 0x3c8f457e, 0xbb2cec20, 0x3c87b5b0, 0x3c0328b0, 0xbbce5768, 0x3ca4e6de, 0x3b9c9618, 0x3cf724c2, 0xbc73db70, 0x3bf391c0, 0x3cd0ac62, 0x3c314338, 0x3ce7253e, 0xba952be0, 0xbca30987, 0xbcaf5902, 0xbcd52f45, 0x3c4b986c, 0x3cf28ac2, 0xbcb18c20, 0xbd07464f, 0xbbcd4a10, 0x3d020e4f, 0x3c3df3ec, 0x3ba9f5d0, 0xbb85d7cc, 0xbacfce60, 0xbacb3e00, 0x3cd1447a, 0xbccaadb0, 0xbc80c71a, 0x3c645bc4, 0x3a8aede0, 0x3cc63036, 0x3b51ed40, 0x3ce04b0e, 0xbce155b8, 0x3bca23f0, 0xbd025ade, 0x3b0541d0, 0x3b393de0, 0x3ccbff10, 0x3cc9b2f8, 0xbc9091c3, 0xbcdf9e94, 0x3c65f884, 0x3c03063c, 0x3c80e916, 0x3cd3157a, 0x3c864a42, 0xbcc95027, 0x3cadbf54, 0xbcb1d287, 0xbc1a0b16, 0x3ca820ac, 0x3c3da888, 0xbbb85800, 0xbc7e76ac, 0xbbf8c3b4, 0xbccb3947, 0x3bb0a468, 0x3b3264c0, 0x3b87fbe0, 0xbba42178, 0xbc813b4d, 0xbcdfeffa, 0xbbcbc300, 0xbcab38f2, 0xbca1e7e2, 0x39faf280, 0xbbd2fac4, 0x3c0dd660, 0xbd0247e8, 0x3a76b040, 0xbcf07389, 0xbba6cbac, 0xbc5724ac, 0x3ca1835c, 0xbb485120, 0xbd045c4d, 0xbd0862e3, 0xbc4c91ca, 0x3bf601b8, 0x3bbc7c88, 0x3c84c53c, 0xbcb74e2c, 0xbca33140, 0xbc3f1184, 0xbc4717c0, 0xbc8ca905, 0x3cab9400, 0xbc075a00, 0x3c8eb8fa, 0xbcd7e487, 0x3cdb8d6a, 0x3bbb5828, 0x3cc83b4e, 0x3c7895ec, 0x3b8d3d20, 0x3ce42ccc, 0x3c93a04a, 0x3ccb2ddc, 0x3ce04e76, 0xbcf3bb07, 0x3bf4fd68, 0xbcc75da7, 0x3cfc2612, 0xbcb04420, 0x3d008441, 0x3c7075c4, 0xbccd9065, 0xbcfe6869, 0x3c729d9c, 0x3c831510, 0xbc7908e8, 0x3c8712ae, 0xbcdaf881, 0x3c97d9b6, 0xbba84654, 0xbcbf7572, 0x3ccf1602, 0x3c9f1f9e, 0x3c0a65bc, 0xbcb7245e, 0xbc0d2f5a, 0xbcc024d6, 0xbc99f849, 0x3c780564, 0x3cc912d4, 0xbcd3976c, 0x3c0949e0, 0x3ba14aa8, 0x3c76a768, 0xbc1aea6c, 0xbcb66334, 0x3ca316ea, 0xbc345952, 0x3cdd4074, 0x3c909030, 0xbcd1e95e, 0xbcc349e7, 0x3c81feb8, 0xbcb90a25, 0x3bafcc58, 0x3c0026a4, 0xbccf477e, 0xbc951f02, 0xbcd82fc5, 0xbcaf1109, 0x3bbaac40, 0xbd00e2ee, 0xba1e7800, 0x3d0535b3, 0x3bd01230, 0xbc3e3cc4, 0xbbe0d370, 0x3bf913c8, 0xbccb8750, 0x3cc43eae, 0x3bf7e520, 0xbca03605, 0x3cbe253e, 0x3cf76296, 0xbc07f126, 0xbcc1a187, 0x3c7020bc, 0xbc33e4bc, 0x3c229120, 0x3c48fd20, 0xbacd2540, 0xbcb292ec, 0xbca7dad6, 0x3cc38596, 0x3cc37a28, 0xbc3a190e, 0x3d07ba63, 0xbcb063b2, 0xbc884e5a, 0xbbb4d6cc, 0x3bdec180, 0x3ce2c20a, 0x3ce07a62, 0x3bf6e028, 0x3b2c73b0, 0x3cda318e, 0xbce13456, 0xbc5d567c, 0xbd03a14a, 0xbc72245a, 0xbbfc90ac, 0x3cd8f36c, 0xbcc891bc, 0xbbb3cf08, 0x3ca0fff4, 0xbcff9263, 0xbbe7fb4c, 0x3a3f9540, 0xbce8f9f6, 0xbc238c26, 0x3c0ec5c4, 0xbcd4159a, 0xbca68c87, 0x3c74ce08, 0x3a03c5c0, 0x3cc5f898, 0x3c0a6bbc, 0x3c1941bc, 0x3d038b0d, 0xbc9c0280, 0x3d0721a3, 0xbc86edb6, 0xbcacd716, 0x3cb7f5ea, 0xbc9f354b, 0x3b8f3ba0, 0x3bcd97f0, 0x3bfc87d8, 0x3c58e8dc, 0xbb9e0460, 0xbcaa1569, 0xbcc06f03, 0xbcc3bf3c, 0x3c1660d4, 0x3d042d93, 0xbcf2df70, 0x3cd05848, 0xbb45ba58, 0x3cb61fca, 0x3c9f104a, 0xba885200, 0xbccb623e, 0xbce2d754, 0x3b6e8200, 0x3c549d00, 0xbd017c4f, 0x3ca2a29c, 0xbc2b662c, 0xbbb1daf0, 0xbc8a599a, 0x3d03e79d, 0xbd03922b, 0x3ce678ba, 0x3c956f06, 0xbba0f344, 0xbd035e33, 0xbd037712, 0xbbb19388, 0xbc4da662, 0x3ce7433e, 0xbcf0de23, 0x3c15c75c, 0xbc244f40, 0xbcef703f, 0x3ac81c80, 0xbc4753b4, 0x3cc77f4c, 0x3cd9fcb0, 0xbd0676fa, 0xba851b60, 0xbcb7cbc9, 0xbd073d96, 0xbc599d62, 0x3b7bf5f0, 0xbd0797b5, 0xbcbb0f58, 0xbb2bb658, 0xbbadcc3c, 0xbc9f687c, 0x3cd4c93e, 0x3c2d2970, 0x3a0a3ec0, 0x3c1a9600, 0x3c149b6c, 0x3c8abef4, 0x3d07cd7d, 0x3c10c2ec, 0x3cb67b3a, 0x3c8b5ff0, 0x3cb049a2, 0xbce69c5c, 0x3ce6ae48, 0x3c83f6dc, 0xbb8aa460, 0xbb244e10, 0x3cbff150, 0x3c6cdaf4, 0x3c7d2c20, 0x3cd80a72, 0xbc86b18b, 0x3ccfb030, 0x3bae4cb0, 0xbcd13558, 0x3ca1aeec, 0xbbb59068, 0x3cebdcb4, 0xbd056059, 0xbcbab0c9, 0x3993f900, 0x3ce784c6, 0x3cae515a, 0x3cc6f57c, 0x3cac1c6c, 0xbc2eca00, 0xbcc78d49, 0xbc59097c, 0x3c8ab526, 0xbc93e3f2, 0x3bad1360, 0xbbfc319c, 0xbc385e00, 0xbc0b8466, 0x3c90dfe6, 0x3badbe18, 0xbb06dd60, 0x3d02a7df, 0xbd03ddeb, 0x3d01ed87, 0xbc549d5a, 0xbc9d4a5a, 0xbce81f3f, 0xbc8bc345, 0x3c96b0fe, 0xbd06035d, 0xbd07efd5, 0x3cf98c2e, 0x3cfe8fee, 0xbc1cc90a, 0x39472b00, 0xbd01a0ac, 0x3cfba286, 0x3cd6f678, 0x3b9318d8, 0xbbea0480, 0x3ca226bc, 0xbca48882, 0x3ca03a2a, 0xbd00b593, 0x3cd8847e, 0xbb0d1548, 0xbcddff27, 0x3a8bca60, 0x3ce2085e, 0x3c8f949e, 0xbcc2c2b0, 0x3b83e398, 0x3c227ba0, 0xbcfe997d, 0xbd0300b7, 0x3c6f8788, 0x3bbe5cd8, 0x3c8f9312, 0x3c41b04c, 0xbcf08636, 0xbb6d7210, 0x3cfda6ca, 0xbc5ebc12, 0x3c41d5fc, 0xbc77e18a, 0xbc3ae016, 0xbcd7fdbe, 0x3b6a6880, 0xbc9efc12, 0x3c7d8080, 0xbb9f6b3c, 0xbad5be00, 0x3ac05de0, 0x3befe9d8, 0xbba7284c, 0xbc80608b, 0xbae089a0, 0xbc84d0c0, 0x3c724c9c, 0xbc1f42de, 0xbcc92d7a, 0xbc4ae99e, 0xbd006a18, 0xbc819cd6, 0x3cb06f54, 0x3cf0367e, 0xbcf8e2d4, 0xbca7fe22, 0xbccc1327, 0x3cc44204, 0x3bec0bb8, 0x3c15b4d0, 0xb9fb1180, 0x3c96912c, 0x3cb75af8, 0x3c860fa4, 0x3ce33c00, 0xba891ce0, 0xbcca8127, 0xbca4d3bc, 0xbccfd952, 0xbca2e57e, 0xbc8d7916, 0xbc875bef, 0xbc9deeb6, 0xbbb0d908, 0xbcc6b3a7, 0xbb1fbf68, 0x3ba764d8, 0xbcf7333d, 0xbd0448a2, 0xbcc365a3, 0x3bc116c8, 0x3ce96450, 0xbbf58fa4, 0x3c3775c4, 0xbc737f96, 0xbc292156, 0xbba41a1c, 0x3cba6c00, 0xbcdb4a47, 0x3a995be0, 0xbd04d654, 0xbc90512d, 0xbcf84b4e, 0xbbb9d44c, 0x3c4791d8, 0xbbeebc60, 0xbc9dd8fe, 0x3c0f4000, 0xbb16c4e0, 0xbaf28020, 0x3ca95434, 0x3bf73158, 0xbc4db56c, 0x3a133480, 0xbcb20d1e, 0x3c35d088, 0xbcd254b0, 0x3cf70ace, 0xbd01e9b0, 0xbc4d3f22, 0x3cf1b496, 0x3b49f3e0, 0xbc8f9f2f, 0xbc85c9d6, 0x3a1d5040, 0x3c00c560, 0xbc422a1a, 0xbc144cb0, 0xbc98753e, 0x3c9531d4, 0x3a89f820, 0xb9a60600, 0x3b193030, 0xbcc29280, 0x3cfd556e, 0xbcd1cbd4, 0x3abe7ac0, 0x3cd351e4, 0x3cc08c7a, 0xbba70f80, 0xbc0e0530, 0x3cfc223a, 0xbc67cae8, 0x3cdc2f3c, 0x3c40b67c, 0xbcff7a8e, 0x3bd87fd0, 0xbc249352, 0xbbdcc370, 0x3cc25198, 0x3c99b5d2, 0xbcf838ee, 0x3cbae4c4, 0x3c3384f4, 0xbd02b0bd, 0x3d01755f, 0x3c43808c, 0xbcb477b8, 0xbd02923b, 0x3d0692df, 0x3ca8f5b6, 0x3cb1187a, 0x3cb0dc94, 0xbcc47203, 0x3c46c2cc, 0x3d07d1af, 0xbc897874, 0xbcb1804e, 0xbd077393, 0x3bf2fca8, 0x3d0307a3, 0xbbed9be8, 0x3c5d87b0, 0x3c4761a4, 0x3c094538, 0xbbaa94e8, 0x3c902bce, 0xbcd29c54, 0x3cae989a, 0x3ca0159c, 0xbcc4634c, 0x3cbe1a62, 0xbb494998, 0xbb2d35e0, 0xbb4388e0, 0xbc2aa9e6, 0xbd05a907, 0xbbadf770, 0x3ccb3196, 0xbcbbcc92, 0xbd01dd44, 0xbccee7b2, 0x3b82bcd8, 0xbbd39008, 0xbcd1a99c, 0x3c066588, 0x3cdf6bc8, 0xbbc89024, 0xbccac8e7, 0x3d007d01, 0x3ce69722, 0x3ccfe0cc, 0x3cdc3dea, 0x3c905bc4, 0x3bb61460, 0x3cef284e, 0x3cc4bef0, 0x3b6700b0, 0xbab30ba0, 0xbc8c9f89, 0xbc18ffd6, 0xbc8698b4, 0x3cb0599c, 0x3c08f170, 0x3caac12e, 0xbc29cfb8, 0x3c86bf56, 0x3bc4a360, 0x3c10b9fc, 0xbcb47054, 0x3a95c360, 0xbceec009, 0x3b2eed90, 0x3cd8e19a, 0x3cf5d8c6, 0x3ccb810a, 0xbc126644, 0x3cd5ae9a, 0x3c5734b4, 0x3bf9fee8, 0x3cff98b2, 0xbc4414c0, 0xbcebdf85, 0xbcb8cbb8, 0x3bc4d5a8, 0x3c5be984, 0xbbed5458, 0xbba4781c, 0x3cdb8b42, 0x3c52eab0, 0x3c960820, 0xbb56f868, 0xbc3e8592, 0xbcaabb85, 0xba614f00, 0x3cfeb4aa, 0xbcd7f9ce, 0x3ce447c8, 0x3c325164, 0x3cdef2e0, 0x3ce12e80, 0x3c2b4f64, 0xbcb51d72, 0xbbfdd4e0, 0x3caec252, 0x3d084b45, 0xbca264cb, 0xbcc28620, 0xbb9d03e8, 0x3d03d5af, 0xbc21079a, 0xbc1f78c4, 0xbcbc17e7, 0xbce1c11c, 0xbcae75f6, 0xbc2b3580, 0xbce9c285, 0xbc9cf3da, 0xbbb54f80, 0x3c1a2ca8, 0xbcc8a238, 0xbb2fdbc0, 0xbcf3359a, 0x3bf58e78, 0xbcd241d4, 0xbbbdb780, 0xbbf903cc, 0x3ca1aede, 0x3cb51d94, 0xbcb93220, 0x3c9f3810, 0xbcaed450, 0xbb3c5198, 0x3cb1f008, 0xbcced540, 0xbc24ff84, 0xbced7136, 0xbbb02670, 0x3ccc6cf2, 0xbc0286f8, 0xbc88d8c0, 0x3c5fa5f4, 0x3ca98f76, 0x3cec80a8, 0x3ca7def4, 0xbca582ba, 0x3c7f792c, 0x3c241300, 0x3b3010a0, 0x3bd62058, 0xbc1337f8, 0x3a21b640, 0xbcc955b2, 0xbb7cc600, 0x3ca54724, 0x3c6f1a0c, 0x3c9fb978, 0x39f92d80, 0xbcc11f1e, 0x3a006d40, 0xbc8ce134, 0xba6e3f40, 0x3ba9b720, 0x3b1c5da0, 0x3caebcac, 0xbc8d3cf2, 0xbcacee5e, 0x3a8fc4e0, 0xb9df7f00, 0x3c82302e, 0xbbf8d124, 0x3c29ee5c, 0xbbd647cc, 0xbb89cdf0, 0x3b13dea0, 0xbc41da12, 0x3cdb47d4, 0x3ce61f08, 0x3ab371c0, 0x3b165e60, 0xbc46205a, 0x3cca411e, 0x3d070b51, 0xbc5c7cc0, 0x3c1c63a4, 0xba816c40, 0xbce42087, 0x3ca64dda, 0x3c54efdc, 0x3cc7dfea, 0x3cc16c96, 0xbbb68768, 0xbae18de0, 0xbcdadfc1, 0x3c2accb0, 0xbc6a1e7c, 0x3c2dbf74, 0xbcd2bfbc, 0xbb36b010, 0xbccf57e7, 0x3c8d0a92, 0x3d07900f, 0xba42a500, 0x3cc67a20, 0xbd00b7ea, 0x3ca53984, 0x3cce6394, 0x3cf28e46, 0x3c229e30, 0x3cec6b26, 0x3ca12fac, 0x3c1294cc, 0xbd052988, 0x3b87db80, 0xbc4ec378, 0x3cdb7142, 0xbcd7d0f2, 0xbd074a48, 0xbca2c434, 0x3ba4d990, 0xbcb2c86e, 0xbc98fe14, 0xbbad4670, 0x3c235d4c, 0x3ba07a88, 0xbb21fe78, 0xbc46f41a, 0xbc2096f0, 0x3d00192b, 0x3cd7bf32, 0xbcccf990, 0x3c8a79f2, 0x3ca5ccea, 0x3cee5d52, 0xbce28307, 0xbcbf73c5, 0x3c5ce758, 0x3c3ac870, 0xbcbeecc0, 0xbc0c4634, 0xbca1113a, 0xbc2634fc, 0x3c362d28, 0x382c8800, 0x3c76a94c, 0xbc130fb0, 0x3d05ba49, 0xbcbcc798, }; // 7 uint32_t bias_vals[] = { 0xbc3266ec, 0xbbe43fa4, 0x3c6898b4, 0x3c210868, 0xbcec5130, 0xbb382ff0, 0xbcd3e31a, }; // 4,1,1,7 uint32_t output_exp_vals[] = { 0x3f0ae6f4, 0x3e06d0c7, 0x3e8cb149, 0xbb4830b7, 0xbe872094, 0x3ea9f6e4, 0x3e83094a, 0x3f29eae5, 0x3e4738be, 0x3eaa75dd, 0x3d940a8e, 0xbe7e27dd, 0xbe0ac591, 0xbd849768, 0x3eb2a525, 0x3f244889, 0x3ec81eaa, 0xbd5edf10, 0xbe003ea4, 0xbd500669, 0x3e220519, 0x3f356aed, 0x3ee21c12, 0x3e9c80a2, 0xbe3e4da9, 0xbe3df2ea, 0x3e3846d2, 0x3dd1579c, }; // 4,1,1,7 uint32_t output_relu_exp_vals[] = { 0x3f0ae6f4, 0x3e06d0c7, 0x3e8cb149, 0x0, 0x0, 0x3ea9f6e4, 0x3e83094a, 0x3f29eae5, 0x3e4738be, 0x3eaa75dd, 0x3d940a8e, 0x0, 0x0, 0x0, 0x3eb2a525, 0x3f244889, 0x3ec81eaa, 0x0, 0x0, 0x0, 0x3e220519, 0x3f356aed, 0x3ee21c12, 0x3e9c80a2, 0x0, 0x0, 0x3e3846d2, 0x3dd1579c, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, VALID_PADDING, NULL); } void test_same_padding_non_zero_strides_large() { input_set *set = &large_input; strides_input_set *strides = &large_non0_strides; // 4,15,10,6 uint32_t input_vals[] = { 0x3b227300, 0x3f239634, 0x3e391590, 0x3f09c42a, 0x3e166940, 0x3e069194, 0x3f5d35bc, 0x3f1db843, 0x3f50936c, 0x3e8b542a, 0x3f1a91df, 0x3e086f24, 0x3e493b6c, 0x3e70d520, 0x3da58e98, 0x3f47d07e, 0x3f4e3621, 0x3f672084, 0x3f08a2e8, 0x3f243d5c, 0x3ecd7c1e, 0x3e99be2a, 0x3eb2bb0a, 0x3ef2679e, 0x3f56d025, 0x3f2783aa, 0x3f2bf3f6, 0x3f71a850, 0x3eaf2578, 0x3e63f6dc, 0x3e8df942, 0x3f15d269, 0x3eb210a4, 0x3f700f08, 0x3f28078d, 0x3e2abb70, 0x3f155820, 0x3e59b2f8, 0x3e98d6d2, 0x3d1d8d70, 0x3f37490b, 0x3d292ac0, 0x3eb0129a, 0x3e294e38, 0x3f3e92bb, 0x3eb536ce, 0x3ee0aad6, 0x3edb1218, 0x3f259a84, 0x3d9b6888, 0x3d769400, 0x3f5bbbf0, 0x3e752aac, 0x3dee2610, 0x3f501963, 0x3e646fa4, 0x3eb97480, 0x3f61aed5, 0x3f045fc5, 0x3f6eec5f, 0x3ee9c662, 0x3f5da091, 0x3f008237, 0x3e22af00, 0x3eac1394, 0x3f16c6a8, 0x3e95e63a, 0x3f7cb28a, 0x3f6e5ab1, 0x3e2ff794, 0x3dda8690, 0x3eb6527e, 0x3f545081, 0x3ecc3588, 0x3ecdda7a, 0x3f5e48ef, 0x3e1dbd08, 0x3f388474, 0x3ec9797c, 0x3e20ddfc, 0x3e210f04, 0x3dbf1058, 0x3dfef5f0, 0x3eca4c76, 0x3ed27c6a, 0x3f1c72dd, 0x3d8caa50, 0x3f1732a3, 0x3e55c1dc, 0x3f7849e2, 0x3f78300a, 0x3cecc400, 0x3f2920de, 0x3f443ee2, 0x3e526a40, 0x3e2ac644, 0x3f3fa4c6, 0x3f14a766, 0x3ecf9714, 0x3f54295a, 0x3e6a3400, 0x3f3a3c48, 0x3f4d1a5a, 0x3f649eb8, 0x3f632da3, 0x3f248220, 0x3e4dd434, 0x3efa92c4, 0x3f0fc029, 0x3e5a078c, 0x3e76b808, 0x3f19a861, 0x3f774430, 0x3f77569e, 0x3de9afd8, 0x3d90e268, 0x3f1ac701, 0x3f57f86b, 0x3f66a396, 0x3ecec390, 0x3e88fe3c, 0x3df434e8, 0x3f31c5c9, 0x3e32ebf0, 0x3f75dba1, 0x3ee0ab1c, 0x3f16a274, 0x3ea1bf7c, 0x3ed0d7ec, 0x3e1ad758, 0x3f45ef00, 0x3f27c019, 0x3f7b46cc, 0x3f493cd3, 0x3f3c87aa, 0x3ef91326, 0x3efd7bd4, 0x3f16e60d, 0x3db0d428, 0x3da74760, 0x3ea228e0, 0x3f1ae3e8, 0x3ea12492, 0x3ce1b520, 0x3e2f785c, 0x3f129c0b, 0x3f04c774, 0x3e4c3798, 0x3eeab532, 0x3f0b3116, 0x3ef157ec, 0x3f66aea5, 0x3eaf7386, 0x3ea57c6a, 0x3e1b21a0, 0x3f310164, 0x3ea4b1c0, 0x3d53d630, 0x3f6469ee, 0x3ead75d0, 0x3f09cd39, 0x3e95e5c8, 0x3bd4df80, 0x3de69818, 0x3e5265ac, 0x3f2da038, 0x3f16ca3a, 0x3f1f2851, 0x3f3483a0, 0x3f6d0642, 0x3f4d0c24, 0x3db32fe8, 0x3d860e10, 0x3f330ec4, 0x3f2fde45, 0x3e82c0f4, 0x3f0f720d, 0x3f6daebd, 0x3f03ae0e, 0x3f0b8600, 0x3ebf31c4, 0x3ea4aa22, 0x3f1c78a3, 0x3c716e40, 0x3e4575d8, 0x3f57ae16, 0x3e6a4260, 0x3f5e50c1, 0x3ecf21ea, 0x3f075442, 0x3ec51e74, 0x3edb6b48, 0x3f2d9719, 0x3ec9526c, 0x3e70fc3c, 0x3afcb800, 0x3f2f4f9c, 0x3f34ab61, 0x3e989b0e, 0x3f1ad501, 0x3f7b4eb2, 0x3f3c5a20, 0x3f398ad5, 0x3f21b58b, 0x3f5339d1, 0x3eb99f66, 0x3f29336e, 0x3f198507, 0x3f1ff7c2, 0x3f0f7b7c, 0x3f7da3d8, 0x3f6d870b, 0x3f70cbc9, 0x3f2684fd, 0x3e96332c, 0x3e3078d0, 0x3e809b9c, 0x3f67939d, 0x3f387367, 0x3f067a8f, 0x3f3ab1fd, 0x3e35a1d8, 0x3e998322, 0x3f173882, 0x3f4547d2, 0x3f7ab26b, 0x3ec8f190, 0x3f63d684, 0x3df099a0, 0x3f7f5118, 0x3eec1784, 0x3f3eaf5f, 0x3f35a0ef, 0x3dcb6f90, 0x3e946d0a, 0x3f0f8eb7, 0x3dc1fd68, 0x3f518bf1, 0x3f5a11d0, 0x3f246bec, 0x3ef26256, 0x3e0f2670, 0x3f1b8e29, 0x3f129ede, 0x3ef82a46, 0x3eb39a8e, 0x3dab1d08, 0x3e8b823a, 0x3f1be004, 0x3cb9b580, 0x3e9293da, 0x3f30e6c2, 0x3f50a3ac, 0x3f1d72ac, 0x3e7b6bf0, 0x3e28a754, 0x3f36df9b, 0x3ddf8260, 0x3c81b4a0, 0x3f07fcc4, 0x3f69986c, 0x3e1de344, 0x3ec52ec4, 0x3c57bfc0, 0x3f0b3294, 0x3f63093d, 0x3f1b7dce, 0x3ed7e19a, 0x3e27a4e4, 0x3ddf4478, 0x3f478ae5, 0x3f3f771e, 0x3e5b9e3c, 0x3ec4f3c4, 0x3eead50e, 0x3f321718, 0x3f1b6d81, 0x3f276718, 0x3f40d46c, 0x3f17eb30, 0x3f56db9d, 0x3f35a402, 0x3e24e830, 0x3f404ba7, 0x3f6d17d4, 0x3ea907b6, 0x3f55b98a, 0x3f31ac61, 0x3f27cd25, 0x3e453574, 0x3efb8bb2, 0x3f2a78c8, 0x3c219740, 0x3e9733f6, 0x3e1b3dac, 0x3e52b850, 0x3ea19c54, 0x3f74eea4, 0x3ec0888e, 0x3ea375a2, 0x3e7d1340, 0x3efefce8, 0x3ef7b7a4, 0x3f15e1d4, 0x3e47e7c0, 0x3ed4e0e0, 0x3f4c78ae, 0x3e464d58, 0x3f3c8f56, 0x3db95320, 0x3f540c87, 0x3ee0a846, 0x3eee9cd4, 0x3f679b97, 0x3eeb1728, 0x3f2eda9a, 0x3f41cb41, 0x3e6a0438, 0x3ed619c8, 0x3f0de10b, 0x3eb85afc, 0x3f102337, 0x3f228999, 0x3f0ba4fb, 0x3f58c2e2, 0x3f475fb4, 0x3f0285eb, 0x3ea4b84a, 0x3f686f8d, 0x3c787280, 0x3f483440, 0x3e87dcba, 0x3e186dd4, 0x3dbbe590, 0x3f0a98cd, 0x3f4f4b31, 0x3f3c31a3, 0x3e7ec630, 0x3dbc4970, 0x3f0e6e6c, 0x3e6c6300, 0x3f533bb5, 0x3e5252c8, 0x3f7bbeee, 0x3e512cf0, 0x3e6eaa88, 0x3ed19e52, 0x3ef2dfd4, 0x3f66298e, 0x3e06c284, 0x3f7913ea, 0x3e086028, 0x3e983d58, 0x3eb12cde, 0x3f69b259, 0x3f1bd003, 0x3e378cc8, 0x3d8336f8, 0x3f39dc93, 0x3f1ec3fe, 0x3ebb3a58, 0x3f5da147, 0x3f6f35c2, 0x3f30f554, 0x3dbbca18, 0x3f2658b0, 0x3f6f702e, 0x3f48373a, 0x3ef3b78e, 0x3f09770f, 0x3edf1ef2, 0x3f73bce8, 0x3f166e85, 0x3f1bf0ab, 0x3f6d0fb0, 0x3f6dbb6b, 0x3e85114e, 0x3e36911c, 0x3a967a00, 0x3f71e565, 0x3ea6d724, 0x3ef5c85a, 0x3eb070ea, 0x3e3fb128, 0x3f0ec81c, 0x3eff7f18, 0x3e21e134, 0x3f119379, 0x3f726941, 0x3eaa67fa, 0x3cd05980, 0x3f646c18, 0x3f343541, 0x3efb9554, 0x3f6e7051, 0x3e5560f4, 0x3f2e20b0, 0x3f4584f1, 0x3f57bd33, 0x3e62445c, 0x3e0db0ec, 0x3e5e4a7c, 0x3f6e32e6, 0x3efabfb4, 0x3f68f574, 0x3e5d16f0, 0x3f1504f6, 0x3ea6319e, 0x3dfece38, 0x3ed875ea, 0x3f7bc660, 0x3ea7df5c, 0x3f00b6e2, 0x3f7bbfd8, 0x3f44f6d3, 0x3f06d40f, 0x3ead5386, 0x3f2ab30b, 0x3f78b86a, 0x3f1d2711, 0x3f78b429, 0x3f7b3075, 0x3f16c7f6, 0x3f4d8f95, 0x3f5c6505, 0x3e154bd8, 0x3dac8ea8, 0x3f29ce96, 0x3f4a8764, 0x3f65ee0a, 0x3ef75684, 0x3e4668ec, 0x3ea73150, 0x3e78878c, 0x3ec29160, 0x3eacb782, 0x3f6bcb4b, 0x3ecfc520, 0x3f6c98ff, 0x3cf2ac20, 0x3f04bbf0, 0x3dda9218, 0x3f17043f, 0x3dd99ac0, 0x3f2f7419, 0x3e151de8, 0x3f3d2a1d, 0x3e4904cc, 0x3f5a5aeb, 0x3e9df2ac, 0x3f2c2b40, 0x3dbd7280, 0x3f467843, 0x3d777790, 0x3f141bc5, 0x3f2acbac, 0x3ebcc4ac, 0x3f49ae6c, 0x3d903228, 0x3f7f1524, 0x3edee394, 0x3f10274a, 0x3f5fe92b, 0x3eb6e0fa, 0x3db0b4d8, 0x3f57f931, 0x3f7d17f4, 0x3f7568e6, 0x3f169c26, 0x3f47d4f7, 0x3f60c98a, 0x3f51a1e1, 0x3f406684, 0x3e214454, 0x3e65d3d4, 0x3f105cc0, 0x3eeb2868, 0x3f00677c, 0x3d840968, 0x3f0c7af9, 0x3e647864, 0x3dbddbb0, 0x3f0858ee, 0x3f65bdc4, 0x3f3c397f, 0x3f171337, 0x3cf62fe0, 0x3ea6e188, 0x3f445b06, 0x3f153ac8, 0x3ebffa40, 0x3ea58e80, 0x3e2098e0, 0x3f355606, 0x3f1bef0c, 0x3f083143, 0x3f46cd34, 0x3f6944c6, 0x3f122dac, 0x3ec87b64, 0x3eb02282, 0x3f3d5363, 0x3e8d3f60, 0x3f4594ef, 0x3f27eddc, 0x3f5e8d79, 0x3f510543, 0x3ec1869e, 0x3e01bb4c, 0x3f1e21f4, 0x3eb8f602, 0x3f46079e, 0x3f4412bf, 0x3eb54668, 0x3b115600, 0x3f46043a, 0x3c899840, 0x3f7c32fa, 0x3f297c08, 0x3e05d578, 0x3eb9b888, 0x3f62adb0, 0x3ebfeb6c, 0x3dc73698, 0x3f7b0564, 0x3f6ad0a8, 0x3f271995, 0x3daf2d98, 0x3f4f6c8a, 0x3f608210, 0x3f1e818b, 0x3f21c37f, 0x3f29bbe3, 0x3ec29db8, 0x3f048eed, 0x3e578144, 0x3f7711d1, 0x3e4f9d44, 0x3eca2398, 0x3e903ca0, 0x3ea10eda, 0x3f7ccd9d, 0x3f78c368, 0x3d899908, 0x3f7da29f, 0x3f07e4b3, 0x3f643cb6, 0x3efd82da, 0x3de20110, 0x3f236212, 0x3f1add60, 0x3ecf797a, 0x3f61c12b, 0x3f6b564c, 0x3e43140c, 0x3ec424fe, 0x3f665adb, 0x3d982838, 0x3f3ccd0d, 0x3e960a94, 0x3e845d42, 0x3f6fe543, 0x3e81547a, 0x3f30a7ee, 0x3e440f70, 0x3eee3322, 0x3eeead26, 0x3f36b3f9, 0x3f304acd, 0x3ed1598a, 0x3ec1edda, 0x3e5f47d4, 0x3efd6506, 0x3ec67c2a, 0x3df9b4f0, 0x3e9df502, 0x3f45e401, 0x3e589ad8, 0x3e1a93b4, 0x3f5c46b8, 0x3e621148, 0x3f7f5600, 0x3f72baff, 0x3f4123e2, 0x3f71a85d, 0x3ead1466, 0x3daa2a58, 0x3f3c9ae3, 0x3f4ca2fc, 0x3f60ab28, 0x3f65251a, 0x3eb71be8, 0x3f2a8be0, 0x3ef2cf8a, 0x3de3cfa8, 0x3f5eedd8, 0x3dbe16d8, 0x3e00f3b4, 0x3e9c556c, 0x3e8e6816, 0x3c8fe4a0, 0x3f47981b, 0x3f647967, 0x3f2302d6, 0x3f6db572, 0x3e756f1c, 0x3f237ae4, 0x3f260622, 0x3f37b5f3, 0x3ebaa3a0, 0x3c14c2c0, 0x3ef040e0, 0x3ecdd6cc, 0x3f09c5ba, 0x3eafffe0, 0x3ee2ad9c, 0x3e69c148, 0x3f45a742, 0x3eef0b64, 0x3e971e1c, 0x3e92f68a, 0x3e8c65b2, 0x3f1d2171, 0x3f465233, 0x3f7ce279, 0x3f728308, 0x3f2cfe96, 0x3f63220d, 0x3ee210e0, 0x3f21773f, 0x3f13a5e2, 0x3e33a0d0, 0x3cf33a80, 0x3f734583, 0x3f53a2dc, 0x3d047510, 0x3d723680, 0x3ef45e58, 0x3c239340, 0x3f2423d9, 0x3f0375eb, 0x3e9ca4c2, 0x3ee4a250, 0x3ed13724, 0x3f460cda, 0x3efccdf4, 0x3f62d212, 0x3f0709fc, 0x3e6e0788, 0x3ef183b6, 0x3f040b9f, 0x3f25cdd1, 0x3eecf9aa, 0x3f4d69af, 0x3f2474ef, 0x3e183368, 0x3f4bacf2, 0x3e38d730, 0x3f5dcdc3, 0x3ebbe596, 0x3edd6934, 0x3f03f7f2, 0x3e185098, 0x3eac703a, 0x3d1c79d0, 0x3dd411b8, 0x3f364ceb, 0x3f070ed7, 0x3ea6470a, 0x3d52aae0, 0x3f720e21, 0x3ea081d8, 0x3d94d6c8, 0x3f25e9c7, 0x3e288ac4, 0x3f01a8ad, 0x3eb0175a, 0x3ec99266, 0x3effa4b2, 0x3f3923ca, 0x3f1f7ee6, 0x3e068364, 0x3f284e78, 0x3d899a78, 0x3f3ada39, 0x3f70a7c2, 0x3e993112, 0x3ee1528a, 0x3f63bc2a, 0x3f0281a1, 0x3f6e80be, 0x3ed4482a, 0x3f3d10e7, 0x3f2f11ec, 0x3d82e6e8, 0x3f30d8dc, 0x3d59a860, 0x3f3a3acc, 0x3e18b574, 0x3f683a08, 0x3eb08d96, 0x3ebc9c68, 0x3e9cb71e, 0x3d976330, 0x3f5cf76c, 0x3edc775c, 0x3f21f7d3, 0x3f63706b, 0x3ecaac74, 0x3e8da316, 0x3e963970, 0x3ee921f2, 0x3e5ddfcc, 0x3f731a16, 0x3d343f70, 0x3dbb54b0, 0x3eab397a, 0x3f2fd8b0, 0x3f590838, 0x3ef754ea, 0x3db72170, 0x3f1223bc, 0x3f40aa88, 0x3e1133e8, 0x3f2e5bd2, 0x3eecf71c, 0x3dbaeaf0, 0x3f6dfea7, 0x3f26cbe0, 0x3dfef600, 0x3f4ea023, 0x3eb03008, 0x3f007f87, 0x3ec6fb9a, 0x3ef3a764, 0x3f788842, 0x3f1ff8ad, 0x3f49695f, 0x3ee9599a, 0x3f55dff9, 0x3f69a690, 0x3eaaa87a, 0x3c923cc0, 0x3f6d2d26, 0x3e9fddae, 0x3eaaa242, 0x3f077995, 0x3e22c624, 0x3e6e3abc, 0x3f5ce1ad, 0x3e48f3b0, 0x3d9ebf48, 0x3ecec5be, 0x3f5dd00b, 0x3ef86604, 0x3f679d61, 0x3cdb0360, 0x3df97ec0, 0x3f25ec6b, 0x3f363d3f, 0x3e596a0c, 0x3f7f2347, 0x3edae694, 0x3f6132f5, 0x3d800fc0, 0x3f3bc71f, 0x3e0ad0e8, 0x3f486f7d, 0x3df0ddd0, 0x3f5430fb, 0x3dfc07c0, 0x3f2bef96, 0x3e09ee0c, 0x3c31b900, 0x3f65a5a4, 0x3e5a7adc, 0x3dfc5d50, 0x3f688721, 0x3f4147d4, 0x3f150ac4, 0x3e480a64, 0x3f2369d7, 0x3e5f2f14, 0x3f6459bf, 0x3dcc8530, 0x3f2128f4, 0x3e59dfd8, 0x3f09ee57, 0x3ebc11e4, 0x3e696ebc, 0x3f7b5d10, 0x3f4f2966, 0x3e10c538, 0x3e419370, 0x3f612083, 0x3f7c7854, 0x3f2e0e5f, 0x3eb470f2, 0x3d9a3708, 0x3e98d21c, 0x3f56c03b, 0x3f0c82c9, 0x3d1488d0, 0x3d99d150, 0x3f7d2b78, 0x3f51c7dd, 0x3d4ac580, 0x3f452f56, 0x3c637bc0, 0x3f73d49d, 0x3f2a91a9, 0x3f43c4bd, 0x3d0fdde0, 0x3ea53ab6, 0x3de05858, 0x3f7a2eff, 0x3f3adcb7, 0x3e7da6ac, 0x3f6c400b, 0x3f2cf549, 0x3f410de1, 0x3f6c1df4, 0x3f13f3e7, 0x3ece914e, 0x3ef81cf2, 0x3f517093, 0x3df8d6e8, 0x3d0103b0, 0x3edab6cc, 0x3e07ff04, 0x3d7ceec0, 0x3f2c77d7, 0x3f52b252, 0x3e46be24, 0x3f3ccb1f, 0x3e2b7570, 0x3e00e6a4, 0x3e858172, 0x3e8b1e94, 0x3f423cdf, 0x3d7b2790, 0x3ec635ea, 0x3f086a23, 0x3f3babb7, 0x3eca00da, 0x3dd86da0, 0x3e6d554c, 0x3f22bdb0, 0x3f7e1cf7, 0x3e299cd0, 0x3eedd0b0, 0x3f154835, 0x3e9d9c14, 0x3f2b023e, 0x3eec0434, 0x3f48c4fc, 0x3f7f2970, 0x3f2bd569, 0x3e95596e, 0x3e7d79c8, 0x3f2e5e73, 0x3f15abd8, 0x3e889f28, 0x3ecc220c, 0x3f241599, 0x3f71b6f6, 0x3f2b4cb0, 0x3d0c1740, 0x3f5d7ec2, 0x3f54ce68, 0x3ea8ff4c, 0x3f60bdde, 0x3d0b0820, 0x3ee349b2, 0x3e8a28a2, 0x3f3c4767, 0x3f5b0ac8, 0x3f0af48f, 0x3ed0230c, 0x3e86b4e4, 0x3f2b0d4a, 0x3d98d4b0, 0x3f0698a6, 0x3dae6af8, 0x3d30d310, 0x3ded8630, 0x3f635c9c, 0x3e9c1ce4, 0x3cc29100, 0x3f5e699c, 0x3f774a6f, 0x3f2fc333, 0x3f7ca2dc, 0x3f6b4b10, 0x3ebff2b8, 0x3edce210, 0x3f15b40b, 0x3f414d23, 0x3f295ef3, 0x3d1255c0, 0x3e99ec1e, 0x3e67421c, 0x3f561b2b, 0x3e35e1c4, 0x3f396694, 0x3f0a8afc, 0x3ea9504c, 0x3f2ba5b9, 0x3f765bb2, 0x3d4c0170, 0x3edf6faa, 0x3f53c21f, 0x3eed2712, 0x3f240319, 0x3ea34d6e, 0x3f53e9d4, 0x3ed5939e, 0x3ec683c6, 0x3e97b538, 0x3da0cf30, 0x3f198721, 0x3bea2380, 0x3e9b28da, 0x3e9341c6, 0x3e4414d0, 0x3e86a172, 0x3f37d055, 0x3f4f6140, 0x3f6fa7aa, 0x3f7cf6be, 0x3f63e38d, 0x3f36b40f, 0x3f25c24a, 0x3f57dcee, 0x3ee8e10e, 0x3d951730, 0x3f266947, 0x3e6ef9e8, 0x3db91588, 0x3dd773d8, 0x3f0a5722, 0x3ec2aab2, 0x3f696037, 0x3e81cbcc, 0x3f71584f, 0x3f2225ce, 0x3ded1468, 0x3df3b248, 0x3f38aa36, 0x3f4c3d00, 0x3e5385c0, 0x3eaa1294, 0x3f67406f, 0x3e01e2b8, 0x3eab3856, 0x3e1b7a90, 0x3f29ea98, 0x3eb2ee0c, 0x3ea0b8de, 0x3f74e2a7, 0x3f37a4ba, 0x3e63dd0c, 0x3eba263e, 0x3f142153, 0x3f54cc97, 0x3e1833ec, 0x3ce4fae0, 0x3f4885f6, 0x3e0e6090, 0x3d37e430, 0x3d485e60, 0x3f5f9d3f, 0x3efa6ed6, 0x3f4c4b68, 0x3f27e414, 0x3e0d2370, 0x3e57096c, 0x3e329078, 0x3f6994b6, 0x3f2c8ea3, 0x3eb01968, 0x3f2c91df, 0x3f1b4723, 0x3f75441d, 0x3ed08cd4, 0x3e8e4594, 0x3f3bd23f, 0x3ec0c306, 0x3d793b10, 0x3da3fc98, 0x3ed9eee2, 0x3f2ca505, 0x3f17327d, 0x3ded1528, 0x3f7d8646, 0x3ebd4142, 0x3f60257a, 0x3f0b7bcc, 0x3e9b6968, 0x3ef868ca, 0x3f4fb17e, 0x3f66464e, 0x3f7a95d2, 0x3ccc43c0, 0x3f1317ba, 0x3f020e47, 0x3f772072, 0x3d677c70, 0x3de323d8, 0x3e8718e8, 0x3f6eea63, 0x3f30b4c8, 0x3f1b58d8, 0x3efc1cca, 0x3d02e760, 0x3f35ad69, 0x3f1d6006, 0x3f4be0f1, 0x3d00f4f0, 0x3f2fdd10, 0x3c8f0820, 0x3ec6a986, 0x3d8c8958, 0x3dd64960, 0x3f0c7fc4, 0x3f398ce9, 0x3f0aaddf, 0x3ea13cd6, 0x3e1a154c, 0x3ea00ee0, 0x3e3a2e18, 0x3ee4b0fc, 0x3eac5aca, 0x3ef1e564, 0x3f4b37cc, 0x3f7ae104, 0x3f53ab47, 0x3e6aadd8, 0x3f437532, 0x3f2c7fb9, 0x3e098bd0, 0x3dbaf628, 0x3dc9ce08, 0x3efd63f8, 0x3e8d38b4, 0x3f20934f, 0x3f238d1f, 0x3f76fb8b, 0x3ece9daa, 0x3f3c284b, 0x3f621b30, 0x3e93a29c, 0x3f2e7902, 0x3d809498, 0x3e047910, 0x3e9265b4, 0x3e5703a8, 0x3cf04620, 0x3f653718, 0x3f557720, 0x3e69fd90, 0x3f12701c, 0x3f0d5de4, 0x3ea9fa56, 0x3f60d22b, 0x3f0e7bf6, 0x3f1e16cc, 0x3e23c218, 0x3dbd6d60, 0x3d71d370, 0x3f25f6be, 0x3e99c3a0, 0x3e4554ac, 0x3f5e6597, 0x3eaf413a, 0x3e83ba80, 0x3f390641, 0x3ec20c52, 0x3f64022f, 0x3f1904d1, 0x3f7aeeeb, 0x3f5f26ed, 0x3efe093a, 0x3f2c3af0, 0x3d7c5340, 0x3e771b70, 0x3f3c9ba2, 0x3f3a0f93, 0x3f05971e, 0x3ef2ea5a, 0x3eb8253c, 0x3f7ecfbf, 0x3d086610, 0x3eb88c36, 0x3f55e59a, 0x3f37f6c6, 0x3d0f44b0, 0x3f44576e, 0x3e5041b4, 0x3f2796f7, 0x3e2d9614, 0x3f7879d6, 0x3f767896, 0x3df10540, 0x3f5a5f10, 0x3ed861b0, 0x3e8155c4, 0x3e009588, 0x3efb9706, 0x3f293d23, 0x3efc23ca, 0x3f0e3473, 0x3f1571b8, 0x3ec84a82, 0x3f490ff7, 0x3e3bf170, 0x3f16585d, 0x3f2f5cf0, 0x3e0ecf24, 0x3e21ebe8, 0x3eb877ba, 0x3f70ba33, 0x3f47bb80, 0x3cbc7740, 0x3f495d88, 0x3e83f83c, 0x3ea633d8, 0x3e0cf644, 0x3d8f7018, 0x3f41d8e8, 0x3f59a178, 0x3f1b532f, 0x3f46bc83, 0x3f73f2b2, 0x3e01f8cc, 0x3ee03a50, 0x3e55f9a8, 0x3edd34f8, 0x3f29d7b1, 0x3f4026b2, 0x3f37a4d2, 0x3f6ce2fd, 0x3e7684e4, 0x3f046475, 0x3f0a0a96, 0x3ed47f3a, 0x3f5bea8b, 0x3e743e34, 0x3e4ffb34, 0x3eac9ac2, 0x3d876210, 0x3f7c9b4c, 0x3e796594, 0x3e312c50, 0x3f4fc17e, 0x3ee8d182, 0x3ef8ac4a, 0x3e87a7fa, 0x3f0c75c5, 0x3e7cb45c, 0x3e823ed4, 0x3f3da9a1, 0x3e82d524, 0x3ef124aa, 0x3e53f980, 0x3f129f91, 0x3ec45ebe, 0x3f1c6cea, 0x3f6b277b, 0x3f21c8ee, 0x3ea44fd0, 0x3f49df77, 0x3e2ba6c0, 0x3f3a2841, 0x3f3b98b8, 0x3f4a1a05, 0x3f672f6c, 0x3f4f85ff, 0x3f216157, 0x3e55c7f4, 0x3f14fbd5, 0x3f62832a, 0x3e863746, 0x3e699c84, 0x3eefa3f2, 0x3f2377ae, 0x3cb7d760, 0x3d092840, 0x3f024d7b, 0x3f66ed12, 0x3f27d1a8, 0x3e2e9848, 0x3f7b5743, 0x3f1c8caa, 0x3f355965, 0x3ef1a048, 0x3edc411a, 0x3f16c4b9, 0x3f0e6027, 0x3f5a8af9, 0x3e8ba48a, 0x3f4da2e7, 0x3f34c842, 0x3ead1d9a, 0x3dcb0c20, 0x3eaa8a30, 0x3f082b28, 0x3ee3d874, 0x3ed7ffe4, 0x3e9e102e, 0x3ede2698, 0x3f1fcd07, 0x3ec59d64, 0x3e9040d2, 0x3f6990d6, 0x3ee6a87e, 0x3f551534, 0x3f001e99, 0x3f5344d8, 0x3e9ad0bc, 0x3eb64558, 0x3f35d210, 0x3f0c8331, 0x3eed874e, 0x3f1dac4a, 0x3ea80004, 0x3f67a0b5, 0x3f7f3807, 0x3e53cd80, 0x3ee9d09c, 0x3e079ba8, 0x3f023023, 0x3ef7fdf2, 0x3e8fa2c4, 0x3e88f4a4, 0x3d15e2c0, 0x3f0055cb, 0x3e3edc90, 0x3f0dd291, 0x3c7efa80, 0x3f7e1978, 0x3e39a244, 0x3f63ad73, 0x3f6de737, 0x3e93b68a, 0x3e943ad4, 0x3ecb8976, 0x3f5b8b43, 0x3f2e4fbf, 0x3db65498, 0x3e28e8f4, 0x3f322b22, 0x3f11aea3, 0x3f7af29d, 0x3f4a4c62, 0x3f400888, 0x3e59df3c, 0x3f53e6a2, 0x3d4a6460, 0x3edcc86c, 0x3f2b89f4, 0x3eb6a5e4, 0x3dfa75c8, 0x3f55e704, 0x3f13b35c, 0x3f68712d, 0x3f424599, 0x3e6b005c, 0x3f4c60ae, 0x3edf3cb8, 0x3f582657, 0x3e52bb8c, 0x3f65c0e9, 0x3f04782b, 0x3f3df458, 0x3f113abd, 0x3f388998, 0x3f675761, 0x3ed4f14a, 0x3ecd2304, 0x3eefb426, 0x3f6c7beb, 0x3f710a5b, 0x3f46623c, 0x3f22e4e3, 0x3cc090e0, 0x3f3dc384, 0x3e53b8a0, 0x3f23c092, 0x3f270aff, 0x3f11881b, 0x3ef7a828, 0x3f312f67, 0x3f26f96f, 0x3f666e90, 0x3ef226a8, 0x3f71c6c5, 0x3f6234f2, 0x3f6cac00, 0x3e7ab140, 0x3e6965e4, 0x3ee6d92c, 0x3e6283b8, 0x3f5e2907, 0x3f70c9c0, 0x3edfc8f4, 0x3ee9d348, 0x3f3c36b2, 0x3dedf718, 0x3ef4d5e6, 0x3f79dee7, 0x3ef4f828, 0x3ef67c60, 0x3ed8525c, 0x3f280f4b, 0x3f608778, 0x3e96f1d6, 0x3f147649, 0x3dea3748, 0x3e37a768, 0x3f51ff66, 0x3f1d0a7f, 0x3f6e2bca, 0x3f53c73b, 0x3eb64b60, 0x3f501bb8, 0x3f373852, 0x3f5184b8, 0x3bc63c00, 0x3e93e44a, 0x3e288efc, 0x3e38ba08, 0x3f35fbbb, 0x3f5048b0, 0x3f2eee5d, 0x3edaaa46, 0x3f12a981, 0x3e874fd6, 0x3e16a03c, 0x3f45aefb, 0x3e4f9560, 0x3ea0a1fa, 0x3e583ad0, 0x3f7cc46b, 0x3f391376, 0x3f4a498a, 0x3f57f889, 0x3edafebc, 0x3f0cd50e, 0x3f2801ac, 0x3eecc4b4, 0x3d93a9b0, 0x3f1dc08b, 0x3f61a9f9, 0x3e46e06c, 0x3f39f92e, 0x3dfba050, 0x3f1f1350, 0x3d8276a0, 0x3f7e9125, 0x3f60a00d, 0x3f5f0c12, 0x3e558830, 0x3ed37dfc, 0x3f1d01bc, 0x3f1da1fc, 0x3f4d0476, 0x3e9ca804, 0x3f3c6250, 0x3f2228c0, 0x3e49d904, 0x3eacdd64, 0x3f5e3ab2, 0x3f7c8ff0, 0x3e33698c, 0x3e814d86, 0x3f70bf0b, 0x3f3dc425, 0x3f445f4d, 0x3e27dc04, 0x3ebee4bc, 0x3f7f0527, 0x3eb3740a, 0x3e48be44, 0x3deda760, 0x3f081c3a, 0x3f5e8c2d, 0x3eb45d9e, 0x3dbf1ed0, 0x3e3e09bc, 0x3e2a2c68, 0x3e0ebd48, 0x3f287380, 0x3f38519f, 0x3e8a551a, 0x3f5122b2, 0x3f397f94, 0x3dd3e600, 0x3f46edca, 0x3f6dbc40, 0x3f74de03, 0x3ebfedcc, 0x3e08fbe8, 0x3f0ed371, 0x3eb57908, 0x3da559f0, 0x3f1d54e0, 0x3a916000, 0x3f568f8e, 0x3f010d0f, 0x3b9cc000, 0x3e9fc0d4, 0x3f220e60, 0x3e3336e4, 0x3f367ad3, 0x3f52970e, 0x3f09b04c, 0x3dca8b40, 0x3f60d904, 0x3e6ef8d4, 0x3e04bf9c, 0x3df93a88, 0x3f5406b2, 0x3f6fcd2b, 0x3eb29bd8, 0x3f7db523, 0x3f2764da, 0x3f2cc8ea, 0x3e3f5ff4, 0x3e4ccfa4, 0x3f57f964, 0x3f171a31, 0x3f3ca691, 0x3ed90664, 0x3dbc1da8, 0x3f5f132f, 0x3f3c41a4, 0x3e9ba21c, 0x3f503055, 0x3f1b07bc, 0x3e9bb2fe, 0x3ec3c94a, 0x3f020dc1, 0x3f1fec28, 0x3d841d00, 0x3ecff25a, 0x3ee58bde, 0x3cb74980, 0x3f6f5ba1, 0x3f388085, 0x3ec092b0, 0x3f1c390a, 0x3f6ebccb, 0x3e664650, 0x3eef27f2, 0x3f14bfa6, 0x3ee8a0cc, 0x3f0065d0, 0x3f1f2548, 0x3edbbb54, 0x3e4c356c, 0x3f106c5c, 0x3ea1058e, 0x3d850760, 0x3f509fcb, 0x3f718560, 0x3b839c00, 0x3eb6e0b4, 0x3f0e8edb, 0x3d6aaea0, 0x3ef40940, 0x3cf20bc0, 0x3e20e9d8, 0x3f753841, 0x3dfa5240, 0x3ec00f88, 0x3e73107c, 0x3e7332e4, 0x3e3e6dac, 0x3f7233bb, 0x3f385e2e, 0x3b4f6800, 0x3f7f377d, 0x3f5a50a9, 0x3f2cf977, 0x3e36cb98, 0x3f421c56, 0x3ec57e14, 0x3f1a8b0f, 0x3ea27ea8, 0x3f353c2b, 0x3f308a75, 0x3f0d810d, 0x3f419fe4, 0x3dc3b938, 0x3e8fb798, 0x3ebd9bb4, 0x3f65c159, 0x3e8824da, 0x3f5e9eb6, 0x3f4948d5, 0x3f29f64a, 0x3f0af015, 0x3da556a0, 0x3f1a32af, 0x3f0eda76, 0x3f2aecee, 0x3e72c01c, 0x3f706328, 0x3e95d614, 0x3ef4523c, 0x3f19afb7, 0x3e6f10c8, 0x3e5c692c, 0x3ef7842c, 0x3e07d914, 0x3e0e2e08, 0x3f4749b4, 0x3f0a307b, 0x3f727e45, 0x3f482963, 0x3f58d43e, 0x3f7a85ef, 0x3ee3d7b4, 0x3c0ba340, 0x3eb9240c, 0x3f2c40ce, 0x3f7e9466, 0x3ce1c320, 0x3f0086ee, 0x3d9ab080, 0x3ecc54d2, 0x3f776ccb, 0x3ec39e70, 0x3f5d5768, 0x3eeded96, 0x3ede3db6, 0x3d82a150, 0x3f756354, 0x3e04d104, 0x3eb8d7f6, 0x3f490930, 0x3f7fcece, 0x3f15aedb, 0x3e1ad2dc, 0x3f49b470, 0x3f72bde7, 0x3f73bfb6, 0x3eb2c40e, 0x3ecc8ed8, 0x3e85e01e, 0x3f04b4bb, 0x3f7980ed, 0x3ee04240, 0x3f1ff613, 0x3f453cd9, 0x3e670308, 0x3f06966a, 0x3f207b74, 0x3f729c4b, 0x3cffe4c0, 0x3f108324, 0x3e9600a4, 0x3e82ce5a, 0x3ec994f6, 0x3f3fe22c, 0x3f4e94f3, 0x3f57e3f8, 0x3df9ba48, 0x3ea2a208, 0x3f572c4d, 0x3f62cb7f, 0x3eb9817c, 0x3f672d44, 0x3d9e86f0, 0x3f5ccda2, 0x3f5e79de, 0x3f20ef81, 0x3f33f733, 0x3e09f4ac, 0x3f547cd7, 0x3f2e4423, 0x3e01989c, 0x3ee78190, 0x3f7b02f9, 0x3ee02960, 0x3f39c136, 0x3ec77460, 0x3e1bb978, 0x3f629d46, 0x3eff370a, 0x3f439684, 0x3f6097b1, 0x3f027a4f, 0x3f706aad, 0x3f23a9be, 0x3f113c59, 0x3f69e97d, 0x3ed2ab70, 0x3f18c6a9, 0x3ecf9680, 0x3f010123, 0x3e12f558, 0x3f5c23eb, 0x3f3ec919, 0x3ec2cbd0, 0x3c922460, 0x3f7a6e4d, 0x3e555d10, 0x3f7b3a25, 0x3c4161c0, 0x3f6287b0, 0x3e47d0b8, 0x3eac0d38, 0x3ddd70f0, 0x3c9b68a0, 0x3f1d0ef6, 0x3f4738c3, 0x3ebc1506, 0x3f2d3f6a, 0x3e87be3e, 0x3ea3e890, 0x3ee21114, 0x3dce2b98, 0x3d07ead0, 0x3ee9c9b2, 0x3f032b58, 0x3edd9a9c, 0x3f1dfc57, 0x3f3d67cc, 0x3ea22e9a, 0x3eb85d7e, 0x3eed110c, 0x3f630656, 0x3ec4af4c, 0x3f472946, 0x3f29af7c, 0x3e23486c, 0x3f376384, 0x3f6e03d8, 0x3f336c44, 0x3dee7be0, 0x3e2ba424, 0x3f6d9ed2, 0x3e22b904, 0x3c49ae40, 0x3ebdf868, 0x3f00cc53, 0x3ed1d02e, 0x3bf9bf00, 0x3f6ea249, 0x3ec91796, 0x3ea9c620, 0x3f1e9ff6, 0x3f1eb6c8, 0x3f21c816, 0x3d24dec0, 0x3e6eee2c, 0x3ee6ef9a, 0x3ee1aa84, 0x3f77ec2d, 0x3f492f6a, 0x3f34cbd0, 0x3e24cc90, 0x3ed787e2, 0x3f112d80, 0x3e89a4de, 0x3c542280, 0x3ec63388, 0x3e24d3d8, 0x3e49a7f8, 0x3f21fe49, 0x3f53e9ba, 0x3f7d9a39, 0x3f088ec4, 0x3d9867f8, 0x3f79bb20, 0x3d852288, 0x3ed24420, 0x3e0f725c, 0x3db85c00, 0x3f5f4bc9, 0x3f5ba8c7, 0x3e01f854, 0x3f419dbc, 0x3f3e906b, 0x3f0cd816, 0x3ef6765e, 0x3f52b96e, 0x3f31a547, 0x3f703a25, 0x3f389339, 0x3deb1c60, 0x3f57e834, 0x3e8c26c2, 0x3f45feb1, 0x3dd6fb30, 0x3f037d1e, 0x3d9b0c90, 0x3e057c9c, 0x3f599f1f, 0x3e0c762c, 0x3f76a82d, 0x3f24342e, 0x3eb22cc6, 0x3f519440, 0x3e18b588, 0x3f586054, 0x3e5475d4, 0x3f3ab683, 0x3e267038, 0x3ef4188a, 0x3f5cf39c, 0x3ed45ff0, 0x3d62cf90, 0x3f588506, 0x3ea692da, 0x3f5ee54f, 0x3ee416da, 0x3f56b3f2, 0x3e951744, 0x3ef06706, 0x3f664f2d, 0x3f3a3575, 0x3ed6c5fc, 0x3eac3316, 0x3ebd8dd8, 0x3f0f22e4, 0x3f174bd5, 0x3ee9f2ae, 0x3e721ae8, 0x3f2835cf, 0x3f118f07, 0x3f0b0cd0, 0x3f262426, 0x3f4a4512, 0x3f02b1ad, 0x3f60fcbe, 0x3ea682f4, 0x3f30fc50, 0x3f305809, 0x3eabdaf2, 0x3eff5ea0, 0x3f423fd7, 0x3b88ef80, 0x3f2a4423, 0x3f1d6e73, 0x3f143475, 0x3ef5d70e, 0x3cca67e0, 0x3f1e6546, 0x3f385b79, 0x3f35ab29, 0x3f122ab6, 0x3f49c5b6, 0x3ec25e9e, 0x3e039dac, 0x3ebad9f8, 0x3f5e02b0, 0x3f024f09, 0x3da6eed0, 0x3d9e6bb0, 0x3ec78492, 0x3f2d84d2, 0x3f0d85f5, 0x3ee70d2c, 0x3e345bcc, 0x3f1af613, 0x3f3fed1b, 0x3ecd5254, 0x3f4e0343, 0x3f695429, 0x3e8bb032, 0x3f018a66, 0x3f12afca, 0x3f7bec67, 0x3f39960d, 0x3f10af91, 0x3d8e22b8, 0x3f351413, 0x3eb0020e, 0x3ad9fe00, 0x3edc1bee, 0x3e28de40, 0x3e6b1818, 0x3ea3b442, 0x3e016fac, 0x3ed68ad2, 0x3e99569c, 0x3f49137a, 0x3f55621e, 0x3edce8de, 0x3f7f6758, 0x3ed778de, 0x3f7f0637, 0x3e2ae554, 0x3f202c8b, 0x3f70d27f, 0x3e12963c, 0x3f340dea, 0x3f76765a, 0x3f29672b, 0x3e74f948, 0x3ec404a8, 0x3f469499, 0x3e6c3cd8, 0x3e4a7b58, 0x3f78f6c8, 0x3ece42bc, 0x3f7addc1, 0x3f4fd36f, 0x3ce962c0, 0x3f5417df, 0x3f3fff09, 0x3e6101f0, 0x3ee25768, 0x3f21652c, 0x3d82b0f8, 0x3eef5cfc, 0x3dda8d90, 0x3ea0d042, 0x3f25d9df, 0x3f3f94de, 0x3f6a0f1b, 0x3e8608c8, 0x3eddeadc, 0x3f42b07d, 0x3e98b09a, 0x3f1ceb72, 0x3f739382, 0x3f0004ac, 0x3ea38fc6, 0x3f5f92cf, 0x3f5dd3ed, 0x3f3c1247, 0x3e0960d4, 0x3f17b78e, 0x3eeafc04, 0x3e762f94, 0x3f6d5945, 0x3f3702a2, 0x3e9f64e2, 0x3eeb56ca, 0x3f494bbf, 0x3c81b540, 0x3f6de5b1, 0x3dd375e0, 0x3f274922, 0x3e871a1a, 0x3f307c6a, 0x3f5c5c35, 0x3e5f5ca8, 0x3e63b024, 0x3f49ce50, 0x3f47ecbe, 0x3f0d0f5d, 0x3e871360, 0x3dedf9c0, 0x3f5057e6, 0x3eded724, 0x3f34c89b, 0x3f2068e8, 0x3eaf5e08, 0x3d902850, 0x3e595034, 0x3f3278a9, 0x3f31579b, 0x3f20089d, 0x3f3263be, 0x3f262b0a, 0x3e057894, 0x3dce3d30, 0x3ef6cfe0, 0x3d9413c0, 0x3f209b96, 0x3f7a0cb1, 0x3f718876, 0x3e5a9b0c, 0x3f1f45f7, 0x3ec7e492, 0x3f0c2fcd, 0x3e840b70, 0x3f546fb5, 0x3f600fa1, 0x3ea64ede, 0x3f120f60, 0x3f7ef5c7, 0x3eba7854, 0x3f2cf1bd, 0x3f1ef247, 0x3e309b54, 0x3de4fe28, 0x3dba0a50, 0x3ec256fa, 0x3f07e755, 0x3ece9524, 0x3e255ffc, 0x3ec766c8, 0x3e9dbbd6, 0x3cdc3500, 0x3f200393, 0x3f71f2f3, 0x3f6499b1, 0x3f470399, 0x3eef0260, 0x3f502ece, 0x3e6ab1e8, 0x3f61eef3, 0x3ea1c83a, 0x3e2c60a8, 0x3ecae280, 0x3f01aee0, 0x3f3d6ed0, 0x3f448546, 0x3e459bb4, 0x3f6edde2, 0x3f7d07c3, 0x3f4f7933, 0x3f23e0eb, 0x3e2d0418, 0x3e4fcec8, 0x3f35e581, 0x3f08ab57, 0x3e9397e2, 0x3ee99216, 0x3e98b25c, 0x3f7df9ca, 0x3df3e7d8, 0x3f1f190c, 0x3e50ec10, 0x3ec4b8b2, 0x3efb67ae, 0x3ec1f562, 0x3f7ff33b, 0x3ec77a62, 0x3e33b8d0, 0x3eff590e, 0x3f4408d8, 0x3e4eb4a8, 0x3eafb0d2, 0x3f166ea0, 0x3c44d680, 0x3eec12c4, 0x3efeed80, 0x3e84fa62, 0x3f59854e, 0x3e468548, 0x3cbd9500, 0x3e4082c8, 0x3f24a064, 0x3f72db6a, 0x3f35d480, 0x3f279af7, 0x3f5d2516, 0x3f63b61a, 0x3f6f14a3, 0x3ef771c2, 0x3e54ac3c, 0x3ebad670, 0x3e9d4f0c, 0x3ed954ba, 0x3f2a1382, 0x3f478ce4, 0x3e431f24, 0x3e37db34, 0x3f48fbb0, 0x3e526f24, 0x3f08827c, 0x3f42d461, 0x3f2c2877, 0x3f7846d1, 0x3f54c2bf, 0x3f737489, 0x3f5ce33c, 0x3f388597, 0x3f6d26e0, 0x3f0cf819, 0x3ead938c, 0x3f64a4b6, 0x3da59d88, 0x3f5bb7b7, 0x3ec3531a, 0x3f2c7d1f, 0x3e7817c0, 0x3f40fdb2, 0x3eca7f2a, 0x3dad5650, 0x3f451750, 0x3eb5663c, 0x3e4113e0, 0x3f27640a, 0x3f590f3e, 0x3f47f6f7, 0x3f761643, 0x3f0a6118, 0x3f429106, 0x3e388134, 0x3def1fa0, 0x3f5f1956, 0x3eb708cc, 0x3dce13b0, 0x3f71fb6d, 0x3f2d06f2, 0x3eef075c, 0x3f42109d, 0x3f7c6db5, 0x3f10916f, 0x3f258d7d, 0x3f6144eb, 0x3e859e92, 0x3e7dfa08, 0x3ea6d616, 0x3edfcbfa, 0x3e96d04e, 0x3f3860ee, 0x3ebc752a, 0x3e8c31f8, 0x3f0182ed, 0x3ed46c60, 0x3f595434, 0x3ea8ac68, 0x3f676640, 0x3c3af8c0, 0x3f5e2d50, 0x3f28fb88, 0x3f7621f0, 0x3f01d8b4, 0x3f02033b, 0x3d55bfe0, 0x3e7976e4, 0x3e115b50, 0x3efd8986, 0x3d1fdb10, 0x3ef19500, 0x3f09c718, 0x3f4d05ce, 0x3f4be92f, 0x3f1f75f6, 0x3d2dad70, 0x3eaeba52, 0x3f24ea89, 0x3ef8bce2, 0x3f3b2776, 0x3ef9a9ae, 0x3f4ab469, 0x3f3d4feb, 0x3f4052e2, 0x3f21b064, 0x3f0f8001, 0x3ecfe7e4, 0x3eb79db8, 0x3ed0967c, 0x3f06e2a0, 0x3e1962f8, 0x3f464dcb, 0x3f0c8942, 0x3f7d604d, 0x3e2c508c, 0x3e6ef3a4, 0x3ed3f7ca, 0x3e10c3e8, 0x3f6f9f37, 0x3eebbaac, 0x3f15cef3, 0x3ef75d62, 0x3e997036, 0x3f709b61, 0x3f4b4305, 0x3f5955f7, 0x3f1c7f75, 0x3f0eacd7, 0x3f72cec1, 0x3ebf8114, 0x3f0c8ed3, 0x3f4742ee, 0x3f464d9f, 0x3f75dcfe, 0x3e2c5308, 0x3e5945e8, 0x3eb73a0a, 0x3e758788, 0x3eee1b88, 0x3f2e979f, 0x3f5f59c1, 0x3f012723, 0x3e8213e6, 0x3efe2ed4, 0x3f1e4948, 0x3f11a540, 0x3f2c9681, 0x3f047e2b, 0x3f148f4b, 0x3ef172c6, 0x3f617cf0, 0x3ee21d74, 0x3f5a87a4, 0x3f1c876a, 0x3d98f4e0, 0x3d2e0570, 0x3ea43b50, 0x3f3e95c5, 0x3e608390, 0x3edf1b0e, 0x3ed9c0ac, 0x3f0516ce, 0x3f6532c6, 0x3f5d2091, 0x3ea40344, 0x3f21a37e, 0x3f7adb96, 0x3c20e5c0, 0x3e227b3c, 0x3f11773c, 0x3d519c50, 0x3f1c6945, 0x3e11dbe4, 0x3f0d3b70, 0x3e8804e8, 0x3dfc17f8, 0x3f669265, 0x3edb721c, 0x3eafdb3c, 0x3f5bc025, 0x3f4724fc, 0x3f7905ff, 0x3ecc3dc6, 0x3e2f1a60, 0x3e62e3a0, 0x3eb7ea3c, 0x3f1b97e4, 0x3ed44ac6, 0x3f5184ce, 0x3d09b140, 0x3ee1a34a, 0x3f748cae, 0x3f763296, 0x3d5cb6e0, 0x3e9bb7f0, 0x3f6e5e2a, 0x3eeb54ec, 0x3eb429be, 0x3e64c554, 0x3e0195d0, 0x3f6eb90a, 0x3e6dce14, 0x3e9437cc, 0x3f3407a3, 0x3ec0175a, 0x3d7a6b40, 0x3f195874, 0x3ec5015e, 0x3e1c1db8, 0x3ef41d56, 0x3ecb2b26, 0x3f2c8782, 0x3f1efa48, 0x3f40ca3d, 0x3f75800f, 0x3f334287, 0x3f4d3838, 0x3f63d41c, 0x3f6a4a13, 0x3e4f668c, 0x3f1df918, 0x3f66fe12, 0x3eafd92c, 0x3e1da3fc, 0x3eb57c2c, 0x3e5e673c, 0x3e193e68, 0x3db898f8, 0x3f74ea47, 0x3e941964, 0x3f24994a, 0x3f0f8cc0, 0x3ecd12ca, 0x3f535c86, 0x3eb28f96, 0x3f031a2b, 0x3e6ac940, 0x3f03c80f, 0x3f1a73a1, 0x3f1df14f, 0x3f3e98f6, 0x3f70c78e, 0x3f268bdd, 0x3f7998c6, 0x3ee4e72a, 0x3e00818c, 0x3ecc361e, 0x3eaeb8a0, 0x3f1c39bb, 0x3bab2f00, 0x3f17ad32, 0x3f47d9b9, 0x3f6512cb, 0x3f3dd5dc, 0x3f129b36, 0x3ef6e4ec, 0x3f130246, 0x3f400fe5, 0x3f4cecae, 0x3f533548, 0x3ef5ccf0, 0x3e1911d8, 0x3e2ee04c, 0x3f1c197f, 0x3f2b6231, 0x3e9ace5e, 0x3f3e1eaf, 0x3f6ac40d, 0x3f13fd09, 0x3f03eb36, 0x3f0b0e09, 0x3e2bf2fc, 0x3ea72f8e, 0x3e845bc6, 0x3f65f06c, 0x3e6c6440, 0x3ed45fc0, 0x3e99bdf2, 0x3e62ea74, 0x3f503c08, 0x3f5c98d4, 0x37760000, 0x3edabe46, 0x3f69fcc7, 0x3ebe0d90, 0x3dccd1a0, 0x3e1df22c, 0x3dae55e8, 0x3f3c2eb1, 0x3f50f0f1, 0x3f379a5a, 0x3f7bd5df, 0x3e90ea36, 0x3f69acab, 0x3ea7fd44, 0x3f530572, 0x3d8696f0, 0x3e147390, 0x3eb72930, 0x3f3c68c1, 0x3f7f6004, 0x3f0871dc, 0x3e8f7f80, 0x3ed03f4a, 0x3f27246a, 0x3e1fde98, 0x3f4bd5ca, 0x3f3d3117, 0x3e018b30, 0x3ebf3038, 0x3ec2f070, 0x3f3796c9, 0x3f5c0430, 0x3ed1e610, 0x3f547dc5, 0x3ef7b59a, 0x3e8e159e, 0x3f6ba379, 0x3f4539b2, 0x3f5237cc, 0x3e563bd8, 0x3f3fcef1, 0x3ea22640, 0x3f1b5c43, 0x3e18c0d4, 0x3d9429a8, 0x3f68b0f0, 0x3dd51f88, 0x3f154c7c, 0x3ea7ebae, 0x3f496013, 0x3f7e4d14, 0x3e179958, 0x3f2399cd, 0x3edd1a5a, 0x3eddec8a, 0x3f7a5a26, 0x3f27b67a, 0x3ea973d4, 0x3f46095d, 0x3f00956f, 0x3f077540, 0x3ec270b0, 0x3f192a75, 0x3e9d0352, 0x3f40a28f, 0x3e9436ce, 0x3f291746, 0x3f042d5d, 0x3e983db2, 0x3f315562, 0x3e9644dc, 0x3f4e2e54, 0x3db32a10, 0x3f0d8a75, 0x3e19ea78, 0x3f76b767, 0x3f0571eb, 0x3f0cff22, 0x3d00cc70, 0x3e94c912, 0x3efac0be, 0x3f2ef1d9, 0x3ce83380, 0x3f7f51c3, 0x3f197e77, 0x3f089771, 0x3e0e7a54, 0x3f08b53a, 0x3da52488, 0x3e474f88, 0x3e7d6fc4, 0x3e0af4f8, 0x3f0e389e, 0x3f2fc5cc, 0x3e125a90, 0x3e50ef88, 0x3f343717, 0x3f282bb7, 0x3f3567c3, 0x3dc3d358, 0x3f37dc10, 0x3e825f14, 0x3f3b96f0, 0x3f487608, 0x3f6f7596, 0x3f1b5452, 0x3f69697b, 0x3f7ed8c8, 0x3f233160, 0x3ea0a56e, 0x3da6f468, 0x3e24c4ac, 0x3e914dea, 0x3ebd8b8a, 0x3f6d1064, 0x3f5c98d4, 0x3e68ffc0, 0x3e4b04b0, 0x3f5a1db2, 0x3e9ab326, 0x3e1218fc, 0x3dd02ba8, 0x3f44866b, 0x3e51c74c, 0x3ebd1708, 0x3f7227b7, 0x3f64907a, 0x3ee79d14, 0x3f777af7, 0x3f771175, 0x3ef268d6, 0x3f326ec2, 0x3e8dbe4e, 0x3f75b929, 0x3f375dc2, 0x3f2195da, 0x3d51ccc0, 0x3f2d8eb5, 0x3f689246, 0x3f57db6e, 0x3e5ddc70, 0x3e437958, 0x3ea17d9e, 0x3f5d2337, 0x3da0b840, 0x3ebbee8a, 0x3ea81168, 0x3ef0c596, 0x3ec6c514, 0x3e422e20, 0x3f40c452, 0x3f2bd24e, 0x3e442174, 0x3c9587a0, 0x3ed7ec3e, 0x3f3429fb, 0x3f6dfcf8, 0x3ebf84b2, 0x3f4a9022, 0x3f23dafd, 0x3f774fee, 0x3f0819bd, 0x3f6a9486, 0x3f44cb26, 0x3d82f4c8, 0x3f357278, 0x3f56480b, 0x3ecc3076, 0x3ee6a840, 0x3f591675, 0x3da4caa8, 0x3f718358, 0x3f2f435c, 0x3f08fcb0, 0x3f6680ef, 0x3f39e1ae, 0x3f6e36b5, 0x3f314f87, 0x3f12309a, 0x3e0262b0, 0x3ee36666, 0x3f1af004, 0x3da00238, 0x3d93b0b0, 0x3f007353, 0x3e7a2bd8, 0x3f1d6c7f, 0x3e193548, 0x3e887c04, 0x3ecc8254, 0x3ece8006, 0x3eb2aa5a, 0x3e9b381c, 0x3f39d3ca, 0x3ebe38de, 0x3f75894c, 0x3f49b065, 0x3f270eaa, 0x3f7ed96a, 0x3e6ed5dc, 0x3f4c2350, 0x3e9635ea, 0x3de0b218, 0x3e9b0c62, 0x3ea4223e, 0x3f7df066, 0x3f7bb910, 0x3f5b64a4, 0x3e13dda0, 0x3e113c14, 0x3db82f18, 0x3e912f40, 0x3e4f07b4, 0x3f26b861, 0x3dbeda70, 0x3f37c8de, 0x3f0ac7fa, 0x3e979360, 0x3dfff0f0, 0x3f4fd16a, 0x3ea211aa, 0x3e5fc338, 0x3dd4b6c8, 0x3f6be5a1, 0x3f1ddc23, 0x3f500bab, 0x3e86441c, 0x3f402a0c, 0x3c4f3cc0, 0x3e8e86bc, 0x3f24c881, 0x3e67bcf0, 0x3cf3b500, 0x3f6f5123, 0x3f35378c, 0x3f12fdd1, 0x3f4b46a9, 0x3f34d642, 0x3f618818, 0x3ecb9592, 0x3f7a0d98, 0x3e297414, 0x3f49405a, 0x3f1941c8, 0x3f60ed84, 0x3f16fd3a, 0x3f7cc034, 0x3db31428, 0x3e3d6ac0, 0x3e04cb88, 0x3e7b7324, 0x3e93eb60, 0x3f794bef, 0x3f0c8e33, 0x3f19ebb9, 0x3f7f787c, 0x3d9427d8, 0x3f490a6b, 0x3b96de80, 0x3eb57cdc, 0x3e4325e0, 0x3f2ca37d, 0x3ed3a328, 0x3eb401d6, 0x3f6f8932, 0x3f4eab48, 0x3f59202a, 0x3d749bf0, 0x3f727c17, 0x3f6db717, 0x3ebe009c, 0x3e841b4e, 0x3f0eb52a, 0x3e8021be, 0x3f196472, 0x3f764abd, 0x3f1a2d89, 0x3f2be68f, 0x3f54858e, 0x3f0ff02c, 0x3e340fe4, 0x3f2185cd, 0x3f7cb696, 0x3f26a29f, 0x3eafc8f0, 0x3d90c708, 0x3edaf2e0, 0x3f2521cc, 0x3ef49a98, 0x3f58dcb6, 0x3ea7d180, 0x3e1bb02c, 0x3f6a1aad, 0x3eb394a2, 0x3f301c25, 0x3f520bd8, 0x3e07aeb4, 0x3f0b853a, 0x3f7984f2, 0x3f497a48, 0x3f314461, 0x3e325f8c, 0x3d051e70, 0x3ded2620, 0x3ec6e40e, 0x3d518140, 0x3f7649c4, 0x3f1936a4, 0x3f51b52c, 0x3ee85672, 0x3e944a30, 0x3f1540d1, 0x3f18997e, 0x3ba31200, 0x3f552ab5, 0x3f7b8b95, 0x3ec389ba, 0x3f642864, 0x3ecfd75a, 0x3f2fb0f3, 0x3f5da11b, 0x3e56fed4, 0x3eebb204, 0x3f6e77d9, 0x3f16f32e, 0x3f3f9efa, 0x3d98b068, 0x3f37a106, 0x3f6f2d74, 0x3e820e62, 0x3f50fc13, 0x3f0fa747, 0x3f3f2ca1, 0x3da95338, 0x3e06afc8, 0x3e9512ea, 0x3da86140, 0x3f51e6d0, 0x3ad07e00, 0x3efbf832, 0x3dc26948, 0x3e8d6f54, 0x3e8ede88, 0x3f79a642, 0x3f331cd7, 0x3f700323, 0x3ef31d8e, 0x3f78050a, 0x3f71aa8a, 0x3e4414c8, 0x3f6f6c5f, 0x3e064450, 0x3d210320, 0x3e1c088c, 0x3f0a410b, 0x3ed78a88, 0x3e1d6094, 0x3d4ce330, 0x3f7e5f07, 0x3f63d241, 0x3f4c3674, 0x3dc16bc8, 0x3df80890, 0x3edabcee, 0x3eb94008, 0x3da77048, 0x3e9e736e, 0x3ee674e4, 0x3df7be78, 0x3ef96414, 0x3f09281f, 0x3e2c02b8, 0x3e74362c, 0x3f2e0ee1, 0x3f01ff5a, 0x3f3de5d5, 0x3d8127b8, 0x3f5b9b46, 0x3f7b98f1, 0x3e993f08, 0x3f089379, 0x3f03021d, 0x3e32cabc, 0x3f19790e, 0x3cdba020, 0x3ddea6f8, 0x3f356643, 0x3f76f320, 0x3f51fa9b, 0x3e5c9b1c, 0x3eb22fca, 0x3e0a7a20, 0x3ed8e80e, 0x3f51cdf9, 0x3e9b8816, 0x3ec376ac, 0x3ec8e688, 0x3f04a40b, 0x3f3ab4b5, 0x3e94d3c4, 0x3db22238, 0x3c023640, 0x3dbb4a48, 0x3f679fb9, 0x3e8d1bf6, 0x3e420610, 0x3e1b9004, 0x3f16b085, 0x3f6a6b6e, 0x3f2a1907, 0x3e39c22c, 0x3f576cf2, 0x3e3b22b4, 0x3f152e47, 0x3d638720, 0x3cbcc3a0, 0x3ef31bc2, 0x3f1fca54, 0x3f451b37, 0x3e4b8b68, 0x3f23c45b, 0x3f248fcf, 0x3f75e088, 0x3f04151e, 0x3f4e1756, 0x3f42adec, 0x3f6571ef, 0x3f322735, 0x3f3c11c4, 0x3ede675c, 0x3f0e2a15, 0x3eb09402, 0x3e3b6b7c, 0x3c472800, 0x3d898160, 0x3f39b80e, 0x3f480a1e, 0x3f5deff4, 0x3e55e4d0, 0x3f21db91, 0x3ee97c30, 0x3e8f32f8, 0x3f5bb475, 0x3dbda638, 0x3f16f12e, 0x3f52ed8d, 0x3f0257ca, 0x3f544fdb, 0x3f280268, 0x3e9a594a, 0x3ee546e8, 0x3e1c2810, 0x3ec87438, 0x3f5fb336, 0x3f03501b, 0x3f2b7924, 0x3f22f754, 0x3d4aea80, 0x3f02ec34, 0x3f7f79e5, 0x3f25fc9c, 0x3c08a280, 0x3dcb3898, 0x3e7b0694, 0x3f0afae0, 0x3f3f0133, 0x3f768fbc, 0x3ddf8810, 0x3d6f1a50, 0x3f13fe60, 0x3ea37c1c, 0x3f1f9dcd, 0x3f40042f, 0x3dc8cb58, 0x3f712d9b, 0x3f2302c8, 0x3ef349a6, 0x3e61a508, 0x3f6d73d4, 0x3f355fca, 0x3e30d0cc, 0x3ef5a774, 0x3f2d61c2, 0x3f5efa8a, 0x3f705611, 0x3edc25bc, 0x3f190445, 0x3f0350b8, 0x3e40d918, 0x3e916348, 0x3ec95924, 0x3f52e13c, 0x3ef55e82, 0x3eb2f05c, 0x3ea39b5e, 0x3f242856, 0x3f3284b4, 0x3e94b6fa, 0x3e9fd99c, 0x3f684583, 0x3d4b4f00, 0x3ee81350, 0x3ef81ac2, 0x3f0faca6, 0x3ef5fe10, 0x3f53eda8, 0x3f7f633f, 0x3e54deec, 0x3f5d2e90, 0x3f14fe52, 0x3e9fe104, 0x3d0178c0, 0x3e98eb60, 0x3f2444c8, 0x3d957178, 0x3f6bedcb, 0x3b8f6800, 0x3eb3c32a, 0x3efcfd92, 0x3ee36d4e, 0x3ec223d0, 0x3ef54b3e, 0x3de4dc98, 0x3ef31280, 0x3f776a3f, 0x3e0853a8, 0x3f6c49fb, 0x3e53d250, 0x3ebe0a70, 0x3f359f3b, 0x3eafb468, 0x3e6b2b74, 0x3f02f05c, 0x3ecdf21c, 0x3d4ba150, 0x3eb68e26, 0x3f2686fd, 0x3f19725c, 0x3f2a08d3, 0x3eeef34e, 0x3f495faf, 0x3f735e74, 0x3e73594c, 0x3d8eb898, 0x3d8283b8, 0x3ecdba8a, 0x3e845460, 0x3ef0f7c0, 0x3f086c16, 0x3e89c828, 0x3ea2e1be, 0x3edf4e2c, 0x3e295d7c, 0x3f7152ad, 0x3f0002ea, 0x3f2e07dc, 0x3d9c6f88, 0x3eb81618, 0x3eee1092, 0x3e15a800, 0x3e6d6918, 0x3e594614, 0x3f26ea9e, 0x3f3a22f5, 0x3da12e30, 0x3f54fb12, 0x3d1c9100, 0x3f75dcac, 0x3f1702c1, 0x3cbffaa0, 0x3f5c777d, 0x3f246abf, 0x3d8de358, 0x3e4e8564, 0x3c0ec480, 0x3f2f3d52, 0x3f4f0720, 0x3f5869b7, 0x3d8d5068, 0x3f0ff831, 0x3ebf6a60, 0x3e356d04, 0x3f1b0841, 0x3f2a51d1, 0x3f48756f, 0x3e902698, 0x3eba6c6e, 0x3f789b74, 0x3dfe4558, 0x3ce61320, 0x3f192210, 0x3f55bdb5, 0x3e12caf0, 0x3f0051a6, 0x3f449833, 0x3f25bab1, 0x3f490b43, 0x3f227569, 0x3f786323, 0x3f0c3697, 0x3dcf02e8, 0x3e831d0a, 0x3ed29ea0, 0x3f396ad5, 0x3f2039f1, 0x3e107048, 0x3f666b9c, 0x3ea8e710, 0x3eaafe84, 0x3f0b19e0, 0x3e727ff8, 0x3ec4a136, 0x3ec690bc, 0x3db7b210, 0x3f4ba9b6, 0x3f70667d, 0x3f59ce18, 0x3f53bd30, 0x3ef17d8c, 0x3f207066, 0x3dec0188, 0x3f6eaeb3, 0x3ea4d9a2, 0x3f3e6334, 0x3d62ce10, 0x3ec38d8e, 0x3e6c502c, 0x3eec5906, 0x3f440057, 0x3e28bcd0, 0x3f29cfe6, 0x3edc2074, 0x3f718e70, 0x3c7b0c80, 0x3ef89c8e, 0x3f66bdf1, 0x3ebfdf80, 0x3df57108, 0x3e51b634, 0x3f7e035b, 0x3e5233dc, 0x3ee5b03a, 0x3ed29e72, 0x3f688ef0, 0x3ee63522, 0x3e7b6be4, 0x3f32fb4e, 0x3f68a697, 0x3eaea96a, 0x3f615116, 0x3f0965aa, 0x3e7e3d74, 0x3ca56180, 0x3f0929c4, 0x3ea08428, 0x3e9a6712, 0x3f3b5687, 0x3f3f1e73, 0x3f0ece49, 0x3e9d3b28, 0x3f10666d, 0x3f027f65, 0x3ef73f7a, 0x3f0d5c89, 0x3f7f0a14, 0x3f12fdaf, 0x3f1fecbd, 0x3dc6ca98, 0x3f01277f, 0x3e443e84, 0x3f67d3ec, 0x3f48fae8, 0x3f5ad5fa, 0x3eb0656c, 0x3e6a58dc, 0x3f0bd847, 0x3f057ab0, 0x3ca21960, 0x3ed907c2, 0x3f5b3862, 0x3f1fedb1, 0x3f4d2730, 0x3edfab0c, 0x3e81717c, 0x3f4b6bc1, 0x3f53697c, 0x3f2ba5cf, 0x3ea23ff8, 0x3ebd7fa0, 0x3f5a0f85, 0x3c5d5980, 0x3f279fd2, 0x3f27bad6, 0x3e306e0c, 0x3f448674, 0x3f0b90af, 0x3f1d7452, 0x3e453514, 0x3e1ba2e8, 0x3f2b871b, 0x3f07d16e, 0x3e7b9008, 0x3f04f1cf, 0x3f3c6147, 0x3d9c4208, 0x3e7ecff4, 0x3f671413, 0x3eec57aa, 0x3ebcbd72, 0x3eb239a4, 0x3ea43872, 0x3dbc7008, 0x3e5c5784, 0x3f449f13, 0x3f2ebe92, 0x3ee73112, 0x3f03f3cb, 0x3f4ea556, 0x3df7d078, 0x3f03f37a, 0x3ef82142, 0x3f1619d0, 0x3ed6933e, 0x3f33b79e, 0x3eaa2022, 0x3dc7ef58, 0x3ee5e184, 0x3d5be810, 0x3da4ed10, 0x3e5fa068, 0x3f588973, 0x3c3b4740, 0x3f77de66, 0x3ef4d7bc, 0x3ee91b02, 0x3ee58602, 0x3f5222ed, 0x3f70cbe0, 0x3d60d810, 0x3e88ceb2, 0x3f534e68, 0x3e1a306c, 0x3f458c71, 0x3eb8ca22, 0x3e442da8, 0x3e82504a, 0x3edc88a8, 0x3f21da37, 0x3e115da0, 0x3e01f7ec, 0x3e9c3eb6, 0x3f1bfd38, 0x3f780f95, 0x3e404f90, 0x3f7e7462, 0x3ed94262, 0x3f6f9ccf, 0x3eb7fd7a, 0x3f6b0471, 0x3d44c3f0, 0x3f50ae5d, 0x3f34d178, 0x3ead6a08, 0x3f27a4b6, 0x3e914308, 0x3e90cc92, 0x3d1debe0, 0x3f61c1b9, 0x3f134823, 0x3f2a814d, 0x3eeedd64, 0x3f1b15c8, 0x3f31a1ba, 0x3e4437f8, 0x3ecc2796, 0x3ce41b20, 0x3f002597, 0x3f39a677, 0x3f55c778, 0x3f47d34e, 0x3f543983, 0x3f05609f, 0x3f2bb2d6, 0x3daec9a8, 0x3ed9beae, 0x3e9859c2, 0x3f51ae0b, 0x3f6fce44, 0x3f4566e2, 0x3e913e3e, 0x3f206163, 0x3f1ad23e, 0x3e22e3c8, 0x3e417f88, 0x3f79ad00, 0x3f19f81d, 0x3ed73a18, 0x3eea5daa, 0x3f0b5bdb, 0x3f40cff4, 0x3f6f8603, 0x3ec2c82e, 0x3f5c4bb2, 0x3e08c228, 0x3ca40d80, 0x3d450fe0, 0x3eb59a7a, 0x3f3f3c4a, 0x3f617c07, 0x3ecf6f26, 0x3e913fbc, 0x3f2d4a48, 0x3f3ababf, 0x3e2afc54, 0x3eda0a2e, 0x3d51dd00, 0x3e02f2d4, 0x3e0d2200, 0x3e88f5a6, 0x3ebb2084, 0x3f64dc94, 0x3d86c5f0, 0x3eb21452, 0x3f63498b, 0x3f319c3b, 0x3eb7b504, 0x3f1e95c3, 0x3e949938, 0x3effa1e4, 0x3de08088, 0x3f4a7323, 0x3e7d6334, 0x3ebf5070, 0x3ea2d94c, 0x3ea66a3c, 0x3f04a629, 0x3f7015cb, 0x3f2eb99a, 0x3f398026, 0x3e529a40, 0x3e9c4dde, 0x3f772f27, 0x3f21f326, 0x3dded688, 0x3f77cb6f, 0x3f2b44a8, 0x3eadb7dc, 0x3f3e617b, 0x3f199ddb, 0x3f7eedbe, 0x3f1bdf85, 0x3ed3f304, 0x3f13228e, 0x3ed8bd6a, 0x3f1a097e, 0x3f32b1e2, 0x3f18417f, 0x3f68e58c, 0x3db6e728, 0x3f38846f, 0x3e628ecc, 0x3f063374, 0x3f6076f0, 0x3f673242, 0x3f67ca8e, 0x3f1f410b, 0x3f4ae052, 0x3f5e3eea, 0x3e957e5a, 0x3ee74f20, 0x3e89cc60, 0x3eb12bba, 0x3e84cbb0, 0x3efd8618, 0x3f4f8b28, 0x3ed1d7ca, 0x3efb6f0e, 0x3ebd8642, 0x3f7b414a, 0x3c8b5780, 0x3f277100, 0x3efcffaa, 0x3dffb6d0, 0x3eb2fe7a, 0x3f406b21, 0x3e8bdc72, 0x3f0455ad, 0x3ef692cc, 0x3d683510, 0x3d1d6250, 0x3ef59622, 0x3f477071, 0x3f58f999, 0x3f20c9a7, 0x3e40e780, 0x3e341ffc, 0x3f085ed3, 0x3ed67fe4, 0x3db2b568, 0x3ee90dfe, 0x3da8dee0, 0x3eee5dca, 0x3c9905e0, 0x3ec8013c, 0x3ebd557a, 0x3f6fd089, 0x3c09da80, 0x3f43fe75, 0x3d931318, 0x3e2be0ac, 0x3f7c5cfb, 0x3f165119, 0x3f570b66, 0x3dca4978, 0x3a9e6400, 0x3f21fa05, 0x3ed49f6a, 0x3f1d92b0, 0x3f7b7b36, 0x3f5c4291, 0x3f2cc8b5, 0x3e87901c, 0x3eb2a546, 0x3dbc1e70, 0x3e4bf77c, 0x3f726fa6, 0x3e5c56cc, 0x3e1ece54, 0x3e172bc0, 0x3ce629a0, 0x3f71d461, 0x3e62af64, 0x3e911fbe, 0x3e8ee43a, 0x3bb3c580, 0x3f06e073, 0x3f0f2e42, 0x3f373e46, 0x3eb56d8e, 0x3c9837e0, 0x3f3223cd, 0x3f552bb2, 0x3f79360c, 0x3f55cc2a, 0x3f49cfe7, 0x3f24dfb5, 0x3ed5161c, 0x3eb6a25c, 0x3dcbc9b0, 0x3e800750, 0x3ea240ce, 0x3ede991a, 0x3e8f8746, 0x3f2602ef, 0x3f16672c, 0x3f3f3a56, 0x3f1a264b, 0x3f546edd, 0x3f18e677, 0x3d242890, 0x3f27d72e, 0x3f73a182, 0x3f0dffe6, 0x3e888c62, 0x3f5c4d18, 0x3f169cbe, 0x3d7b8c40, 0x3f605ca4, 0x3f44e1c3, 0x3f4c64c3, 0x3f3b6024, 0x3ec74bb4, 0x3f4fe7ec, 0x3d031120, 0x3f1a9c3a, 0x3eafddd2, 0x3e2ac25c, 0x3e9922e0, 0x3ec26036, 0x3eebbab8, 0x3f495d11, 0x3d89a9d8, 0x3f19aff9, 0x3e85fce8, 0x3f5379d2, 0x3eece884, 0x3f53cf2e, 0x3f634ee4, 0x3e1ecc48, 0x3eef20a6, 0x3ec165ac, 0x3f3a4501, 0x3effdc42, 0x3e988ff0, 0x3f51f7da, 0x3f443ee8, 0x3e49edf8, 0x3f0ee752, 0x3f60e541, 0x3dfeb8b8, 0x3e9d672a, 0x3f71a387, 0x3f49cd1f, 0x3e4b5e48, 0x3f4407de, 0x3f1dcc19, 0x3f5db90d, 0x3df4e668, 0x3f2415ac, 0x3d2036c0, 0x3f1937dc, 0x3f2e41e7, 0x3df0ea08, 0x3f207d8d, 0x3f54de5c, 0x3ebd6b04, 0x3ccb1ce0, 0x3f3e12a0, 0x3f6466e2, 0x3d02c9a0, 0x3f049180, 0x3ef4e928, 0x3f3ce2f4, 0x3ec7cccc, 0x3e43afbc, 0x3f248e42, 0x3f43918a, 0x3e2cd7d0, 0x3e5667d8, 0x3f43b581, 0x3e14715c, 0x3f560b4c, 0x3e985292, 0x3f307ecf, 0x3f1e8f76, 0x3f127f33, 0x3f4ca87d, 0x3f10d78a, 0x3f78e196, 0x3eae9436, 0x3f091df0, 0x3f47b310, 0x3d3302c0, 0x3f4c97fb, 0x3f43dbe4, 0x3eafe3f0, 0x3dc86608, 0x3f79ec4e, 0x3f00ae56, 0x3db23db8, 0x3b78b900, 0x3e750ee8, 0x3f18c0bc, 0x3ee0f508, 0x3ed1941a, 0x3f252a81, 0x3e830b0c, 0x3e2a455c, 0x3e3457a4, 0x3ece5dc0, 0x3f474bae, 0x3e79391c, 0x3e3ca940, 0x3f52c8c9, 0x3e280e9c, 0x3f4bc808, 0x3eac37ea, 0x3f171c7f, 0x3e811d68, 0x3f628233, 0x3f081aeb, 0x3e668b58, 0x3e524fb8, 0x3f060431, 0x3efe42f4, 0x3ee88ba8, 0x3e904256, 0x3e97380a, 0x3f36e5fe, 0x3f52320d, 0x3f789972, 0x3e778920, 0x3ec925de, 0x3f6b3040, 0x3f00a8c0, 0x3f048bd4, 0x3ea06fd8, 0x3ef9e334, 0x3e7ef494, 0x3f5107ea, 0x3e78e178, 0x3f3a98cd, 0x3e966bf8, 0x3ecd02ee, 0x3f700d02, 0x3f789ad5, 0x3ecbde24, 0x3f4ebdab, 0x3f1720d2, 0x3f3a08c4, 0x3f3a7fc6, 0x3e2ffae4, 0x3e0faae8, 0x3ecc09e8, 0x3f1f00a4, 0x3ec6a7d6, 0x3f762028, 0x3f4d490d, 0x3eed2a50, 0x3e0d1d84, 0x3ed2208e, 0x3e6a8dfc, 0x3e506670, 0x3ebe807e, 0x3e226ae8, 0x3ef31cae, 0x3ea68cf8, 0x3f514123, 0x3e9c3530, 0x3f744663, 0x3e9f6e0e, 0x3f34916e, 0x3ed4a298, 0x3eb41312, 0x3ec7f226, 0x3f0fd8be, 0x3f680726, 0x3d34bb20, 0x3f109d2b, 0x3f5ee98a, 0x3e5208a0, 0x3ecff9f0, 0x3f00bdd9, 0x3e64ad70, 0x3e1f3b94, 0x3f06c818, 0x3d3448f0, 0x3f5c78e3, 0x3f01590a, 0x3f3f5d23, 0x3f76c802, 0x3f4a8229, 0x3e2f6268, 0x3e5f4e80, 0x3da63b10, 0x3e218fbc, 0x3ee79b0a, 0x3ef12da4, 0x3f0b1eb3, 0x3f5d3ef2, 0x3ece0f6e, 0x3f72eaea, 0x3f609c76, 0x3ec588a2, 0x3f26821b, 0x3f34b1fb, 0x3e9d18d2, 0x3e36f0dc, 0x3eb39350, 0x3f04961a, 0x3e89e9d4, 0x3cff9ae0, 0x3d65f5a0, 0x3f66ffb4, 0x3f06a561, 0x3edb3446, 0x3ec6fc78, 0x3f3c4eb4, 0x3f4c77b3, 0x3deb7f70, 0x3f12c831, 0x3f0bad94, 0x3e3476e4, 0x3ee84aac, 0x3e89db56, 0x3f0ae963, 0x3cff0160, 0x3f0f3758, 0x3f46ce71, 0x3ebaa738, 0x3f65f39a, 0x3ef8b3fc, 0x3f16d8bf, 0x3f3a1f29, 0x3f35b3c0, 0x3e8f1cfe, 0x3e51f31c, 0x3f31af9a, 0x3ed1fbfa, 0x3f027566, 0x3f22276a, 0x3c632300, 0x3f06a19e, 0x3f11828f, 0x3f15517c, 0x3eec5686, 0x3f37849b, 0x3ecff914, 0x3f288069, 0x3f6f67a9, 0x3f1c340a, 0x3f064ff6, 0x3f358da9, 0x3f0db027, 0x3f080aae, 0x3ec92462, 0x3f4fa70a, 0x3f10f69f, 0x3ee25440, 0x3eace126, 0x3f0fd537, 0x3f72877d, 0x3eb3cf50, 0x3f76d9f9, 0x3f732b7a, 0x3e920596, 0x3ec8e89e, 0x3ebdd1e4, 0x3ea91346, 0x3f22981e, 0x3d592dc0, 0x3ee045d6, 0x3f435a29, 0x3dc14358, 0x3f4e6f74, 0x3f70eeb9, 0x3e5a1320, 0x3f0fb2e1, 0x3ef85dc6, 0x3f5e4519, 0x3f319171, 0x3f34a145, 0x3f5e7569, 0x3eb26be2, 0x3f414f54, 0x3f1a466c, 0x3f21fc0c, 0x3f582f71, 0x3f7fd18b, 0x3e99f12a, 0x3eaa84c0, 0x3f20f760, 0x3e347ea4, 0x3e1edd98, 0x3dc48998, 0x3dd5ace0, 0x3e953030, 0x3f26d6dc, 0x3e7fd7f8, 0x3f5a4b96, 0x3f387a47, 0x3f577696, 0x3f1e696f, 0x3f4d9809, 0x3df64db8, 0x3e6a57ac, 0x3f504830, 0x3aa13e00, 0x3efcfd44, 0x3f407dab, 0x3f3849a3, 0x3f09fa5d, 0x3ec16df8, 0x3f00d206, 0x3d8b01d8, 0x3f2b3041, 0x3e8363ee, 0x3f705db6, 0x3e8febdc, 0x3f097505, 0x3f58532a, 0x3f12c068, 0x3f4edfcb, 0x3ef9bfd4, 0x3ed74622, 0x3d4071a0, 0x3d135070, 0x3f0972a9, 0x3df15ad8, 0x3f4417ef, 0x3e1c6988, 0x3ea42372, 0x3f645560, 0x3f45967c, 0x3d368900, 0x3ee80cfa, 0x3e67671c, 0x3f48c9dd, 0x3dc8a3d0, 0x3f74e491, 0x3e78e600, 0x3e1e1fbc, 0x3da61ec0, 0x3e6ab84c, 0x3d9620c0, 0x3eb9f948, 0x3f5c169c, 0x3f643138, 0x3e088630, 0x3f723855, 0x3f4eff0f, 0x3d5799f0, 0x3f40e570, 0x3e62c9e4, 0x3f5817d0, 0x3e9cb156, 0x3f3dca3d, 0x3f1e4567, 0x3e19d6c0, 0x3f7ceae9, 0x3f276397, 0x3eca861a, 0x3f4f2fec, 0x3f429788, 0x3f1c976f, 0x3ed929ba, 0x3f560095, 0x3ebc78e8, 0x3e8d7156, 0x3e19952c, 0x3db0afd0, 0x3e94a56e, 0x3f051ecb, 0x3f43665f, 0x3eda474e, 0x3e2f0b2c, 0x3e043530, 0x3dab6028, 0x3e9a58d4, 0x3d966070, 0x3f09c912, 0x3dd51d78, 0x3e8a96ea, 0x3f4bcc7c, 0x3d9942f8, 0x3ebe3416, 0x3f309cd0, 0x3ef365a2, 0x3f43957d, 0x3dc081b8, 0x3ecbb09a, 0x3f0535f7, 0x3ef6717e, 0x3e5845b0, 0x3f1072e5, 0x3edbc85a, 0x3f71f39b, 0x3f30676e, 0x3c126b40, 0x3f27b5f7, 0x3ec6872e, 0x3eedc058, 0x3f5469a4, 0x39b64000, 0x3ebce648, 0x3f3ea5e5, 0x3f283526, 0x3f32f4cc, 0x3d0e8b50, 0x3e43fe94, 0x3f579a71, 0x3e8984e6, 0x3f18a322, 0x3e940f60, 0x3d95f7e8, 0x3e7073c4, 0x3ef1eac6, 0x3e40a1d0, 0x3f47cb81, 0x3f1fa1ac, 0x3f1579ce, 0x3f741f69, 0x3f017077, 0x3d032bd0, 0x3f33b776, 0x3e0b9120, }; // 4,6,6,7 uint32_t kernel_vals[] = { 0xbd4a03c3, 0xbc5236e0, 0xbcae018c, 0x3bbe1100, 0xbd5142e3, 0x3d87edd1, 0xbd47b618, 0x3b769320, 0x3d9ab045, 0xbd05cbfe, 0x3d61fe4a, 0x3c25a5c8, 0xbd900d38, 0x3d62a71e, 0x3d9c1deb, 0xbcdfe380, 0xbcfb6226, 0x3d733b32, 0xbccdcb56, 0xbd922153, 0x3d6b1ada, 0xbd6120bb, 0x3c675e68, 0x3d9ab0b5, 0xbd665cdb, 0xbd954bc3, 0xbd8b4e1e, 0xbc8efd34, 0x3d761bda, 0x3cc9bd6c, 0xbb01d160, 0xbd5238bb, 0xbd73ef38, 0xbb98c350, 0x3c010f40, 0x3b2d32a0, 0xbc32d1c8, 0xbc4765c8, 0xbc0e9040, 0x3da601a9, 0x3d9fec2b, 0x3da50ef9, 0x3cfd2260, 0x3d75a5aa, 0xbb2958e0, 0xbcf45a30, 0x3d5b947a, 0x3b4502a0, 0xbd87a9ac, 0xbd30ab90, 0xbd7e999b, 0xbcdc1fe0, 0x3cf19a1c, 0x3cf83e74, 0xbd6ce22e, 0x3c9412e0, 0xbd6314f8, 0xbd8989b6, 0xbb206ee0, 0xb94f9800, 0xbb4cfd20, 0x3da94535, 0xbd91357b, 0xbd0a68a0, 0xbd84500b, 0xbda98373, 0xbd90c926, 0x3cce5310, 0xbd666610, 0x3cf01390, 0xbce33ad6, 0xbaae3e40, 0xbc9744a0, 0x3c36b518, 0xbc9bbcc4, 0xbd87c6ca, 0xbd829a38, 0xbd1270c6, 0xbd2f3168, 0xbdaa5313, 0x3da73187, 0x3bd83540, 0xbd7bb888, 0xbd9c2266, 0x3d385dba, 0xbd7461cb, 0xbd7f31ab, 0x3d800dc7, 0xbcbc873c, 0xbd667fb3, 0xbd9abfd4, 0x3d22eaa6, 0x3c806804, 0xbcb97cc0, 0xbc88b354, 0xbda676d8, 0xbd4ed83b, 0xbd1a0aae, 0xbd7773c8, 0x3bf2a210, 0x3ce93214, 0x3d9452fb, 0x3c9b2c44, 0x3c990d8c, 0xbd964a23, 0x3d79671a, 0xbc6d6958, 0xbd69e633, 0xbd138708, 0xbbc895d0, 0x3d2790f6, 0x3c61ca38, 0xbb4f0e20, 0xbd940883, 0x3d7bfc2a, 0x3d6fdb12, 0x3d315be2, 0xbd2d4c3b, 0xbd0c25c0, 0x3d72df32, 0x3c917af4, 0xbd8c49b7, 0xbd0b3336, 0xbd59673e, 0x3d84b6f9, 0x3d6b8ebe, 0xbc50ffa0, 0x3da06631, 0x3c677ab8, 0x3da59d41, 0xbda8ae8a, 0x3daa0c4b, 0x3c5d9af8, 0xbd87d57a, 0xbd2fb7e3, 0xbd5eb736, 0x3cc0fb3c, 0x3bec2f80, 0x3d62a892, 0x3d01ef10, 0x3d5d3c0a, 0x3cacdaa0, 0xbcb23880, 0x3d6bfc32, 0xbd8c4892, 0xbcc77b7c, 0xbd366458, 0xbc0f6448, 0x3b6d7660, 0x3d259518, 0x3d917fed, 0x3c778448, 0xbd9d1dc6, 0x3daa79e5, 0x3c574c60, 0x3d8fcc0b, 0xbd8a1148, 0x3ae3dc00, 0x3b02cd80, 0x3ca7b88c, 0xbce928d6, 0x3d6000fe, 0x3d7cd93a, 0xbd0491f3, 0x3d939069, 0x3da781f5, 0x3cab431c, 0x3d707002, 0xbd09fcfe, 0x3cf1dfc4, 0xbcc6e010, 0x3d9b0a09, 0xbc938a64, 0x3d934c85, 0x3d044c48, 0x3d8bccb1, 0xbd7820d0, 0xbcd881ac, 0xbd0c0308, 0xbda88d38, 0xbd1c52db, 0xbd090ae8, 0x3d478712, 0xbd3add30, 0x3d6eecaa, 0x3d436ff2, 0x3c0c4e38, 0x3d57f8ba, 0x3d941841, 0x3d893f19, 0xbcbbe2bc, 0x3d5f09d6, 0xbd7a70a8, 0xbc3c97c8, 0x3c817dc4, 0x3d4588a2, 0x3d522efa, 0xbd9de178, 0xbc1b6868, 0x3ca2b0ac, 0x3da67919, 0xbd61e47b, 0x3d30937a, 0x3d20a766, 0x3d83eabd, 0xbda09743, 0x3d1bcf6e, 0xbd0e940e, 0x3c1630e8, 0xbd95ac72, 0xbcbe5580, 0xbd850cff, 0xbd0121cb, 0xbda5dcd3, 0x3c597e38, 0xbd048f08, 0x3d7364e6, 0xbc5b3fe0, 0xbb9ecb50, 0xbcc07970, 0x3d495e42, 0xbd7244a8, 0xbba458c0, 0xbd2938bb, 0xbc857b8c, 0x3d7c964a, 0xbc4a2920, 0x3c4ee508, 0xbd8f9162, 0x3d6936f6, 0xbcf24430, 0x3c83eb40, 0x3c69dee0, 0xba93cac0, 0xbd195598, 0x3d18eb9a, 0xbd646000, 0xbc436438, 0xbd198366, 0xbca107f4, 0x3d87a943, 0xbd06fdc0, 0x3cb5c450, 0x3d386062, 0xbd2c5af0, 0xbbcde190, 0x3da093c1, 0x3d3340ca, 0x3d7b3e6a, 0xbd884b9b, 0x3cc6e034, 0xbc27b048, 0x3d685ba2, 0x3d47e7fa, 0xbd7c1920, 0x3d020fa8, 0x3cfede94, 0x3b942550, 0x3d9e15cd, 0xbd87bafb, 0x3d1b78de, 0xbcc421a0, 0x3d2fbc62, 0xbc84d870, 0x3d9fba41, 0x3d9d1cc9, 0x3d57c20e, 0xbc382738, 0x3d9a5495, 0xbcce81d6, 0x3c6d1f18, 0x3cdc9670, 0x3da20251, 0xbda7c0eb, 0xbda8c18b, 0x3d23aef0, 0xbd44bb1e, 0xbc7d4a58, 0xbc1d0c88, 0x3c8b2db4, 0xbc613720, 0x3d988a2d, 0x3d9f800d, 0xbda3b07e, 0xbd560d4b, 0x3d84a039, 0xbd485743, 0x3c8ffad4, 0x3ca4b1f4, 0xbd076a66, 0x3d9fe6cf, 0x3d1e1f82, 0xbd73ba73, 0xbd4d1ea3, 0xbd1b65a8, 0x3cce6e20, 0x3d5626ce, 0x3d97d1af, 0xbd827e7a, 0xbd3a5a08, 0x3ccbcf1c, 0x3cb14adc, 0x3d00c4e0, 0xbd824f02, 0xbcab27c6, 0x3d8a989b, 0xbd982f57, 0xbd6df280, 0xbc9ad2bc, 0x3d8adfa9, 0x3d1af2f8, 0xbcb937e6, 0xbd849250, 0xbd869830, 0xbb81f4b0, 0x3d80eaed, 0x3d659d6e, 0xbd6d9283, 0xbd911c08, 0xb9dd0900, 0xbcddf680, 0x3d875dd1, 0xbce7e3e6, 0xbd261250, 0x3d638eca, 0x3ce98ecc, 0xbd7a0fd6, 0x3d03a7fa, 0x3cdbc19c, 0xbd83005c, 0x3ccd6be4, 0x3d743cca, 0xbcb62090, 0x3d8e6675, 0xbd069c18, 0xbd9910cc, 0xbd40193b, 0xbc57c220, 0x3da191a9, 0xbd44f610, 0xbd30923b, 0x3ccfcfd0, 0x3d99dd31, 0xbda5ff74, 0xbd6cf72e, 0xbc9be3c4, 0xbc9468f4, 0x3d8ea223, 0x3d2b00c2, 0x3da1cfc5, 0x3d769002, 0xbc0ba500, 0x3ca23384, 0xbd455806, 0xbda0bce0, 0x3c75e600, 0xbb8ed8d0, 0xbd3820d3, 0xbd59c020, 0x3d3931da, 0xbd6e0228, 0xbcfc3f16, 0x3d424db2, 0x3ce49904, 0x3cb2f314, 0xbd09cc83, 0x3da8afe5, 0x3c0677c8, 0xbd24a163, 0x3d370cd2, 0xbd925bee, 0x3cb6c29c, 0x3c2a68c8, 0xbd340246, 0xbc050168, 0xbd216376, 0x3d340a32, 0xbd2faa58, 0xbd83fb53, 0xbd78bfde, 0x3da08a5d, 0xbd36e5f0, 0xbb33c3e0, 0x3d3c6dbe, 0xbc6b0880, 0x3d946a69, 0xbd733f56, 0x3d8743e3, 0xbda8f65f, 0x3d66b4d6, 0xbc0493f8, 0xbcb2bde6, 0xbd5d4a2b, 0xbd09095b, 0xbb6b1e20, 0x3d8f511d, 0x3d08ee3e, 0xbd1fc2ee, 0x3b389ba0, 0x3d5b997a, 0xbd4845c8, 0x3cc9af00, 0x3c9d8610, 0x3d004b8e, 0x3c2ed268, 0x3da3da01, 0x3b3a9a20, 0xbcfd49f6, 0xbd56ae76, 0xbd03c61b, 0xbd5726ee, 0xbd5a2928, 0x3d55484a, 0x3c9a634c, 0xbd8770c6, 0x3d6d1f0a, 0x3d33e832, 0x3d694b3e, 0xbcc187fc, 0xbd242a76, 0xbd13130e, 0x3da72273, 0x3d92b731, 0xbd4aebb6, 0xba1b6580, 0x3d72c8e6, 0x3d4925e2, 0x3d236c5e, 0x3da15fff, 0xbaedc400, 0x3d4c3222, 0x3cbe0dac, 0x3b0f3d80, 0xbcdc1c6c, 0xbc492478, 0xbb4e9ce0, 0xbc4403a0, 0xbca3c834, 0xbd9505ff, 0xbd40e9c8, 0xbcafff9c, 0xbc7b90e0, 0x3cc9f06c, 0xbd4b6eab, 0x3d7358ea, 0x3cbcc304, 0xbd7b946b, 0x3da83db9, 0x3da7ba81, 0x3d7273aa, 0x3c9fb3f4, 0x3d35f28a, 0x3cb64c2c, 0x3d13ae6a, 0xbb8e24c0, 0xbd0a239b, 0xbcac75bc, 0x3d37fdce, 0x3c8e076c, 0xbd19c92e, 0xbd8af5ca, 0xbce7a0e6, 0xbd9bef43, 0xbd71ac18, 0xbc20bd68, 0xbd8713cb, 0xbd0ba7f6, 0x3d9bdc03, 0xbd748a23, 0x3cf9f78c, 0x3d1957ce, 0xbcb48d90, 0x3d87a11d, 0xbd368300, 0x3d71779a, 0x3d9f7779, 0x3d13d07e, 0x3d78d2a2, 0xbb27f100, 0xbc85c52c, 0x3d71496a, 0x3d9dd073, 0xbd64cd66, 0xbd0dec4b, 0x3d5366f6, 0xbd140f3e, 0xbccf4696, 0x3d890e07, 0xbd5fc223, 0xbd48bb08, 0xbb1e2120, 0xbcf35ff0, 0xbb3fa780, 0x3d2367c0, 0xbcb8fd1c, 0x3c4230a0, 0x3c28b8e0, 0xbd843ad8, 0x3d667bb2, 0x3d6ba9ba, 0xbd31a7c8, 0xbc91a29c, 0x3d1f525e, 0x3d56d02a, 0x3c58f918, 0xbd4e7748, 0xbd069380, 0xbd868d93, 0x3c189918, 0x3c4db988, 0xbd597f13, 0xbd66b160, 0xbc9c6190, 0x3c6cd880, 0x3beff080, 0xbd4fd32b, 0xbda0b9f6, 0x3c616068, 0xbca808ac, 0x3c9ac354, 0xbd344e9b, 0xbb158160, 0x3b365c60, 0xbd3e3f5e, 0xbc0d2708, 0x3d62fcc6, 0x3cda7c50, 0x3d153bc0, 0x3d158ff8, 0x3d4ebf7a, 0xbbdae480, 0xbd6a50c6, 0xbd7e4803, 0xbc7792e8, 0xbd12d0de, 0x3c343060, 0xbd7420e8, 0xbc5a75f8, 0x3ce2c7c0, 0xba3b0480, 0x3ccd7200, 0x3c3f2c08, 0xbd46fff0, 0x3d4a83aa, 0xbd11f5d6, 0x3d3bee22, 0x3d36d2b2, 0x3a294080, 0xbbed67d0, 0xbd8575c0, 0x3ccbd3dc, 0xbd7b58d6, 0x3cfc2f3c, 0x3d10d15e, 0x3d9eac33, 0x3d63527e, 0xbd95759f, 0xbd817ba4, 0x3d050c4e, 0x3d93373d, 0x3da49995, 0x3d90861d, 0x3d55d23a, 0x3d3b2d0a, 0x3d9d3063, 0xbd723016, 0x3cc20d70, 0xb9c62100, 0xbd859a97, 0xbd0d1698, 0xbda20baa, 0x3c74b958, 0x3d11e536, 0x3d9a2b91, 0x3d35b086, 0x3d7029e2, 0xbd8368e6, 0x3d2295c8, 0x3d5e2072, 0xbc1980a8, 0xbd01fb43, 0x3d507efa, 0x3d84132b, 0xbd69cbb8, 0xbd124ef8, 0x3d05e09a, 0xbd583096, 0xbd25dcb8, 0xbc9b34f0, 0xbc012fe0, 0x3cf104c4, 0xbc939eec, 0xbd92f58e, 0xbda36403, 0x3d4ac81a, 0xbd9225a3, 0xbd3a51c0, 0x3d98faeb, 0x3d6f850e, 0x3d4396c6, 0x3d2b0e4a, 0x3da2cb89, 0x3d77ff42, 0x3d680d82, 0xb7820000, 0x3d04fd7a, 0xbc040aa0, 0xbcd8f0f6, 0x3cf44ea0, 0xbd972e2a, 0x3da9c73b, 0xbd958eda, 0xbc3de068, 0xbbf73cf0, 0xbcaed310, 0xbd9136ac, 0x3d3f64ca, 0xbd939ec8, 0xbd5295ab, 0xbcf5ca66, 0xbd974058, 0xbd3b6956, 0x3c663100, 0xbd4bc706, 0x3cd65f44, 0xbc8aa470, 0xbd77e1fb, 0x3d827151, 0x3d12755e, 0xbd62511e, 0x3cc7c950, 0xbd526e3e, 0xbd26b046, 0xbd03d88b, 0xbdaaa8ee, 0x3c87e5bc, 0x3c4d17b8, 0x3ab2c4c0, 0xbb761120, 0x3d96b75d, 0xbd8fadcf, 0xbc7c0238, 0xbc6dd6a0, 0x3c67ac88, 0xbd686143, 0xbd8ab51f, 0xbd2b4853, 0x3d4d83ca, 0x3d0652e6, 0x3da86b55, 0xba274280, 0x3d9f8853, 0x3d1f1aca, 0xbd1ff04e, 0xbd87a7e4, 0xbbeb7310, 0xbd0e4be0, 0x3d82c1f5, 0x3b93f100, 0xbc48fda0, 0xbca725a0, 0x3cc52edc, 0xbd0d028b, 0x3c064460, 0x3d108328, 0x3d445006, 0x3ca2ebcc, 0x3cb4c6a0, 0xbd918164, 0xbce079b0, 0x3d468be6, 0x3bcf5b30, 0x3c94a440, 0x3d57dd62, 0xbda84590, 0x3d4c6202, 0x3c5a8a08, 0x3d1c1212, 0x3cb9ae74, 0x3d50fd96, 0x3d0b3670, 0xbd3f0786, 0x3d88c839, 0xbceb9f90, 0x3c353208, 0xbd91131b, 0x3d61f992, 0x3d596c52, 0xbcb54dc0, 0xbd5eb8ce, 0x3bf4c430, 0xbce49680, 0x3c96c7d0, 0x3da53077, 0x3d8b11d5, 0x3d007956, 0xbd4240ce, 0xbd2dd5b0, 0xbd91414f, 0xbd9d1547, 0xba83de00, 0x3d2867f2, 0x3d893173, 0x3d8460a1, 0x3d2e6bfa, 0xbd9f0580, 0x3d808d1d, 0xbce392b6, 0xbbcea8c0, 0xbd4bbc6b, 0xbc0c4918, 0x3d4201fa, 0x3d42c78e, 0xbd1ed16e, 0x3d447092, 0xbcb6e20c, 0xbca1eb10, 0x3c9982f0, 0x3c174de8, 0xbd4b2130, 0x3d64072a, 0x3c003838, 0xbd98af67, 0x3cde6524, 0x3d9eac01, 0x3d3c4262, 0x3d708e6a, 0xbd82ab1f, 0xbd6b1bf6, 0xbd1b98a0, 0xbcfccf66, 0xbd99004a, 0x3d9f1509, 0xbd851e14, 0x3d8a5981, 0xbda1edb8, 0xbd828fc6, 0x3d17dfd6, 0x3d3fb852, 0x3d85bafd, 0x3cbb2a14, 0xbc00aed8, 0x3d563aee, 0xbccda146, 0x3daa4fc9, 0x3d009e36, 0x3d043db6, 0xbd59b186, 0xba87d740, 0xbcf34820, 0xbd601c9b, 0x3d879839, 0xbc78e9e0, 0x3d522172, 0x3d843c15, 0xbcf89fd0, 0x3d9de679, 0x3c76e580, 0x3da022d9, 0xbb2b0960, 0x3d8d958d, 0x3bb72830, 0x3d47e44e, 0xbd861bcb, 0x3d841fbd, 0xbcb14396, 0xbd9e5a1f, 0xbd50064e, 0xbd65881e, 0xbc2c1178, 0x3c9935f4, 0x3cd26b14, 0xbd964b93, 0x3d0ece78, 0xbd3823e8, 0xbd390750, 0x3cc02404, 0x3ce14fc4, 0xbd468230, 0x3c71fc00, 0xbbcb8d10, 0xbd65f760, 0x3d6b7c6e, 0x3cf6fde4, 0x3b848080, 0x3d8c8471, 0x3d79d7da, 0x3bc5f110, 0x3d475ae6, 0x3cc6fd24, 0x3d216f98, 0x3d97f671, 0x3cc07234, 0xbca16f40, 0x3d30e80a, 0xbd0c4656, 0x3d071596, 0x3c7ee198, 0x3bd44630, 0xbc975adc, 0x3cf64664, 0xbd98952e, 0xbd658dce, 0xbd94b083, 0x3d29ce46, 0xbc531258, 0x3d8a636b, 0xbc40ea08, 0x3da40a5d, 0xbd13582b, 0x3d8f2b9d, 0xbd16a40e, 0xbda1e36a, 0xbd6b0edb, 0xbd3335bb, 0x3adacdc0, 0x3bdebd00, 0xbd45d8b8, 0xbd6f4a10, 0xbc522c38, 0xbd65d418, 0xbda75ad6, 0xbc027a68, 0x3da13ba5, 0x398f4500, 0xbd855b0c, 0xbaae74c0, 0x3c77ccf8, 0x3cd991f0, 0x3c98cfcc, 0x3c67cfc0, 0x3c92a474, 0xbda73f5a, 0xbd47c613, 0xbc87a984, 0xbd98ea20, 0xbd688dd6, 0xbd9e1cc8, 0xbd63b108, 0xbd42dc90, 0xbd31977b, 0xbcc06b16, 0x3d748c1a, 0x3d081cd2, 0x3b634420, 0x3ce49d64, 0x3cc3b2dc, 0xbd987c76, 0xbd08e1a6, 0xbc03aa00, 0xbda3ae33, 0x3c9f9694, 0xbd6b8b8b, 0x3c19d538, 0x3c7765e0, 0x3d0880ce, 0xbd1a8f38, 0x3d3f94a2, 0xbd72580e, 0x3d047fe6, 0xbb229f80, 0xbd289976, 0x3d882ef5, 0x3d83c213, 0xbbffd530, 0xbd12bb66, 0x3b79b6a0, 0x3d320592, 0x3d41b30e, 0x3d0dfdb6, 0xbb816370, 0xbc16cf78, 0xbd96a58f, 0xbbcbc7c0, 0x3cd957bc, 0x3d8f1b19, 0xbd3e4b03, 0x3da8f2e7, 0xbd2e5dd3, 0x3be3d140, 0x3d1a5f92, 0x3cc65100, 0xbcb5ecd6, 0xbd98aac0, 0x3d8f6871, 0x3d17c096, 0xbb20c5a0, 0x3ce1e18c, 0xbd8fc1c0, 0xbbfcf430, 0x3ae3df00, 0xbd092c23, 0xbcece9ec, 0x3d30a792, 0x3d31f3f6, 0x3d9680b1, 0x3d06d1da, 0xbc4dfd68, 0x3d9dd547, 0x3d85ae15, 0x3d205320, 0x3d14a018, 0xbc8ad6fc, 0xbd42672e, 0xbd7779de, 0x3da53843, 0xbd69a3d8, 0xbd3bbe16, 0xbd7468a6, 0x3cf76de0, 0x3d3af472, 0xbbc2b040, 0xbd471f58, 0xbd9682bb, 0x3cb26d40, 0xbda47dee, 0x3d47fdba, 0x3d66c7e2, 0xbcfb69ac, 0xbd9d1c80, 0xbc4a0e68, 0x3cf65330, 0xbd1b30ab, 0x3cd110a0, 0xbc572bd8, 0x3d8fe485, 0x3abb1f40, 0x3d8baaed, 0x3c785ca8, 0xbda6b760, 0x3c642688, 0xbd9156a0, 0xbb8e1b90, 0xbd393ae0, 0xbcba77bc, 0xbda80d80, 0x3d89eb6d, 0xbcd71d4c, 0x3d5b3d2e, 0x3da096c1, 0x3d977241, 0xbc756640, 0x3da514a5, 0x3d3e230a, 0x3ba671b0, 0xbda375c7, 0x3d8f01c3, 0xbd5e89ee, 0x3d9913a5, 0x3ac94200, 0xbd46aec3, 0xbd85060f, 0x3a4ca080, 0x3d3901f2, 0xbd2cc0d6, 0xbd38388b, 0xbd977c72, 0xbd68695e, 0xbd356b80, 0x3c396248, 0x3d7d26e6, 0x3d9f7b59, 0x3d5170ce, 0xbd8fc497, 0x3b8a3e50, 0xbd60a916, 0xbcf97180, 0x3ceb3d34, 0x3c90038c, 0xbd905acf, 0xbd447fa0, 0xbcb5506c, 0x3ca3926c, 0x3ce23a2c, 0x3cc87fb0, 0xbc6f4800, 0x3cf6c04c, 0x3ceff3dc, 0x3cdb344c, 0xbd747cd6, 0xbca6ca9c, 0x3da86511, 0x3d35aa3a, 0xbda53be8, 0xbd4e883e, 0x3b353780, 0xbd67b886, 0xbd8006bf, 0x3a1be600, 0xbd16e450, 0xbda47564, 0xbcaebbc0, 0xbd900413, 0xbd9261d2, 0x3d4f1bba, 0xbc26e7c0, 0xbd4c509b, 0x3d925d1d, 0xbda9f75b, 0xbd958d2b, 0x3d8b3fb7, 0xbd0bd06b, 0xbd08bf1b, 0x3d904c03, 0xbd321c06, 0xbd90b0ff, 0x3d5b7eaa, 0xbc8051d0, }; // 7 uint32_t bias_vals[] = { 0x3d7895da, 0x3d66c0c2, 0x3da8f295, 0x3c8090d0, 0x3b0969a0, 0x3da4fbad, 0xbd55808e, }; // 4,5,3,7 uint32_t output_exp_vals[] = { 0x3e800009, 0x3e5cc2bb, 0x3dd8b7fc, 0xbd6f5e64, 0xbf0049b7, 0x3db2113b, 0x3c2e3283, 0xbea7f82c, 0x3e190482, 0x3e964a40, 0xbdeea57b, 0xbe488eb1, 0x3dbd218d, 0xbd843b27, 0x3c353168, 0x3dadf9bd, 0xbe95f953, 0xbe2ab356, 0xbe95d365, 0xbe939e65, 0x3e89892d, 0x3e25c7d0, 0x3e9b0553, 0x3e39f0f1, 0x3eca599b, 0xbe152c42, 0x3ea822df, 0xbe339202, 0x3e6d580b, 0x3e9794f4, 0x3dde4c3a, 0x3d8b0621, 0xbf1a21a5, 0x3dfc1fe5, 0x3e49eed5, 0x3e5ebc15, 0x3d19c5a0, 0x3d8d4f3d, 0xbea808ac, 0xbecf76da, 0xbee54599, 0x3ea8e7bd, 0x3d4c47a1, 0xbcd8a9d4, 0x3e1d24d0, 0xbcd58c40, 0xbee6366e, 0x3e88acad, 0xbbb28961, 0xbea28a89, 0x3ea61d80, 0x3ed57081, 0xbdf12a11, 0xbf1070d0, 0xbeb9ecba, 0x3d948c77, 0xbe1630c7, 0xbd865d9a, 0x3d694f50, 0x3d618060, 0xbe90c00a, 0xbc7090db, 0x3ec9335e, 0x3d69cdbb, 0x3d960288, 0x3edc27a8, 0x3e078210, 0xbebb55cf, 0x3ddc602d, 0xbde874ef, 0x3db7ea35, 0x3e592130, 0x3e2a8154, 0xbe215282, 0xbf16bf05, 0xbdadf37e, 0x3daf312c, 0xbe3b1d5e, 0xbdf7a1ce, 0xbdbffeb8, 0xbe1678e4, 0xbe663303, 0xbe360a72, 0xbe2acad4, 0x3e436c58, 0x3da03a17, 0xbcd28ce2, 0x3e86bb89, 0xbd8a93ca, 0x3e1ccc14, 0xbcc44d16, 0x3e75ece0, 0x3e21a281, 0x3e9e283c, 0xbdc6f8fb, 0xbdd9e63e, 0xbe41d862, 0x3e958b70, 0x3dd38536, 0x3d36528a, 0xbdae929f, 0xbce4e6a2, 0xbd965d20, 0xbe1e6fc7, 0x3e596745, 0x3e6acaab, 0x3e0c2af5, 0x3ec92511, 0x3d9b3198, 0xbe7669a4, 0x3e6d9559, 0xbe238994, 0xbd6f15a0, 0x3ecbbbb7, 0x3dea562a, 0xbdcd3380, 0xbef6648c, 0xbe05855d, 0xbd10f5eb, 0x3ee80009, 0x3db3b7f8, 0x3de7f23f, 0xbe15d9b3, 0xbe03a005, 0xbdbd7cce, 0x3e17e7f6, 0x3e050054, 0x3dfdf63a, 0x3f0b55cd, 0x3dde99dd, 0xbe93ac48, 0x3d927932, 0xbc006933, 0x3e995281, 0x3e9fa656, 0x3e0838d8, 0xbdb96f3f, 0xbe628743, 0xbe9d09ac, 0xbcc5c04d, 0x3e2b9311, 0x3e544b71, 0xbe0b460d, 0xbeba0990, 0xbe86fe5a, 0x3d86e498, 0x3e4f89b7, 0x3e85155f, 0x3e70834f, 0x3edb8026, 0x3e106b80, 0xbeb7ecce, 0x3e6d4fd1, 0x3dcee4a3, 0x3e2cec70, 0x3e652ac0, 0x3e3d0220, 0x3e802fb4, 0xbe94e2d7, 0xbe1a902e, 0x3dcf41ab, 0xbda36d77, 0xbdd779ec, 0x3d22e8e3, 0xbe17c8d2, 0xbed6b5ab, 0xbd1cefdb, 0x3e7ebc8d, 0x3cb6a703, 0x3dc6f159, 0x3e939f4c, 0x3cc6d6ae, 0xbea4d8c8, 0x3e5d0622, 0xbd23eacd, 0xbda939c9, 0x3e1b1995, 0x3e2f815b, 0xbeac3cd3, 0xbf15d0da, 0xbf03af7c, 0x3bc4a6d9, 0x3e8cf965, 0x3d1a27a2, 0x3eeaaa98, 0xbd7bdc52, 0xbd4fb68e, 0xbe4063ea, 0x3d8d0cc5, 0x3e916e54, 0xbac6376b, 0x3dd4732e, 0x3e7bfcc1, 0xbe81430c, 0x3e77d1b0, 0x3d80743a, 0x3c75e0f7, 0x3dc65b26, 0x3cb872dc, 0x3d429fa2, 0xbe005912, 0xbe103baf, 0x3de03a8c, 0x3e851e20, 0xbe285826, 0x3dbf8d53, 0xbe559c2a, 0xbe5b362e, 0x3d2ee6a4, 0x3e3f6f18, 0x3cc667e5, 0x3be227ae, 0x3d016ffc, 0x3e20fbce, 0xbe9fe558, 0x3e10e7f8, 0x3e4824d5, 0xbda27412, 0x3eb27828, 0x3e755759, 0xbe7c3e18, 0xbf2b8387, 0xbe8a3ca3, 0xbde6d540, 0x3d44254c, 0x3c9c5216, 0xbdf7ec4c, 0xbe3e7179, 0xbe8b1c89, 0xbe2ae027, 0xb94c3ecd, 0x3dee7547, 0xbd6cafec, 0x3e909c65, 0xbe25799b, 0xbe957a87, 0x3dd1f2cf, 0x3d4fffba, 0x3e9ad1f3, 0x3ecf9869, 0x3e851b77, 0xbef21b3c, 0xbf309a66, 0xbe9694e1, 0xbdd16fef, 0x3db6f5d4, 0x3cd36c12, 0x3d88ba04, 0xbe8e4ee1, 0xbeac0437, 0xbde01afc, 0x3ed26389, 0x3dfbaafb, 0x3b38fc61, 0x3e97a1f5, 0x3d6752c6, 0xbf07fb08, 0x3dcd47db, 0xbe56aea5, 0x3e02e71c, 0x3f02f762, 0x3e4dc44e, 0xbd755279, 0xbedfb32f, 0xbe522fa0, 0xbc4d388e, 0x3cecdfd6, 0x3da0a80e, 0x3bbac653, 0xbd82ef3d, 0xbe60044e, 0xbe9ca11d, 0x3e631998, 0x3d3bb59f, 0x3e71dfde, 0x3d2286e5, 0x3e98798d, 0xbf09b153, 0x3d6a9f74, 0x3e11df9c, 0x3e5de0f9, 0x3ea99bb4, 0x3e43c72e, 0xbddb4395, 0xbe69c536, 0xbc0e0570, 0x3ea5b6ca, 0xbcf35b4f, 0xbb791864, 0xbe413177, 0xbea6b9f5, 0xbddddcef, 0xbd76b1a3, 0xbc547e22, 0x3e4ee61d, 0xbe2bf763, 0x3de683ed, 0x3dbff523, 0xbe3847ed, 0x3e775bb5, 0xbd0b4a08, 0x3e59e88a, 0x3e26091d, 0xbdebc80d, 0x3dae7906, 0xbe19f53b, 0xbd8380c1, 0xbc766243, 0x3d2245bc, 0x3c994d8d, 0x3e4c9d2a, 0x3e0e9a3a, 0xbe13408d, 0x3da080bc, 0x3b439034, 0x3d52f123, 0x3dbe7f95, 0x3eeebcbb, 0x3ea507c6, 0xbed81e08, 0x3e9538e6, 0x3d3f8f59, 0x3e91f5d3, 0x3e9249cf, 0x3e83c73c, 0x3de597cb, 0xbee560c4, 0xbe1e8918, 0x3ca144b6, 0x3d726a89, 0x3d846794, 0x3dd78c67, 0xbea7732f, 0xbe7bde9e, 0xbe6706c7, 0xbdf711c2, 0x3e4bd329, 0x3d2304df, 0x3eabc3f0, 0x3d45e53a, 0xbedcc3e9, 0x3e8446f9, 0xbe3fd995, 0x3e547af2, 0x3f0aa842, 0x3ec9a325, 0xbed2a254, 0xbf0f6b26, 0xbde25b3f, 0x3dc8c105, 0x3d8ec9d0, 0x3d7fd7a1, 0x3e610f6a, 0xbdea6665, 0xbead5c1f, 0xbe80e77d, 0x3e489cb7, 0x3ec65a7c, 0x3e4ffac6, 0x3d55f9a6, 0x3e9ea98b, 0xbf0e625e, 0xbc8bde61, 0x3dd68ecb, 0x3bc64cbd, 0x3e86a09b, 0x3d554cb4, 0xbeccd628, 0xbf035dfc, 0xbe6c27ea, 0x3d4483cf, 0x3e223af9, 0xbe20cbee, 0x3dd718e7, 0xbe8fad2f, 0xbe938918, 0xbeb29804, 0x3e9142f0, 0x3de3e136, 0x3e9a39ce, 0x3efa0610, 0x3d9406ea, 0xbee24e0f, 0x3e38404b, 0xbe3ef7ee, 0xbc59ad65, 0x3e5f9e81, 0x3e23b360, 0xbea0121f, 0xbf0bfbbc, 0xbec79dfc, 0xbd7102a6, 0x3eb5585c, 0x3dca0b72, 0x3cb1a8b7, 0xbe1a22e0, 0xbe477474, 0xbe2e323b, 0x3e06e740, 0x3e6ec883, 0xbd822e0f, 0x3e84a3f8, 0x3dbc54c1, 0xbe2a66fe, 0x3e5fe31b, 0x3d6cdf21, 0x3eed45e5, 0x3e49ef86, 0x3e042067, 0xbd2b9ef1, 0x3d8982d5, 0x3cd070fb, 0x3ededc87, 0x3e0a8bfa, 0xbb858c8b, 0x3d04acd8, 0xbe08ce60, 0xbe30cc81, 0x3d582e3d, 0x3db17c5b, }; // 4,5,3,7 uint32_t output_relu_exp_vals[] = { 0x3e800009, 0x3e5cc2bb, 0x3dd8b7fc, 0x0, 0x0, 0x3db2113b, 0x3c2e3283, 0x0, 0x3e190482, 0x3e964a40, 0x0, 0x0, 0x3dbd218d, 0x0, 0x3c353168, 0x3dadf9bd, 0x0, 0x0, 0x0, 0x0, 0x3e89892d, 0x3e25c7d0, 0x3e9b0553, 0x3e39f0f1, 0x3eca599b, 0x0, 0x3ea822df, 0x0, 0x3e6d580b, 0x3e9794f4, 0x3dde4c3a, 0x3d8b0621, 0x0, 0x3dfc1fe5, 0x3e49eed5, 0x3e5ebc15, 0x3d19c5a0, 0x3d8d4f3d, 0x0, 0x0, 0x0, 0x3ea8e7bd, 0x3d4c47a1, 0x0, 0x3e1d24d0, 0x0, 0x0, 0x3e88acad, 0x0, 0x0, 0x3ea61d80, 0x3ed57081, 0x0, 0x0, 0x0, 0x3d948c77, 0x0, 0x0, 0x3d694f50, 0x3d618060, 0x0, 0x0, 0x3ec9335e, 0x3d69cdbb, 0x3d960288, 0x3edc27a8, 0x3e078210, 0x0, 0x3ddc602d, 0x0, 0x3db7ea35, 0x3e592130, 0x3e2a8154, 0x0, 0x0, 0x0, 0x3daf312c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e436c58, 0x3da03a17, 0x0, 0x3e86bb89, 0x0, 0x3e1ccc14, 0x0, 0x3e75ece0, 0x3e21a281, 0x3e9e283c, 0x0, 0x0, 0x0, 0x3e958b70, 0x3dd38536, 0x3d36528a, 0x0, 0x0, 0x0, 0x0, 0x3e596745, 0x3e6acaab, 0x3e0c2af5, 0x3ec92511, 0x3d9b3198, 0x0, 0x3e6d9559, 0x0, 0x0, 0x3ecbbbb7, 0x3dea562a, 0x0, 0x0, 0x0, 0x0, 0x3ee80009, 0x3db3b7f8, 0x3de7f23f, 0x0, 0x0, 0x0, 0x3e17e7f6, 0x3e050054, 0x3dfdf63a, 0x3f0b55cd, 0x3dde99dd, 0x0, 0x3d927932, 0x0, 0x3e995281, 0x3e9fa656, 0x3e0838d8, 0x0, 0x0, 0x0, 0x0, 0x3e2b9311, 0x3e544b71, 0x0, 0x0, 0x0, 0x3d86e498, 0x3e4f89b7, 0x3e85155f, 0x3e70834f, 0x3edb8026, 0x3e106b80, 0x0, 0x3e6d4fd1, 0x3dcee4a3, 0x3e2cec70, 0x3e652ac0, 0x3e3d0220, 0x3e802fb4, 0x0, 0x0, 0x3dcf41ab, 0x0, 0x0, 0x3d22e8e3, 0x0, 0x0, 0x0, 0x3e7ebc8d, 0x3cb6a703, 0x3dc6f159, 0x3e939f4c, 0x3cc6d6ae, 0x0, 0x3e5d0622, 0x0, 0x0, 0x3e1b1995, 0x3e2f815b, 0x0, 0x0, 0x0, 0x3bc4a6d9, 0x3e8cf965, 0x3d1a27a2, 0x3eeaaa98, 0x0, 0x0, 0x0, 0x3d8d0cc5, 0x3e916e54, 0x0, 0x3dd4732e, 0x3e7bfcc1, 0x0, 0x3e77d1b0, 0x3d80743a, 0x3c75e0f7, 0x3dc65b26, 0x3cb872dc, 0x3d429fa2, 0x0, 0x0, 0x3de03a8c, 0x3e851e20, 0x0, 0x3dbf8d53, 0x0, 0x0, 0x3d2ee6a4, 0x3e3f6f18, 0x3cc667e5, 0x3be227ae, 0x3d016ffc, 0x3e20fbce, 0x0, 0x3e10e7f8, 0x3e4824d5, 0x0, 0x3eb27828, 0x3e755759, 0x0, 0x0, 0x0, 0x0, 0x3d44254c, 0x3c9c5216, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3dee7547, 0x0, 0x3e909c65, 0x0, 0x0, 0x3dd1f2cf, 0x3d4fffba, 0x3e9ad1f3, 0x3ecf9869, 0x3e851b77, 0x0, 0x0, 0x0, 0x0, 0x3db6f5d4, 0x3cd36c12, 0x3d88ba04, 0x0, 0x0, 0x0, 0x3ed26389, 0x3dfbaafb, 0x3b38fc61, 0x3e97a1f5, 0x3d6752c6, 0x0, 0x3dcd47db, 0x0, 0x3e02e71c, 0x3f02f762, 0x3e4dc44e, 0x0, 0x0, 0x0, 0x0, 0x3cecdfd6, 0x3da0a80e, 0x3bbac653, 0x0, 0x0, 0x0, 0x3e631998, 0x3d3bb59f, 0x3e71dfde, 0x3d2286e5, 0x3e98798d, 0x0, 0x3d6a9f74, 0x3e11df9c, 0x3e5de0f9, 0x3ea99bb4, 0x3e43c72e, 0x0, 0x0, 0x0, 0x3ea5b6ca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e4ee61d, 0x0, 0x3de683ed, 0x3dbff523, 0x0, 0x3e775bb5, 0x0, 0x3e59e88a, 0x3e26091d, 0x0, 0x3dae7906, 0x0, 0x0, 0x0, 0x3d2245bc, 0x3c994d8d, 0x3e4c9d2a, 0x3e0e9a3a, 0x0, 0x3da080bc, 0x3b439034, 0x3d52f123, 0x3dbe7f95, 0x3eeebcbb, 0x3ea507c6, 0x0, 0x3e9538e6, 0x3d3f8f59, 0x3e91f5d3, 0x3e9249cf, 0x3e83c73c, 0x3de597cb, 0x0, 0x0, 0x3ca144b6, 0x3d726a89, 0x3d846794, 0x3dd78c67, 0x0, 0x0, 0x0, 0x0, 0x3e4bd329, 0x3d2304df, 0x3eabc3f0, 0x3d45e53a, 0x0, 0x3e8446f9, 0x0, 0x3e547af2, 0x3f0aa842, 0x3ec9a325, 0x0, 0x0, 0x0, 0x3dc8c105, 0x3d8ec9d0, 0x3d7fd7a1, 0x3e610f6a, 0x0, 0x0, 0x0, 0x3e489cb7, 0x3ec65a7c, 0x3e4ffac6, 0x3d55f9a6, 0x3e9ea98b, 0x0, 0x0, 0x3dd68ecb, 0x3bc64cbd, 0x3e86a09b, 0x3d554cb4, 0x0, 0x0, 0x0, 0x3d4483cf, 0x3e223af9, 0x0, 0x3dd718e7, 0x0, 0x0, 0x0, 0x3e9142f0, 0x3de3e136, 0x3e9a39ce, 0x3efa0610, 0x3d9406ea, 0x0, 0x3e38404b, 0x0, 0x0, 0x3e5f9e81, 0x3e23b360, 0x0, 0x0, 0x0, 0x0, 0x3eb5585c, 0x3dca0b72, 0x3cb1a8b7, 0x0, 0x0, 0x0, 0x3e06e740, 0x3e6ec883, 0x0, 0x3e84a3f8, 0x3dbc54c1, 0x0, 0x3e5fe31b, 0x3d6cdf21, 0x3eed45e5, 0x3e49ef86, 0x3e042067, 0x0, 0x3d8982d5, 0x3cd070fb, 0x3ededc87, 0x3e0a8bfa, 0x0, 0x3d04acd8, 0x0, 0x0, 0x3d582e3d, 0x3db17c5b, }; test_conv2d(set, strides, input_vals, kernel_vals, bias_vals, output_exp_vals, output_relu_exp_vals, SAME_PADDING, NULL); } // wrong padding type = response code F000 void test_f000_fail() { input_set i = {1, 1, 1, 1, {1, 1}, 1}; input_set *set = &i; // just so we can copy and paste code strides_input_set s = {1, 1}; strides_input_set *strides = &s; zdnn_status status; zdnn_pool_padding padding = 0xFF; uint32_t input_dims[4] = {set->n, set->height_in, set->width_in, set->channel_in}; uint32_t kernel_dims[4] = {set->kernel_size[0], set->kernel_size[1], set->channel_in, set->channel_out}; uint32_t bias_dims[1] = {set->channel_out}; uint32_t output_dims[4] = {set->n, 1, 1, set->channel_out}; zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values( kernel_dims, ZDNN_HWCK, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values( bias_dims, ZDNN_1D, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, CONV2D_ACT_NONE, NULL, output_ztensor); TEST_ASSERT_MESSAGE(status == ZDNN_FUNC_RC_F000, "zdnn_conv2d(): status not ZDNN_FUNC_RC_F000"); } // wrong activation function = response code F001 void test_f001_fail() { input_set i = {1, 1, 1, 1, {1, 1}, 1}; input_set *set = &i; // just so we can copy and paste code strides_input_set s = {1, 1}; strides_input_set *strides = &s; zdnn_status status; zdnn_pool_padding padding = VALID_PADDING; uint32_t input_dims[4] = {set->n, set->height_in, set->width_in, set->channel_in}; uint32_t kernel_dims[4] = {set->kernel_size[0], set->kernel_size[1], set->channel_in, set->channel_out}; uint32_t bias_dims[1] = {set->channel_out}; uint32_t output_dims[4] = {set->n, 1, 1, set->channel_out}; zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values( kernel_dims, ZDNN_HWCK, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values( bias_dims, ZDNN_1D, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, 0xFF, NULL, output_ztensor); TEST_ASSERT_MESSAGE(status == ZDNN_FUNC_RC_F001, "zdnn_conv2d(): status not ZDNN_FUNC_RC_F001"); } // both strides = 0, kernel height > 448 void test_f002_height_fail() { input_set i = {1, 1, 1, 1, {512, 1}, 1}; input_set *set = &i; // just so we can copy and paste code strides_input_set s = {0, 0}; strides_input_set *strides = &s; zdnn_status status; zdnn_pool_padding padding = VALID_PADDING; uint32_t input_dims[4] = {set->n, set->kernel_size[0], set->kernel_size[1], set->channel_in}; uint32_t kernel_dims[4] = {set->kernel_size[0], set->kernel_size[1], set->channel_in, set->channel_out}; uint32_t bias_dims[1] = {set->channel_out}; uint32_t output_dims[4] = {set->n, 1, 1, set->channel_out}; zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values( kernel_dims, ZDNN_HWCK, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values( bias_dims, ZDNN_1D, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, CONV2D_ACT_NONE, NULL, output_ztensor); TEST_ASSERT_MESSAGE(status == ZDNN_FUNC_RC_F002, "zdnn_conv2d(): status not ZDNN_FUNC_RC_F002"); } // both strides = 0, kernel width > 448 void test_f002_width_fail() { input_set i = {1, 1, 1, 1, {1, 512}, 1}; input_set *set = &i; // just so we can copy and paste code strides_input_set s = {0, 0}; strides_input_set *strides = &s; zdnn_status status; zdnn_pool_padding padding = VALID_PADDING; uint32_t input_dims[4] = {set->n, set->kernel_size[0], set->kernel_size[1], set->channel_in}; uint32_t kernel_dims[4] = {set->kernel_size[0], set->kernel_size[1], set->channel_in, set->channel_out}; uint32_t bias_dims[1] = {set->channel_out}; uint32_t output_dims[4] = {set->n, 1, 1, set->channel_out}; zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values( kernel_dims, ZDNN_HWCK, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values( bias_dims, ZDNN_1D, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, CONV2D_ACT_NONE, NULL, output_ztensor); TEST_ASSERT_MESSAGE(status == ZDNN_FUNC_RC_F002, "zdnn_conv2d(): status not ZDNN_FUNC_RC_F002"); } // both strides > 0, kernel height > 64 void test_f003_height_fail() { uint32_t bad_height = 70; // output height becomes 11 // height_in must > kernel_height input_set i = {1, bad_height + 10, 1, 1, {bad_height, 1}, 1}; input_set *set = &i; // just so we can copy and paste code strides_input_set s = {1, 1}; strides_input_set *strides = &s; zdnn_status status; zdnn_pool_padding padding = VALID_PADDING; uint32_t input_dims[4] = {set->n, set->height_in, set->width_in, set->channel_in}; uint32_t kernel_dims[4] = {set->kernel_size[0], set->kernel_size[1], set->channel_in, set->channel_out}; uint32_t bias_dims[1] = {set->channel_out}; uint32_t output_dims[4] = {set->n, 11, 1, set->channel_out}; // zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values( kernel_dims, ZDNN_HWCK, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values( bias_dims, ZDNN_1D, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, CONV2D_ACT_NONE, NULL, output_ztensor); TEST_ASSERT_MESSAGE(status == ZDNN_FUNC_RC_F003, "zdnn_conv2d(): status not ZDNN_FUNC_RC_F003"); } // both strides > 0, kernel width > 64 void test_f003_width_fail() { uint32_t bad_width = 70; // output width becomes 11 // width_in must > kernel_width input_set i = {1, 1, bad_width + 10, 1, {1, bad_width}, 1}; input_set *set = &i; // just so we can copy and paste code strides_input_set s = {1, 1}; strides_input_set *strides = &s; zdnn_status status; zdnn_pool_padding padding = VALID_PADDING; uint32_t input_dims[4] = {set->n, set->height_in, set->width_in, set->channel_in}; uint32_t kernel_dims[4] = {set->kernel_size[0], set->kernel_size[1], set->channel_in, set->channel_out}; uint32_t bias_dims[1] = {set->channel_out}; uint32_t output_dims[4] = {set->n, 1, 11, set->channel_out}; zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values( kernel_dims, ZDNN_HWCK, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values( bias_dims, ZDNN_1D, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, CONV2D_ACT_NONE, NULL, output_ztensor); TEST_ASSERT_MESSAGE(status == ZDNN_FUNC_RC_F003, "zdnn_conv2d(): status not ZDNN_FUNC_RC_F003"); } // stride height > 13 void test_f004_stride_height_fail() { uint32_t bad_stride_height = 15; input_set i = {1, 2, 2, 1, {1, 1}, 1}; input_set *set = &i; // just so we can copy and paste code strides_input_set s = {bad_stride_height, 1}; strides_input_set *strides = &s; zdnn_status status; zdnn_pool_padding padding = VALID_PADDING; uint32_t input_dims[4] = {set->n, set->height_in, set->width_in, set->channel_in}; uint32_t kernel_dims[4] = {set->kernel_size[0], set->kernel_size[1], set->channel_in, set->channel_out}; uint32_t bias_dims[1] = {set->channel_out}; uint32_t output_dims[4] = {set->n, 1, 2, set->channel_out}; zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values( kernel_dims, ZDNN_HWCK, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values( bias_dims, ZDNN_1D, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, CONV2D_ACT_NONE, NULL, output_ztensor); TEST_ASSERT_MESSAGE(status == ZDNN_FUNC_RC_F004, "zdnn_conv2d(): status not ZDNN_FUNC_RC_F004"); } // stride width > 13 void test_f004_stride_width_fail() { uint32_t bad_stride_width = 15; input_set i = {1, 2, 2, 1, {1, 1}, 1}; input_set *set = &i; // just so we can copy and paste code strides_input_set s = {1, bad_stride_width}; strides_input_set *strides = &s; zdnn_status status; zdnn_pool_padding padding = VALID_PADDING; uint32_t input_dims[4] = {set->n, set->height_in, set->width_in, set->channel_in}; uint32_t kernel_dims[4] = {set->kernel_size[0], set->kernel_size[1], set->channel_in, set->channel_out}; uint32_t bias_dims[1] = {set->channel_out}; uint32_t output_dims[4] = {set->n, 2, 1, set->channel_out}; zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *kernel_ztensor = alloc_ztensor_with_values( kernel_dims, ZDNN_HWCK, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *bias_ztensor = alloc_ztensor_with_values( bias_dims, ZDNN_1D, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_dims, ZDNN_NHWC, test_datatype, NO_CONCAT, true, ZERO_ARRAY); status = zdnn_conv2d(input_ztensor, kernel_ztensor, bias_ztensor, padding, strides->height, strides->width, CONV2D_ACT_NONE, NULL, output_ztensor); TEST_ASSERT_MESSAGE(status == ZDNN_FUNC_RC_F004, "zdnn_conv2d(): status not ZDNN_FUNC_RC_F004"); } int main() { UNITY_BEGIN(); #ifdef TEST_AIU RUN_TEST_ALL_DATATYPES(test_valid_padding_non_zero_strides_small); RUN_TEST_ALL_DATATYPES(test_valid_padding_non_zero_strides_small_with_clip); RUN_TEST_ALL_DATATYPES(test_valid_padding_zero_strides_small); RUN_TEST_ALL_DATATYPES(test_same_padding_non_zero_strides_small); RUN_TEST_ALL_DATATYPES(test_valid_padding_non_zero_strides_medium); RUN_TEST_ALL_DATATYPES(test_valid_padding_zero_strides_medium); RUN_TEST_ALL_DATATYPES(test_valid_padding_zero_strides_medium_with_clip); RUN_TEST_ALL_DATATYPES(test_same_padding_non_zero_strides_medium); RUN_TEST_ALL_DATATYPES(test_valid_padding_non_zero_strides_large); RUN_TEST_ALL_DATATYPES(test_valid_padding_zero_strides_large); RUN_TEST_ALL_DATATYPES(test_same_padding_non_zero_strides_large); RUN_TEST_ALL_DATATYPES(test_f000_fail); RUN_TEST_ALL_DATATYPES(test_f001_fail); RUN_TEST_ALL_DATATYPES(test_f002_height_fail); RUN_TEST_ALL_DATATYPES(test_f002_width_fail); RUN_TEST_ALL_DATATYPES(test_f003_height_fail); RUN_TEST_ALL_DATATYPES(test_f003_width_fail); RUN_TEST_ALL_DATATYPES(test_f004_stride_height_fail); RUN_TEST_ALL_DATATYPES(test_f004_stride_width_fail); #endif return UNITY_END(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_div_elwise.c�������������������������������������������������������0000664�0000000�0000000�00000012325�14364043643�0021240�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_elwise.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} /* * Simple test to drive a full div api. Input tensor 1 has values greater than * those in input tensor 2. */ void api_div_basic() { /* Input 1 values as true NHWC sized (1,2,2,2) [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {1, 2, 2, 2}; float input1_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Input 2 values as true NHWC sized (1,2,2,2) [[ [[1, 15], [3, 12]], [[4, 40], [4.5, 45]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 15, 3, 12, 4, 40, 4.5, 15}; /* Expected values as true NHWC sized (1,2,2,2) [[ [[3, 2], [2, 5]], [[2, 2], [2, 6]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_DIV, ZDNN_OK); } // test to drive input tensors with 280 values in their buffer. All randomly // generated numbers in first input tensor will be greater than or equal to // those in the second input tensor to avoid negatives in the output tensor void api_div_med_dims() { uint32_t shape[] = {1, 7, 10, 4}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_DIV, ZDNN_OK); } // test to drive input tensors with 6825 values in their buffer void api_div_high_dims() { uint32_t shape[] = {1, 3, 33, 65}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_DIV, ZDNN_OK); } /* * Simple test to drive a full div api using the data type and * 3D layout */ void api_div_3D() { /* Input 1 values as true NHWC sized (1,2,2,2) [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2, 2}; float input1_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Input 2 values as true NHWC sized (1,2,2,2) [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 5, 2, 20, 4, 40, 5, 50}; /* Expected values as true NHWC sized (1,2,2,2) [[ [[3, 150], [12, 1200]], [[32, 3200], [45, 1400]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_3D, input1_values, input2_values, NNPA_DIV, ZDNN_OK); } /* * Simple test to drive a full div api using the data type * and 2 dimensional tensors */ void api_div_2D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[1, 10], [2, 20]] ]] */ float input1_values[] = {1, 10, 2, 20}; /* Input 2 values as true NHWC sized (1,1,2,2) [[ [[3, 20], [2, 5]] ]] */ float input2_values[] = {3, 20, 2, 5}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[0.33333333, 0.5], [1, 4]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_2D, input1_values, input2_values, NNPA_DIV, ZDNN_OK); } /* * Simple test to drive a full div api using the data type * and 1 dimensional tensors */ void api_div_1D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[10000, 12000]] ]] */ float input1_values[] = {10000, 12000}; /* Input 2 values as true NHWC sized (1,1,2,2) [[ [[2.5, 4000]] ]] */ float input2_values[] = {2.5, 4000}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[4000, 3]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_1D, input1_values, input2_values, NNPA_DIV, ZDNN_OK); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(api_div_basic); RUN_TEST_ALL_DATATYPES(api_div_med_dims); RUN_TEST_ALL_DATATYPES(api_div_high_dims); RUN_TEST_ALL_DATATYPES(api_div_3D); RUN_TEST_ALL_DATATYPES(api_div_2D); RUN_TEST_ALL_DATATYPES(api_div_1D); return UNITY_END(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_exp_elwise.c�������������������������������������������������������0000664�0000000�0000000�00000010313�14364043643�0021245�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_elwise.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } /********************************************************** * FP16 tops out at 65504, so no input number larger than * 11.089866488461016 should be used **********************************************************/ void tearDown(void) {} /* * Simple test to drive a full exp api. */ void api_exp_basic() { /* Input values as true NHWC sized (1,2,2,2) [[ [[3, 4], [6, 7]], [[10, 12], [3, 10]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {1, 2, 2, 2}; float input_values[] = {3, 4, 6, 7, 10, 9, 3, 10}; /* Expected values as true NHWC sized (1,2,2,2) [[ [[20.085536923, 54.598150033], [403.42879349, 1096.6331584]], [[22026.465794, 8103.083926], [20.085536923, 22026.465794]] ]] */ test_elwise_api_1_input(shape, ZDNN_NHWC, input_values, NNPA_EXP, ZDNN_OK); } // test to drive input tensors with 280 values in their buffer. void api_exp_med_dims() { uint32_t shape[] = {1, 7, 10, 4}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input_values); test_elwise_api_1_input(shape, ZDNN_NHWC, input_values, NNPA_EXP, ZDNN_OK); } // test to drive an input tensor with 6825 values in its buffer void api_exp_high_dims() { uint32_t shape[] = {1, 3, 33, 65}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input_values); test_elwise_api_1_input(shape, ZDNN_NHWC, input_values, NNPA_EXP, ZDNN_OK); } /* * Simple test to drive a full exp api using the data type * and 3D layout */ void api_exp_3D() { /* Input values as true NHWC sized (1,2,2,2) [[ [[3, 4], [6, 7]], [[10, 8], [3, 10]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2, 2}; float input_values[] = {3, 4, 6, 7, 10, 5, 3, 10}; /* Expected values as true NHWC sized (1,2,2,2) [[ [[20.085536923, 54.598150033], [403.42879349, 1096.6331584]], [[22026.465794, 148.41315910], [20.085536923, 22026.465794]] ]] */ test_elwise_api_1_input(shape, ZDNN_3D, input_values, NNPA_EXP, ZDNN_OK); } /* * Simple test to drive a full exp api using the data type * and 2 dimensional tensors */ void api_exp_2D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[1, 10], [2, 6]] ]] */ float input_values[] = {1, 10, 2, 6}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[2.718281828, 22026.465794807], [7.3890560989, 403.42879349]] ]] */ test_elwise_api_1_input(shape, ZDNN_2D, input_values, NNPA_EXP, ZDNN_OK); } /* * Simple test to drive a full exp api using the data type * and 1 dimensional tensors */ void api_exp_1D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[6, 7]] ]] */ float input_values[] = {6, 7}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[403.42879349, 1096.6331584]] ]] */ test_elwise_api_1_input(shape, ZDNN_1D, input_values, NNPA_EXP, ZDNN_OK); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(api_exp_basic); RUN_TEST_ALL_DATATYPES(api_exp_med_dims); RUN_TEST_ALL_DATATYPES(api_exp_high_dims); RUN_TEST_ALL_DATATYPES(api_exp_3D); RUN_TEST_ALL_DATATYPES(api_exp_2D); RUN_TEST_ALL_DATATYPES(api_exp_1D); return UNITY_END(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_gru_dual_layers.c��������������������������������������������������0000664�0000000�0000000�00000141241�14364043643�0022267�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } zdnn_ztensor *test_layer(zdnn_ztensor *input, uint32_t *h0_shape, void *h0_values, uint32_t *weights_shape, void *weights_values, uint32_t *biases_shape, void *biases_values, uint32_t *hidden_weights_shape, void *hidden_weights_values, uint32_t *hidden_biases_shape, void *hidden_biases_values, uint32_t *all_ts_out_shape, void *all_ts_out_exp_values, bool is_prev_layer_bidir, bool is_this_layer_bidir) { zdnn_ztensor *h0, *weights, *biases, *hidden_weights, *hidden_biases, *all_ts_out; h0 = alloc_ztensor_with_values(h0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (float *)h0_values); // FICO/ZRH elements coming in as one pointer instead of four or three // pointers uint32_t num_elements_weights = weights_shape[0] * weights_shape[1] * weights_shape[2]; weights = alloc_ztensor_with_values( weights_shape, ZDNN_3DS, test_datatype, RNN_TYPE_GRU | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI) | USAGE_WEIGHTS, false, (float *)weights_values, (float *)weights_values + num_elements_weights, (float *)weights_values + 2 * num_elements_weights); uint32_t num_elements_biases = biases_shape[0] * biases_shape[1]; biases = alloc_ztensor_with_values( biases_shape, ZDNN_2DS, test_datatype, RNN_TYPE_GRU | USAGE_BIASES, false, (float *)biases_values, (float *)biases_values + num_elements_biases, (float *)biases_values + 2 * num_elements_biases); uint32_t num_elements_hidden_weights = hidden_weights_shape[0] * hidden_weights_shape[1] * hidden_weights_shape[2]; hidden_weights = alloc_ztensor_with_values( hidden_weights_shape, ZDNN_3DS, test_datatype, RNN_TYPE_GRU | USAGE_HIDDEN_WEIGHTS, false, (float *)hidden_weights_values, (float *)hidden_weights_values + num_elements_hidden_weights, (float *)hidden_weights_values + 2 * num_elements_hidden_weights); uint32_t num_elements_hidden_biases = hidden_biases_shape[0] * hidden_biases_shape[1]; hidden_biases = alloc_ztensor_with_values( hidden_biases_shape, ZDNN_2DS, test_datatype, RNN_TYPE_GRU | USAGE_HIDDEN_BIASES, false, (float *)hidden_biases_values, (float *)hidden_biases_values + num_elements_hidden_biases, (float *)hidden_biases_values + 2 * num_elements_hidden_biases); all_ts_out = alloc_ztensor_with_values( all_ts_out_shape, ZDNN_4DS, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_status status = zdnn_gru(input, h0, weights, biases, hidden_weights, hidden_biases, is_this_layer_bidir ? BIDIR : FWD, NULL, all_ts_out); if (status != ZDNN_OK) { TEST_FAIL_MESSAGE_FORMATTED("%s() - zdnn_gru() not ZDNN_OK, status = %08x", __func__, status); } assert_ztensor_values(all_ts_out, false, all_ts_out_exp_values); free_ztensor_buffers(5, h0, weights, biases, hidden_weights, hidden_biases); return all_ts_out; } void gru_fwd_to_fwd() { // num_timesteps = 5 // num_batches = 2 // num_features = 4 // num_hidden = 4, 5 bool is_layer_bidir[] = {false, false}; // first layer uint32_t input0_shape[] = {5, 2, 4}; uint32_t input0_values[] = { 0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a, 0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e, 0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0, 0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48, 0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8, 0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b, 0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80}; uint32_t h00_shape[] = {1, 2, 4}; uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f, 0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4}; uint32_t weights0_shape[] = {1, 4, 4}; uint32_t weights0_values[] = { 0x3e8c896e, 0x3e9ed100, 0x3e493898, 0x3dcbca78, 0xbd813f20, 0x3ef5cf48, 0x3ed41bd0, 0xbede9cf8, 0x3c9c6440, 0xbec54796, 0x3edec5e8, 0x3d3c6690, 0x3ded4400, 0xbe3ba1ec, 0x3ee1e222, 0xbea027ac, 0xbe6311c8, 0x3e4b3424, 0x3dbed0f8, 0x3e67aa8c, 0xbc93cb20, 0x3d8a55c8, 0xbec67a6c, 0x3e4de7f8, 0x3ea3ba40, 0x3eaba4fe, 0xbeb16e18, 0xbe97a46a, 0x3efe7f82, 0xbe96bbc0, 0xbe843ed2, 0x3e1aadc8, 0xbeee948c, 0x3dbfaa08, 0x3e44e48c, 0x3eb7435c, 0x3ee3743e, 0xbdac80c8, 0xbe97a134, 0x3e3f7148, 0x3ec2a6f0, 0xbda882b8, 0x3e3bb1dc, 0xbefd5f4a, 0xbeff5dfe, 0xbe6a5f1c, 0x3e817616, 0xbea61100}; uint32_t biases0_shape[] = {1, 4}; uint32_t biases0_values[] = {0xbe7e7cdc, 0xbec42d02, 0xbeef9400, 0xbed810ec, 0xbee5f866, 0xbe72ba40, 0x3eae4fce, 0xbb546b00, 0xbdcfb470, 0x3e8c6456, 0x3e8a6774, 0xbef6e502}; uint32_t hidden_weights0_shape[] = {1, 4, 4}; uint32_t hidden_weights0_values[] = { 0xbe9bc938, 0xbdfedb88, 0x3e48ec5c, 0xbef59156, 0x3ee84968, 0x3cb8d280, 0x3cf559e0, 0xbe97bba0, 0x3eaf6fd0, 0x3d956718, 0xbe79d1cc, 0xbe002b3c, 0xbed7e164, 0x3df2ddd0, 0x3e7245d4, 0xbe7966ec, 0x3e7fa638, 0x3ef0d4f2, 0xbef3dd78, 0xbce1b020, 0x3dd65318, 0x3eac7f54, 0xbc133e80, 0x3d99bfa0, 0xbec7b396, 0xbe5f3eb0, 0xbec0c878, 0xbe51adf4, 0xbe9368e8, 0xbe00dcd4, 0xbec577a2, 0x3e97e798, 0xbe331d5c, 0xbea6c676, 0x3c63ac80, 0x3ef27eba, 0xbed1d2ba, 0xbcd23440, 0xbd30adc0, 0x3ea29306, 0xbdd9d200, 0x3eb74200, 0x3dcf3d10, 0x3ef30cc4, 0x3ddae2f8, 0xbd5288f0, 0x3ea2c660, 0xbd141d60}; uint32_t hidden_biases0_shape[] = {1, 4}; uint32_t hidden_biases0_values[] = { 0xbdc53cf0, 0xbdc90e10, 0xbee5b8ba, 0xbedd0a44, 0x3e9fb02e, 0xbec8528a, 0xbdd87bf0, 0xbe4f9a1c, 0xbda03c28, 0x3bd3e180, 0xbe6896b8, 0x3e40deb8}; uint32_t all_ts_out0_shape[] = {5, 1, 2, 4}; uint32_t all_ts_out0_exp_values[] = { 0x3dbbe338, 0x3e91c6be, 0x3f53d36d, 0xbee51fe8, 0x3f248241, 0x3f14fbd0, 0x3ed3b798, 0x3ed452e7, 0xbdfe4e88, 0x3e12cda1, 0x3f3e34b7, 0xbf103a51, 0x3e33cc72, 0x3e93fd0d, 0x3ee42df8, 0x3d790f32, 0xbe6f1ec6, 0x3c36a710, 0x3f380cab, 0xbf4b6960, 0x3ce736e8, 0x3e6fd98a, 0x3ef5e203, 0xbedb0b88, 0xbedb1a27, 0xbc8798ec, 0x3f1fe987, 0xbecfbd8c, 0x3cd23b72, 0x3e817b76, 0x3edf4e9e, 0xbe603530, 0xbeee1f9e, 0xbda1fc72, 0x3f24978b, 0xbf2e6ce5, 0xbe8638b3, 0x3e90d126, 0x3f01ed5f, 0xbdfc585c}; zdnn_ztensor *input0 = alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (void *)input0_values); zdnn_ztensor *all_ts_out0 = test_layer( input0, h00_shape, (void *)h00_values, weights0_shape, (void *)weights0_values, biases0_shape, (void *)biases0_values, hidden_weights0_shape, (void *)hidden_weights0_values, hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape, (void *)all_ts_out0_exp_values, false, is_layer_bidir[0]); // second layer uint32_t h01_shape[] = {1, 2, 5}; uint32_t h01_values[] = {0x3ff3351d, 0x3f88a36c, 0x3df6f2f0, 0x3fb435ce, 0x3dc6a650, 0x3f2349e4, 0x3ff383d7, 0x3ebc0f18, 0x3f8ec53f, 0x3fb923dc}; uint32_t weights1_shape[] = {1, 4, 5}; uint32_t weights1_values[] = { 0xbe8872c0, 0xbead15e7, 0xbe249da6, 0xbb5a2c80, 0xbb4def80, 0xbc1fdba0, 0xbe9d3169, 0x3ec122ee, 0xbdb50e24, 0x3d69b920, 0x3c9a1ea0, 0xbe84f4be, 0x3e2598d4, 0x3d65d3e0, 0xbeb31aa8, 0x3e9399fc, 0x3ea04420, 0x3d67f3b0, 0xbdd123b0, 0xbe700636, 0x3eb7196c, 0x3ea38344, 0xbddc3fcc, 0x3eb5ccc2, 0xbea16940, 0xbeb90843, 0x3dffaaa8, 0xbdc09e0c, 0x3e9cab54, 0xbe7c17a9, 0x3d448f50, 0x3e5c0bbc, 0xbebcb154, 0xbea1834a, 0xbe856c8e, 0xbdbfc268, 0x3e21ba5c, 0x3e7822c0, 0x3ca36520, 0x3e1c8044, 0x3eb8e4f2, 0x3e256d64, 0xbea317e4, 0x3ba04b00, 0x3e8c10dc, 0xbeb9d294, 0x3c4f7420, 0xbe01fea6, 0x3ebcdbe4, 0xbe90c29a, 0xbd0388a0, 0xbec66e3b, 0xbe19a60a, 0x3d64ada0, 0x3e4d6418, 0x3ee28262, 0x3e62db50, 0xbd87a1dc, 0x3ecd16fc, 0xbea1dc41}; uint32_t biases1_shape[] = {1, 5}; uint32_t biases1_values[] = {0x3e3d5c4c, 0x3d0f9250, 0x3d190310, 0x3d64ba10, 0xbeb401c3, 0xbe271822, 0x3e2dd3f4, 0x3e987cda, 0xbe6f1e1b, 0x3b9084c0, 0x3d0ff4f8, 0x3e9e8ea0, 0x3ece54c0, 0x3e86944e, 0x3d757710}; uint32_t hidden_weights1_shape[] = {1, 5, 5}; uint32_t hidden_weights1_values[] = { 0x3eafbdf8, 0x3ebc395c, 0x3dc5e080, 0xbd506310, 0x3eb682ba, 0x3e261b9c, 0x3df90638, 0xbe807ef0, 0x3e0332e4, 0x3d952498, 0xbe18ef8e, 0xbe58ace5, 0xbecc25a9, 0x3c696e40, 0x3ebdf640, 0xbdfff1d8, 0xbe574539, 0x3ec8c806, 0xbe9a126e, 0xbe1985b8, 0x3e074a8c, 0xbed87cba, 0xbe94b2a7, 0xbeb9158a, 0x3e06e404, 0xbe4216de, 0x3a3bae00, 0x3bc9f900, 0xbe05dde4, 0xbe5bef69, 0x3e06b148, 0x3e6bc304, 0xbd9bb79c, 0xbe87f0ac, 0xbe98cd9b, 0x3e1735dc, 0xbedd7037, 0xbe71302b, 0xbe295dd2, 0xbe83e971, 0x3eabc840, 0x3ea58b16, 0x3d721bf0, 0xbee2f252, 0x3e83a64e, 0xbe136b9a, 0xbebd57dc, 0x3ebd57a4, 0x3e4eb6e0, 0x3e72843c, 0xbdd1716c, 0xbc172600, 0x3e3b9ae0, 0x3dd306b8, 0x3e354500, 0xbca2ec60, 0xbdcdfc84, 0xbe19fc78, 0x3db3dd28, 0xbd669538, 0xbe8b7474, 0xbe8d2560, 0xbe5cf1d4, 0xbeaa02a3, 0xbebbb5a4, 0x3e1ae0c4, 0x3e9e5868, 0x3da48928, 0x3d987eb0, 0xbd8d3050, 0x3e10c984, 0xbeaa740b, 0xbe6de235, 0x3e430d88, 0x3e1f0c64}; uint32_t hidden_biases1_shape[] = {1, 5}; uint32_t hidden_biases1_values[] = { 0x3e915990, 0xbe9e462c, 0x3e332b14, 0x3eace9cc, 0x3ee4e29a, 0x3e55de1c, 0xbe5ec821, 0xbebdbf60, 0xbec4e626, 0x3ee46d12, 0x3ec83690, 0x3eb165e2, 0xbdd1fa20, 0xbe20b66c, 0x3ebbff92}; uint32_t all_ts_out1_shape[] = {5, 1, 2, 5}; uint32_t all_ts_out1_exp_values[] = { 0x3faed879, 0x3f212916, 0x3e315ac6, 0x3f584762, 0x3e773eca, 0x3f1a0e70, 0x3f30b93c, 0x3cd3b530, 0x3f55a8be, 0x3f7349dc, 0x3f67b47e, 0x3ea2e278, 0x3e728624, 0x3f05967e, 0x3eae0ece, 0x3f01eb96, 0x3ed38c5e, 0x3d76c0f6, 0x3f1f4629, 0x3f31922a, 0x3f018d7e, 0x3db2f8c8, 0x3e962ef5, 0x3e91c9db, 0x3ed82154, 0x3eab6769, 0x3e736499, 0x3e04e914, 0x3eda874c, 0x3f183a7d, 0x3e91da9e, 0x3cec7d07, 0x3eaa587e, 0x3e519080, 0x3ed40a7e, 0x3e783466, 0x3e5bb505, 0x3e2863f0, 0x3eb7d4c3, 0x3efefd82, 0x3daf16aa, 0xbd5aa005, 0x3eba1ae9, 0x3dcca13b, 0x3edeb73c, 0x3e1b0164, 0x3e316c76, 0x3e5809ce, 0x3eaea292, 0x3ec931ed}; zdnn_ztensor *all_ts_out1 = test_layer( all_ts_out0, h01_shape, (void *)h01_values, weights1_shape, (void *)weights1_values, biases1_shape, (void *)biases1_values, hidden_weights1_shape, (void *)hidden_weights1_values, hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape, (void *)all_ts_out1_exp_values, is_layer_bidir[0], is_layer_bidir[1]); free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1); } void gru_fwd_to_bidir() { // num_timesteps = 5 // num_batches = 2 // num_features = 4 // num_hidden = 4, 5 bool is_layer_bidir[] = {false, true}; // first layer uint32_t input0_shape[] = {5, 2, 4}; uint32_t input0_values[] = { 0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a, 0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e, 0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0, 0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48, 0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8, 0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b, 0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80}; uint32_t h00_shape[] = {1, 2, 4}; uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f, 0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4}; uint32_t weights0_shape[] = {1, 4, 4}; uint32_t weights0_values[] = { 0x3e8c896e, 0x3e9ed100, 0x3e493898, 0x3dcbca78, 0xbd813f20, 0x3ef5cf48, 0x3ed41bd0, 0xbede9cf8, 0x3c9c6440, 0xbec54796, 0x3edec5e8, 0x3d3c6690, 0x3ded4400, 0xbe3ba1ec, 0x3ee1e222, 0xbea027ac, 0xbe6311c8, 0x3e4b3424, 0x3dbed0f8, 0x3e67aa8c, 0xbc93cb20, 0x3d8a55c8, 0xbec67a6c, 0x3e4de7f8, 0x3ea3ba40, 0x3eaba4fe, 0xbeb16e18, 0xbe97a46a, 0x3efe7f82, 0xbe96bbc0, 0xbe843ed2, 0x3e1aadc8, 0xbeee948c, 0x3dbfaa08, 0x3e44e48c, 0x3eb7435c, 0x3ee3743e, 0xbdac80c8, 0xbe97a134, 0x3e3f7148, 0x3ec2a6f0, 0xbda882b8, 0x3e3bb1dc, 0xbefd5f4a, 0xbeff5dfe, 0xbe6a5f1c, 0x3e817616, 0xbea61100}; uint32_t biases0_shape[] = {1, 4}; uint32_t biases0_values[] = {0xbe7e7cdc, 0xbec42d02, 0xbeef9400, 0xbed810ec, 0xbee5f866, 0xbe72ba40, 0x3eae4fce, 0xbb546b00, 0xbdcfb470, 0x3e8c6456, 0x3e8a6774, 0xbef6e502}; uint32_t hidden_weights0_shape[] = {1, 4, 4}; uint32_t hidden_weights0_values[] = { 0xbe9bc938, 0xbdfedb88, 0x3e48ec5c, 0xbef59156, 0x3ee84968, 0x3cb8d280, 0x3cf559e0, 0xbe97bba0, 0x3eaf6fd0, 0x3d956718, 0xbe79d1cc, 0xbe002b3c, 0xbed7e164, 0x3df2ddd0, 0x3e7245d4, 0xbe7966ec, 0x3e7fa638, 0x3ef0d4f2, 0xbef3dd78, 0xbce1b020, 0x3dd65318, 0x3eac7f54, 0xbc133e80, 0x3d99bfa0, 0xbec7b396, 0xbe5f3eb0, 0xbec0c878, 0xbe51adf4, 0xbe9368e8, 0xbe00dcd4, 0xbec577a2, 0x3e97e798, 0xbe331d5c, 0xbea6c676, 0x3c63ac80, 0x3ef27eba, 0xbed1d2ba, 0xbcd23440, 0xbd30adc0, 0x3ea29306, 0xbdd9d200, 0x3eb74200, 0x3dcf3d10, 0x3ef30cc4, 0x3ddae2f8, 0xbd5288f0, 0x3ea2c660, 0xbd141d60}; uint32_t hidden_biases0_shape[] = {1, 4}; uint32_t hidden_biases0_values[] = { 0xbdc53cf0, 0xbdc90e10, 0xbee5b8ba, 0xbedd0a44, 0x3e9fb02e, 0xbec8528a, 0xbdd87bf0, 0xbe4f9a1c, 0xbda03c28, 0x3bd3e180, 0xbe6896b8, 0x3e40deb8}; uint32_t all_ts_out0_shape[] = {5, 1, 2, 4}; uint32_t all_ts_out0_exp_values[] = { 0x3dbbe338, 0x3e91c6be, 0x3f53d36d, 0xbee51fe8, 0x3f248241, 0x3f14fbd0, 0x3ed3b798, 0x3ed452e7, 0xbdfe4e88, 0x3e12cda1, 0x3f3e34b7, 0xbf103a51, 0x3e33cc72, 0x3e93fd0d, 0x3ee42df8, 0x3d790f32, 0xbe6f1ec6, 0x3c36a710, 0x3f380cab, 0xbf4b6960, 0x3ce736e8, 0x3e6fd98a, 0x3ef5e203, 0xbedb0b88, 0xbedb1a27, 0xbc8798ec, 0x3f1fe987, 0xbecfbd8c, 0x3cd23b72, 0x3e817b76, 0x3edf4e9e, 0xbe603530, 0xbeee1f9e, 0xbda1fc72, 0x3f24978b, 0xbf2e6ce5, 0xbe8638b3, 0x3e90d126, 0x3f01ed5f, 0xbdfc585c}; zdnn_ztensor *input0 = alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (void *)input0_values); zdnn_ztensor *all_ts_out0 = test_layer( input0, h00_shape, (void *)h00_values, weights0_shape, (void *)weights0_values, biases0_shape, (void *)biases0_values, hidden_weights0_shape, (void *)hidden_weights0_values, hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape, (void *)all_ts_out0_exp_values, false, is_layer_bidir[0]); // second layer uint32_t h01_shape[] = {2, 2, 5}; uint32_t h01_values[] = {0x3ff3351d, 0x3f88a36c, 0x3df6f2f0, 0x3fb435ce, 0x3dc6a650, 0x3f2349e4, 0x3ff383d7, 0x3ebc0f18, 0x3f8ec53f, 0x3fb923dc, 0x3e4d27b0, 0x3fe76faa, 0x3f6487aa, 0x3f9acc98, 0x3e925fd4, 0x3f3889fc, 0x3f04fd9a, 0x3f259760, 0x3f9ec7e0, 0x3f9aeb4a}; uint32_t weights1_shape[] = {2, 4, 5}; uint32_t weights1_values[] = { 0x3e2598d4, 0x3d65d3e0, 0xbeb31aa8, 0xbd0388a0, 0xbec66e3b, 0x3d67f3b0, 0xbdd123b0, 0xbe700636, 0x3ee28262, 0x3e62db50, 0xbb5a2c80, 0xbb4def80, 0x3eb8e4f2, 0x3e256d64, 0xbea317e4, 0xbdb50e24, 0x3d69b920, 0xbeb9d294, 0x3c4f7420, 0xbe01fea6, 0xbe5f6ed0, 0x3ebb7968, 0xbdea86c4, 0x3ee4e636, 0x3e5bbc44, 0xbedd358e, 0x3ea3e864, 0x3e497f5c, 0x3e6d851c, 0x3d527bf8, 0xbe81ffa5, 0x3eb0cbec, 0x3ecbffd4, 0x3e8e5746, 0xbddabb30, 0x3ebc5350, 0x3ecb999a, 0x3e177f54, 0xbe20471c, 0xbe811315, 0xbebcb154, 0xbea1834a, 0xbe856c8e, 0x3c9a1ea0, 0xbe84f4be, 0x3e7822c0, 0x3ca36520, 0x3e1c8044, 0x3e9399fc, 0x3ea04420, 0x3eb5ccc2, 0xbea16940, 0xbe8872c0, 0xbead15e7, 0xbe249da6, 0x3e9cab54, 0xbe7c17a9, 0xbc1fdba0, 0xbe9d3169, 0x3ec122ee, 0x3e3248cc, 0x3e5f481c, 0xbee1e40d, 0x3ed6d390, 0xbd93fe10, 0x3da2aec0, 0xbe9fee66, 0xbeb7e0dd, 0x3eb76f78, 0xbe94b3e4, 0x3e42d780, 0x3dcedbf0, 0x3eb4c482, 0xbecc7bce, 0x3e9eff90, 0xbe1b9f76, 0xbe9aebe8, 0x3e77c3f8, 0xbe9c4230, 0xbead1b0c, 0xbe19a60a, 0x3d64ada0, 0x3e4d6418, 0x3e1735dc, 0x3e6bc304, 0xbd87a1dc, 0x3ecd16fc, 0xbea1dc41, 0x3eabc840, 0xbedd7037, 0x3ba04b00, 0x3e8c10dc, 0xbe4216de, 0xbe136b9a, 0x3ea58b16, 0x3ebcdbe4, 0xbe90c29a, 0x3e06b148, 0x3a3bae00, 0xbebd57dc, 0xbe807b12, 0xbd507b08, 0x3d082a00, 0xbeadd2f6, 0x3e80b7ea, 0xbeb030cc, 0xbe8480f1, 0xbe58367b, 0x3edb2580, 0xbe8219a4, 0x3e99b77e, 0x3eb0f98a, 0x3ed26ffe, 0x3eade05a, 0xbd8f889c, 0x3ea2c8c8, 0x3e926d0a, 0x3e3b45e4, 0xbe26eada, 0x3ec26bea}; uint32_t biases1_shape[] = {2, 5}; uint32_t biases1_values[] = { 0x3e55de1c, 0xbe5ec821, 0xbebdbf60, 0xbec4e626, 0x3ee46d12, 0xbea06a9a, 0x3ec02c1a, 0xbd472b98, 0xbebfde02, 0xbe77c691, 0x3d0ff4f8, 0x3e9e8ea0, 0x3ece54c0, 0x3e86944e, 0x3d757710, 0x3c6b9ce0, 0xbe0d9648, 0xbdc724ec, 0x3d737210, 0x3e630230, 0x3e915990, 0xbe9e462c, 0x3e332b14, 0x3eace9cc, 0x3ee4e29a, 0x3eca9984, 0x3ed16702, 0xbed417e7, 0x3ea17e98, 0x3e658114}; uint32_t hidden_weights1_shape[] = {2, 5, 5}; uint32_t hidden_weights1_values[] = { 0x3dc5e080, 0xbd506310, 0x3eb682ba, 0xbdd1716c, 0xbc172600, 0xbe807ef0, 0x3e0332e4, 0x3d952498, 0xbca2ec60, 0xbdcdfc84, 0xbecc25a9, 0x3c696e40, 0x3ebdf640, 0xbe8b7474, 0xbe8d2560, 0x3ec8c806, 0xbe9a126e, 0xbe1985b8, 0x3e1ae0c4, 0x3e9e5868, 0xbe94b2a7, 0xbeb9158a, 0x3e06e404, 0x3e10c984, 0xbeaa740b, 0x3e63833c, 0x3e99f81e, 0x3ca711d0, 0x3e675c3c, 0xbeb798f6, 0xbecfe0c1, 0xbed8b7ed, 0xbece783b, 0xbe972362, 0xbe03b7b6, 0xbedc1c4e, 0x3ebe51d8, 0x3ebde4ee, 0x3ebf18f2, 0xbee0d2e5, 0xbede7c01, 0xbe37306c, 0x3e769414, 0x3cc4e590, 0xbe325de8, 0xbdb9cd1c, 0x3e062014, 0x3ee39938, 0x3e592a78, 0x3dc59638, 0x3bc9f900, 0xbe05dde4, 0xbe5bef69, 0x3eafbdf8, 0x3ebc395c, 0xbd9bb79c, 0xbe87f0ac, 0xbe98cd9b, 0x3e261b9c, 0x3df90638, 0xbe71302b, 0xbe295dd2, 0xbe83e971, 0xbe18ef8e, 0xbe58ace5, 0x3d721bf0, 0xbee2f252, 0x3e83a64e, 0xbdfff1d8, 0xbe574539, 0x3ebd57a4, 0x3e4eb6e0, 0x3e72843c, 0x3e074a8c, 0xbed87cba, 0x3c976030, 0x3d2f4d98, 0x3e5b9460, 0xbe436636, 0x3cf049b0, 0xbea1ef22, 0x3ed3c2e8, 0x3e6328f4, 0x3e24fec4, 0xbe989ba1, 0xbe190f96, 0x3cc42620, 0xbed14480, 0xbea299d4, 0xbe24134e, 0xbdf89d64, 0xbe8d6097, 0xbda3e468, 0x3e2a3b28, 0x3dc7ff90, 0xbdb0b3c4, 0x3cbbc620, 0xbeaa2909, 0x3ec258fa, 0xbeae8cee, 0x3e3b9ae0, 0x3dd306b8, 0x3e354500, 0xbe271822, 0x3e3d5c4c, 0xbe19fc78, 0x3db3dd28, 0xbd669538, 0x3e2dd3f4, 0x3d0f9250, 0xbe5cf1d4, 0xbeaa02a3, 0xbebbb5a4, 0x3e987cda, 0x3d190310, 0x3da48928, 0x3d987eb0, 0xbd8d3050, 0xbe6f1e1b, 0x3d64ba10, 0xbe6de235, 0x3e430d88, 0x3e1f0c64, 0x3b9084c0, 0xbeb401c3, 0xbeb3c7f8, 0xbeb1870e, 0xbd4e46b0, 0xbe81b1a9, 0x3e6ef9a8, 0x3e11fa20, 0xbe0d48c0, 0x3e20904c, 0x3e5c50f0, 0xbd3aa670, 0x3e75d434, 0x3e4904fc, 0xbee0a324, 0xbea1a3c0, 0x3eb037d8, 0x3d7f2f50, 0x3ee1dbc6, 0xbec39102, 0xbe62d375, 0x3e8db48a, 0xbe9933c8, 0x3e83aa94, 0x3e55ae7c, 0xbebc9a53, 0x3e7d66c4}; uint32_t hidden_biases1_shape[] = {2, 5}; uint32_t hidden_biases1_values[] = { 0x3e804fe0, 0xbe89ca96, 0x3ecdd9da, 0x3e5d42c8, 0x3e79a49c, 0xbe0751fa, 0x3e1940d8, 0xbe03c1e6, 0x3e8d90bc, 0xbdfe1e6c, 0x3ec83690, 0x3eb165e2, 0xbdd1fa20, 0xbe20b66c, 0x3ebbff92, 0x3e878898, 0x3ec1d528, 0xbe76cf7f, 0x3e109bc4, 0x3e3b6830, 0xbe8f83dc, 0x3e036284, 0xbe2089f6, 0x3eb2e8ec, 0xbda4ce70, 0xbe2ab878, 0x3de69348, 0x3e226e48, 0xbe5fbd62, 0x3d21ed48}; uint32_t all_ts_out1_shape[] = {5, 2, 2, 5}; uint32_t all_ts_out1_exp_values[] = { 0x3fb07596, 0x3f0724ff, 0x3d69c926, 0x3f5b7fa7, 0x3e9f50e4, 0x3e47b948, 0x3f169176, 0x3e5bd372, 0x3f6ed378, 0x3f48821b, 0x3e88bf42, 0x3f1503cf, 0xbe228c59, 0x3f0cf024, 0x3d87f2ca, 0x3e298037, 0x3f0cee29, 0xbe29a96c, 0x3e9dca6b, 0x3ec26071, 0x3f6dcbb8, 0x3ebb0660, 0x3c74d650, 0x3f117062, 0x3ee3a265, 0x3db18655, 0x3e677394, 0x3db978f5, 0x3f3bbe5a, 0x3f1d1df8, 0x3e9c2766, 0x3f1e9c69, 0xbe214906, 0x3f0e5d23, 0x3d5ee33f, 0x3e809bf2, 0x3f0fa73a, 0xbe160d84, 0x3ec20162, 0x3e9546b7, 0x3f0d0270, 0x3ea79919, 0xbc9908d0, 0x3ed83b4c, 0x3f0a1d62, 0xbba4d360, 0x3e5a624c, 0x3a3d5a00, 0x3f19d3f1, 0x3f137653, 0x3ea3d178, 0x3f33a091, 0xbdfac5f0, 0x3f118a1b, 0x3db83b0a, 0x3e44b9c6, 0x3f10e4c8, 0xbdc43ac6, 0x3edf58bb, 0x3e902384, 0x3ea54086, 0x3e589718, 0xbd23b7e4, 0x3eb6e5d1, 0x3f0c00aa, 0xbd1787d8, 0x3e2d45a3, 0xbd1be2d7, 0x3f094a68, 0x3f050376, 0x3ef25316, 0x3f66231a, 0xbbf4ad80, 0x3f1f5c9d, 0x3e57ea78, 0x3e7b6112, 0x3f182175, 0x3da612d0, 0x3f04cef6, 0x3ee8d645, 0x3e136cf0, 0x3e5768e7, 0xbd873546, 0x3ea25dfa, 0x3f133a2c, 0xbce72cb2, 0x3e1813fb, 0xbdb1ffc8, 0x3ef86608, 0x3eea8306, 0x3f02832e, 0x3f97b462, 0x3e814796, 0x3f4e1d12, 0x3e7082c4, 0x3ea66204, 0x3f147ff7, 0x3ebb4a06, 0x3f477b01, 0x3f2985fa}; zdnn_ztensor *all_ts_out1 = test_layer( all_ts_out0, h01_shape, (void *)h01_values, weights1_shape, (void *)weights1_values, biases1_shape, (void *)biases1_values, hidden_weights1_shape, (void *)hidden_weights1_values, hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape, (void *)all_ts_out1_exp_values, is_layer_bidir[0], is_layer_bidir[1]); free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1); } void gru_bidir_to_bidir() { // num_timesteps = 5 // num_batches = 2 // num_features = 4 // num_hidden = 4, 5 bool is_layer_bidir[] = {true, true}; // first layer uint32_t input0_shape[] = {5, 2, 4}; uint32_t input0_values[] = { 0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a, 0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e, 0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0, 0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48, 0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8, 0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b, 0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80}; uint32_t h00_shape[] = {2, 2, 4}; uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f, 0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4, 0x3fb8c472, 0x3f849e59, 0x3eb88b80, 0x3bc03f00, 0x3f1a65ee, 0x3f5d6a8e, 0x3ea8b604, 0x3fcb5de0}; uint32_t weights0_shape[] = {2, 4, 4}; uint32_t weights0_values[] = { 0x3e493898, 0x3dcbca78, 0xbeee948c, 0x3dbfaa08, 0x3ed41bd0, 0xbede9cf8, 0x3ee3743e, 0xbdac80c8, 0x3edec5e8, 0x3d3c6690, 0x3ec2a6f0, 0xbda882b8, 0x3ee1e222, 0xbea027ac, 0xbeff5dfe, 0xbe6a5f1c, 0xbeb493ac, 0xbe952c30, 0x3cac4fa0, 0xbe94a63c, 0x3cb6ae60, 0x3e2ef934, 0x3ea50604, 0x3eb32ed6, 0xbeb47690, 0xbe988dc4, 0xbec183fa, 0xbe380bcc, 0xbe8cec88, 0xbc32ba00, 0xbeafbf44, 0x3ed7eee0, 0x3dbed0f8, 0x3e67aa8c, 0x3e8c896e, 0x3e9ed100, 0xbec67a6c, 0x3e4de7f8, 0xbd813f20, 0x3ef5cf48, 0xbeb16e18, 0xbe97a46a, 0x3c9c6440, 0xbec54796, 0xbe843ed2, 0x3e1aadc8, 0x3ded4400, 0xbe3ba1ec, 0xbd6c53f0, 0x3d5bc2b0, 0x3e7604cc, 0xbed2f700, 0xbe648f70, 0xbdd664c0, 0x3e34d140, 0x3e8ab64c, 0x3eccb614, 0x3eb6d016, 0xbdf63f00, 0x3ecb4226, 0xbecedf54, 0x3e0eec08, 0xbdd75a50, 0x3eaf295c, 0x3e44e48c, 0x3eb7435c, 0x3e7fa638, 0x3ef0d4f2, 0xbe97a134, 0x3e3f7148, 0x3dd65318, 0x3eac7f54, 0x3e3bb1dc, 0xbefd5f4a, 0xbec7b396, 0xbe5f3eb0, 0x3e817616, 0xbea61100, 0xbe9368e8, 0xbe00dcd4, 0x3e3924a0, 0x3d807a40, 0xbec83e98, 0xbd130f20, 0x3d81aa40, 0xbde9d330, 0xbe862d7a, 0x3efd3ec0, 0xbb73ed00, 0xbb663e00, 0x3eceb7d8, 0x3e38f410, 0xbdca6d08, 0x3d82a7c0, 0xbecfc186, 0x3c67f0c0}; uint32_t biases0_shape[] = {2, 4}; uint32_t biases0_values[] = { 0x3e9fb02e, 0xbec8528a, 0xbdd87bf0, 0xbe4f9a1c, 0x3ee07afa, 0xbea63fd0, 0xbd68fbd0, 0x3e12af48, 0xbdcfb470, 0x3e8c6456, 0x3e8a6774, 0xbef6e502, 0xbef20a42, 0x3ddd3bb0, 0xbe8fa9a8, 0xbee43e50, 0xbdc53cf0, 0xbdc90e10, 0xbee5b8ba, 0xbedd0a44, 0x3c827de0, 0xbeac41fa, 0xbeceee2c, 0x3ecc0d98}; uint32_t hidden_weights0_shape[] = {2, 4, 4}; uint32_t hidden_weights0_values[] = { 0x3e48ec5c, 0xbef59156, 0xbe331d5c, 0xbea6c676, 0x3cf559e0, 0xbe97bba0, 0xbed1d2ba, 0xbcd23440, 0xbe79d1cc, 0xbe002b3c, 0xbdd9d200, 0x3eb74200, 0x3e7245d4, 0xbe7966ec, 0x3ddae2f8, 0xbd5288f0, 0x3e290ef0, 0x3e83cb7a, 0x3be1d000, 0x3ed3b0f2, 0x3ec00ef2, 0xbef7935a, 0xbdae18e0, 0xbe15aae8, 0xbe24d228, 0x3eb91542, 0xbe86d40a, 0xbe97fc56, 0x3a51d400, 0xbed3b130, 0x3d8757d8, 0xbe3d5b84, 0xbef3dd78, 0xbce1b020, 0xbe9bc938, 0xbdfedb88, 0xbc133e80, 0x3d99bfa0, 0x3ee84968, 0x3cb8d280, 0xbec0c878, 0xbe51adf4, 0x3eaf6fd0, 0x3d956718, 0xbec577a2, 0x3e97e798, 0xbed7e164, 0x3df2ddd0, 0xbeddda26, 0xbe2bc8cc, 0x3d7fab80, 0x3e65a254, 0x3e7da22c, 0xbd97a438, 0x3ee54c20, 0xbeb4f724, 0xbeb65808, 0x3bb33680, 0x3e9c9930, 0xbe58ff9c, 0xbe1156a8, 0x3ed32696, 0xbea1d8c6, 0x3e169740, 0x3c63ac80, 0x3ef27eba, 0xbee5f866, 0xbe7e7cdc, 0xbd30adc0, 0x3ea29306, 0xbe72ba40, 0xbec42d02, 0x3dcf3d10, 0x3ef30cc4, 0x3eae4fce, 0xbeef9400, 0x3ea2c660, 0xbd141d60, 0xbb546b00, 0xbed810ec, 0xbefdbbe6, 0xbe937b62, 0x3e39b6d8, 0x3ed270de, 0x3e671d1c, 0x3e933052, 0xbe2afcc4, 0x3e0b3574, 0xbe75e520, 0x3e879224, 0xbe0f13d4, 0xbe72401c, 0xbeaad6d0, 0x3ec47c50, 0x3e174298, 0xbe70adfc}; uint32_t hidden_biases0_shape[] = {2, 4}; uint32_t hidden_biases0_values[] = { 0xbee66a3a, 0xbd0a36c0, 0x3ee121a2, 0xbe50d738, 0xbdea2a18, 0xbcb62760, 0xbe9bea52, 0x3e2d28ac, 0xbda03c28, 0x3bd3e180, 0xbe6896b8, 0x3e40deb8, 0x3da6bf30, 0x3ed46246, 0xbe2ba4a8, 0x3e16cff8, 0x3ee72b36, 0x3e396c38, 0xbee707ae, 0x3ea1f874, 0x3e21e080, 0xbc28fd40, 0xbde64cc0, 0xbe9dce58}; uint32_t all_ts_out0_shape[] = {5, 2, 2, 4}; uint32_t all_ts_out0_exp_values[] = { 0x3f6bce30, 0x3beaf6b0, 0xbec8dfee, 0xbd929bc0, 0x3fb6725f, 0x3f5a6c8b, 0xbee4e44b, 0xbdb632bc, 0x3d9293c4, 0xbeb2a8df, 0xbf3182a1, 0x3f098928, 0x3e809ad9, 0xbeaffc95, 0xbf27c972, 0x3f331a57, 0x3f5aaeda, 0xbe80c748, 0xbf27f391, 0xbc2d591f, 0x3faa62a2, 0x3f0a4d52, 0xbf36fb1c, 0x3ec311f0, 0x3e085652, 0xbec6dc8d, 0xbf337790, 0x3efc9499, 0x3e91c071, 0xbe90d269, 0xbf2fab83, 0x3f3dd627, 0x3f50bbdd, 0xbf231060, 0xbf498fe4, 0xbea2a61f, 0x3f8e5d9f, 0x3c3ce7d0, 0xbf4c17b3, 0xbe4c7e78, 0x3dd54579, 0xbecb384e, 0xbf1ee32c, 0x3ed38a87, 0x3e22ecd6, 0xbe6019ea, 0xbebcd226, 0x3f30504a, 0x3f4025f6, 0xbe8eb1d6, 0xbf4b2853, 0x3eac30ec, 0x3f79e857, 0x3e21b530, 0xbf4bce96, 0x3ecebfe8, 0x3e88787f, 0xbe832944, 0xbf56da6c, 0x3e9e64a2, 0x3ea35eab, 0xbd986300, 0xbf12712f, 0x3f597df2, 0x3f3d9310, 0xbf083670, 0xbf5b102b, 0x3ec92c09, 0x3f5df7b3, 0x3e6c9d73, 0xbf43d815, 0x3e9aa38c, 0x3f09f861, 0x3d10f6e8, 0xbf26dab4, 0x3e60c564, 0x3ea667e6, 0x3ee0c930, 0xbed2d9b6, 0x3f655092}; zdnn_ztensor *input0 = alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (void *)input0_values); zdnn_ztensor *all_ts_out0 = test_layer( input0, h00_shape, (void *)h00_values, weights0_shape, (void *)weights0_values, biases0_shape, (void *)biases0_values, hidden_weights0_shape, (void *)hidden_weights0_values, hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape, (void *)all_ts_out0_exp_values, false, is_layer_bidir[0]); // second layer uint32_t h01_shape[] = {2, 2, 5}; uint32_t h01_values[] = {0x3e9dedd8, 0x3fdf494a, 0x3f17202a, 0x3fab0a5b, 0x3fbdc183, 0x3f5202c8, 0x3fc27d91, 0x3f450430, 0x3f4db9fc, 0x3fdf09e5, 0x3f55605a, 0x3f12f64e, 0x3f1aaad2, 0x3f901ccb, 0x3fe8eecd, 0x3f93bb52, 0x3f2716d8, 0x3faeb44b, 0x3f1ed3c6, 0x3eab06f4}; uint32_t weights1_shape[] = {2, 8, 5}; uint32_t weights1_values[] = { 0xbe1b9f76, 0x3e77c3f8, 0xbead1b0c, 0x3ecb999a, 0xbe20471c, 0x3e5f481c, 0x3ed6d390, 0xbe5f6ed0, 0xbdea86c4, 0x3e5bbc44, 0xbe9fee66, 0x3eb76f78, 0xbedd358e, 0x3e497f5c, 0x3d527bf8, 0x3dcedbf0, 0xbecc7bce, 0xbe81ffa5, 0x3ecbffd4, 0xbddabb30, 0xbe9aebe8, 0xbe9c4230, 0x3ebc5350, 0x3e177f54, 0xbe811315, 0xbee1e40d, 0xbd93fe10, 0x3ebb7968, 0x3ee4e636, 0xbe807b12, 0xbeb7e0dd, 0xbe94b3e4, 0x3ea3e864, 0x3e6d851c, 0xbeb030cc, 0x3eb4c482, 0x3e9eff90, 0x3eb0cbec, 0x3e8e5746, 0x3e99b77e, 0xbebd9868, 0x3eb1c556, 0x3ed4086e, 0xbe5113e1, 0xbe4a029f, 0xbecfb148, 0xbd891828, 0x3ed8ea94, 0x3e6fec98, 0x3e2270c4, 0x3de585b8, 0xbec9e6b4, 0x3ecebb20, 0xbe53d7b8, 0x3ec72844, 0xbd0ab3d0, 0xbecee7d6, 0xbec12893, 0xbe618c84, 0x3e66f338, 0xbe6741db, 0x3ed5ca40, 0xbe2ccb44, 0xbd203aa8, 0x3d81ac10, 0x3db92198, 0x3e4a7010, 0xbe9d7ac6, 0xbd301208, 0x3ec2d2d6, 0x3e2de8c8, 0x3e479f54, 0x3ed8d474, 0xbeb25d85, 0x3d763d80, 0x3eb61b5a, 0xbec61cd1, 0xbe44c542, 0x3ebee346, 0xbe53df41, 0xbe6f1e1b, 0x3e9e8ea0, 0x3ee46d12, 0xbdd1fa20, 0xbe8f83dc, 0x3b9084c0, 0x3ece54c0, 0x3e915990, 0xbe20b66c, 0x3e036284, 0x3e3d5c4c, 0x3e86944e, 0xbe9e462c, 0x3ebbff92, 0xbe2089f6, 0x3d0f9250, 0x3d757710, 0x3e332b14, 0x3e804fe0, 0x3eb2e8ec, 0x3d190310, 0x3e55de1c, 0x3eace9cc, 0xbe89ca96, 0xbda4ce70, 0x3d64ba10, 0xbe5ec821, 0x3ee4e29a, 0x3ecdd9da, 0x3e3248cc, 0xbeb401c3, 0xbebdbf60, 0x3ec83690, 0x3e5d42c8, 0x3da2aec0, 0x3d0ff4f8, 0xbec4e626, 0x3eb165e2, 0x3e79a49c, 0x3e42d780, 0x3dcaf230, 0x3ee0b168, 0xbdcc9010, 0x3ed7e74a, 0xbe97eae2, 0xbdd20768, 0xbed93dd3, 0x3e917fbc, 0xbdcbff10, 0xbd084a60, 0xbe5de779, 0xbedb8204, 0x3caf1b90, 0xbda475ac, 0x3ebd81c8, 0x3d7ba930, 0x3ee1a07c, 0xbedeee8a, 0x3eb369f6, 0xbe19b22c, 0x3ebc4676, 0xbe90de80, 0xbe872d40, 0x3e662ae4, 0xbed457d0, 0xbe9acddc, 0x3daf9920, 0xbe1c1d3a, 0x3ec2326c, 0x3e3bb9b4, 0x3caa1db0, 0xbd1e1828, 0x3e667240, 0x3e8472c6, 0x3edee626, 0xbe28e040, 0xbdc0f07c, 0xbe942d27, 0xbe0aeb80, 0xbe025ea8, 0x3ea2c8c8, 0x3e3b45e4, 0x3ec26bea, 0x3cc42620, 0xbe436636, 0xbd507b08, 0xbeadd2f6, 0x3c976030, 0xbe8d6097, 0x3e24fec4, 0xbe8480f1, 0x3edb2580, 0xbea1ef22, 0x3cbbc620, 0xbea299d4, 0x3eb0f98a, 0x3eade05a, 0xbe190f96, 0x3e5b9460, 0x3e2a3b28, 0x3e926d0a, 0xbe26eada, 0xbdf89d64, 0x3e6328f4, 0x3ec258fa, 0x3d082a00, 0x3e80b7ea, 0xbdb0b3c4, 0xbed14480, 0x3cf049b0, 0xbe58367b, 0xbe8219a4, 0x3d2f4d98, 0xbda3e468, 0xbe989ba1, 0x3ed26ffe, 0xbd8f889c, 0x3ed3c2e8, 0xbeaa2909, 0xbe24134e, 0x3ed89bd2, 0xbce64df0, 0xbed605fa, 0x3edaf946, 0xbe9d91cb, 0x3dd8c630, 0x3e8fcc58, 0xbeac7e7c, 0xbe8525dc, 0xbec0490a, 0xbedf67a9, 0x3dedf310, 0x3e4679ac, 0x3ebc54aa, 0xbe4e7f38, 0xbe025fa2, 0x3e10ce08, 0xbe879404, 0xbeb62674, 0x3d940df8, 0xbe9bf81e, 0x3d2a1fb8, 0x3d836668, 0xbddc5118, 0x3ed2d41c, 0x3ec8c0ca, 0x3e2abb28, 0x3e122c34, 0x3e791bd4, 0xbe5a9fca, 0xbd97418c, 0xbddf28c4, 0x3d01b298, 0xbe3b1bb2, 0x3e23c650, 0xbed0b705, 0xbe362bda, 0xbe94746f, 0x3ec058f2, 0xbde59ef4}; uint32_t biases1_shape[] = {2, 5}; uint32_t biases1_values[] = { 0xbe5fbd62, 0x3d21ed48, 0x3e84b2c0, 0xbd3641c0, 0x3e0b5e64, 0x3cdf2e90, 0x3eb58a42, 0xbe019774, 0x3e578a54, 0x3ec4c2fc, 0x3e8d90bc, 0xbdfe1e6c, 0xbe2ab878, 0x3de69348, 0x3e226e48, 0xbd6ccb78, 0xbea7780c, 0x3e061770, 0xbea2cdd5, 0xbeb5b12a, 0xbddce6cc, 0x3e208298, 0xbea5ddf2, 0xbe86a497, 0xbe68730d, 0x3e97de7c, 0xbe703894, 0xbd48ccd8, 0xbe101be0, 0xbeb81f6b}; uint32_t hidden_weights1_shape[] = {2, 5, 5}; uint32_t hidden_weights1_values[] = { 0xbe325de8, 0x3d7f2f50, 0x3ee1dbc6, 0xbec39102, 0xbe62d375, 0x3dc59638, 0xbe9933c8, 0x3e83aa94, 0x3e55ae7c, 0xbebc9a53, 0xbeb3c7f8, 0xbeb1870e, 0xbd4e46b0, 0xbe81b1a9, 0x3e6ef9a8, 0x3e11fa20, 0xbe0d48c0, 0x3e20904c, 0x3e5c50f0, 0xbd3aa670, 0x3e75d434, 0x3e4904fc, 0xbee0a324, 0xbea1a3c0, 0x3eb037d8, 0xbd912c2c, 0xbe8d3f0b, 0x3ea0bcaa, 0x3e1f747c, 0x3d6b9ee0, 0xbebdb332, 0x3e935dc2, 0xbea9c5c8, 0xbecccd1f, 0x3ec31294, 0x3e62e8b8, 0x3ed8df8e, 0x3dd289d0, 0x3dd09a78, 0xbe5a7ee4, 0x3e08fc84, 0x3d1ef258, 0x3d851878, 0xbe91286a, 0x3e92b048, 0x3e37f4f4, 0xbed5df49, 0xbe5655f7, 0xbd4613f0, 0xbd68b2e8, 0x3dc7ff90, 0xbede7c01, 0xbe37306c, 0x3e769414, 0x3cc4e590, 0xbeae8cee, 0xbdb9cd1c, 0x3e062014, 0x3ee39938, 0x3e592a78, 0x3e63833c, 0x3e99f81e, 0x3ca711d0, 0x3e675c3c, 0xbeb798f6, 0xbecfe0c1, 0xbed8b7ed, 0xbece783b, 0xbe972362, 0xbe03b7b6, 0xbedc1c4e, 0x3ebe51d8, 0x3ebde4ee, 0x3ebf18f2, 0xbee0d2e5, 0xbdc69f70, 0xbd7bb5b8, 0xbd840080, 0xbd88748c, 0xbe987408, 0x3ea85d6a, 0x3eb1c89c, 0xbda0df98, 0xbc914780, 0xbd4637a8, 0xbeb1737d, 0xbe0d071e, 0x3e1469e4, 0x3e9ccdb4, 0xbcc4c620, 0x3d428f68, 0x3eb8509c, 0x3e33aa40, 0xbdf7d0f0, 0x3e4c5720, 0x3ed75422, 0xbedd7e2d, 0x3eafcf42, 0x3ec8b9ca, 0x3e9c8b2a, 0x3e8db48a, 0x3d737210, 0xbebfde02, 0x3ea17e98, 0x3e109bc4, 0x3e7d66c4, 0x3e630230, 0xbe77c691, 0x3e658114, 0x3e3b6830, 0x3c6b9ce0, 0xbea06a9a, 0x3eca9984, 0x3e878898, 0xbe0751fa, 0xbe0d9648, 0x3ec02c1a, 0x3ed16702, 0x3ec1d528, 0x3e1940d8, 0xbdc724ec, 0xbd472b98, 0xbed417e7, 0xbe76cf7f, 0xbe03c1e6, 0xbe597ddb, 0x3cb6fdc0, 0xbea9a47a, 0x3ed6ece6, 0x3eb5c09c, 0xbec763d2, 0x3df84f58, 0xbd92bdd4, 0xbeb76e74, 0xbdcf25dc, 0xbed21657, 0x3e9ba3fc, 0xbe877dfe, 0x3e8a9360, 0x3d26cb70, 0x3edf9e2a, 0x3ec36c40, 0xbe82d308, 0xbe6d6e1d, 0xbea00f51, 0xbde46c64, 0x3eb9b38a, 0x3dd941a0, 0xbdb26478, 0x3ec2e956}; uint32_t hidden_biases1_shape[] = {2, 5}; uint32_t hidden_biases1_values[] = { 0x3edfa1a6, 0xbeacb04b, 0xbeb99f2f, 0xbead8f69, 0xbb0d5900, 0xbe46414a, 0x3eacd6bc, 0xbe3e8e36, 0xbe9f0e96, 0x3d8d0aa8, 0x3ed26dd4, 0xbdf673cc, 0xbaa00c00, 0xbe5ddf86, 0x3ee494f2, 0x3941c000, 0x3eac49a0, 0x3ec0e9e4, 0x3d2ae830, 0x3dd00540, 0xbde97700, 0xbe95df9f, 0xbe2440b2, 0x3dad0a60, 0xbe6f45de, 0x3e893e48, 0xbece70c1, 0x3ecefc06, 0x3e24bcd8, 0xbea06bf2}; uint32_t all_ts_out1_shape[] = {5, 2, 2, 5}; uint32_t all_ts_out1_exp_values[] = { 0x3ebd7308, 0x3f64bfca, 0x3e96c38c, 0x3f3d08b3, 0x3f4ed9a0, 0x3f4cbe71, 0x3f4eb04c, 0x3e85fce6, 0x3e97fd95, 0x3f8901b2, 0x3f2f67f8, 0xbedb2fa7, 0xbefa32c3, 0x3ec8b1e1, 0xbed037d0, 0x3f4ba138, 0xbeabf370, 0xbf4120d0, 0x3ecca2bb, 0xbf2c7ea2, 0x3ee040ab, 0x3eedbe60, 0x3e6717ff, 0x3ec905c6, 0x3ed8b348, 0x3f4ef281, 0x3ed71f06, 0x3dc962ab, 0x3d91f336, 0x3f248a02, 0x3f2dcf90, 0xbe9f2068, 0xbedd7c39, 0x3ead94a9, 0xbe50a7d2, 0x3f4577ae, 0xbe58e036, 0xbf377f08, 0x3eb83368, 0xbf0e3834, 0x3ef216aa, 0x3e5e4d08, 0x3e745018, 0x3e62837b, 0x3e11ab71, 0x3f4573d1, 0x3e0c25a8, 0x3debf382, 0xbdd8e72a, 0x3e7fc71f, 0x3f2cd1a8, 0xbe07a588, 0xbea8172b, 0x3ea0fd5a, 0x3d6961d8, 0x3f3b7bd9, 0xbc7f2780, 0xbf166c22, 0x3ed1edf5, 0xbed9aa68, 0x3f0c0d67, 0x3e330cab, 0x3e2f6954, 0x3e448f94, 0x3dfbfbd1, 0x3f4a1f6a, 0x3d3c12cf, 0x3dfc4ab2, 0xbe278de1, 0x3e04a44b, 0x3f2753d8, 0x3e1a2b60, 0xbee04b4a, 0x3e6e3232, 0x3ee33cb4, 0x3f25b2fe, 0x3e751f72, 0xbf051b4b, 0x3ed8a638, 0xbe8dcab2, 0x3f1f2826, 0x3e559c26, 0x3dbbfaaa, 0x3e4feb0b, 0x3e147845, 0x3f4b713c, 0x3c42a99e, 0x3de07552, 0xbe9fcdb7, 0x3d18e8b6, 0x3f2e37ae, 0x3eea935e, 0xbe97bb49, 0x3eefdd22, 0x3f84dd69, 0x3f3c21fd, 0x3f0577d9, 0xbceedc60, 0x3f1a0c27, 0xbd85eeb0}; zdnn_ztensor *all_ts_out1 = test_layer( all_ts_out0, h01_shape, (void *)h01_values, weights1_shape, (void *)weights1_values, biases1_shape, (void *)biases1_values, hidden_weights1_shape, (void *)hidden_weights1_values, hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape, (void *)all_ts_out1_exp_values, is_layer_bidir[0], is_layer_bidir[1]); free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1); } void gru_bidir_to_fwd() { // num_timesteps = 5 // num_batches = 2 // num_features = 4 // num_hidden = 5, 4 bool is_layer_bidir[] = {true, false}; // first layer uint32_t input0_shape[] = {5, 2, 4}; uint32_t input0_values[] = { 0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a, 0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e, 0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0, 0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48, 0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8, 0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b, 0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80}; uint32_t h00_shape[] = {2, 2, 5}; uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f, 0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4, 0x3fb8c472, 0x3f849e59, 0x3eb88b80, 0x3bc03f00, 0x3f1a65ee, 0x3f5d6a8e, 0x3ea8b604, 0x3fcb5de0, 0x3f504bc2, 0x3fe33d36, 0x3fd8b70c, 0x3fc21f69}; uint32_t weights0_shape[] = {2, 4, 5}; uint32_t weights0_values[] = { 0xbed56486, 0x3dab6e00, 0x3e301b34, 0x3ea3ea60, 0x3e64a8e0, 0x3ecb70ec, 0xbd9a4a9c, 0xbe879f2a, 0x3e2b3b3c, 0x3dbfb2a0, 0x3eae1a26, 0xbd96b870, 0x3e27e118, 0xbee29f7d, 0xbeb29e53, 0xbee46847, 0xbe51a0d6, 0x3e67965c, 0xbe9488c8, 0xbe83d8ea, 0xbedd7037, 0xbd9bb79c, 0xbe05dde4, 0x3e4eb6e0, 0x3e83a64e, 0x3ea58b16, 0xbe71302b, 0xbe87f0ac, 0xbe5bef69, 0x3e72843c, 0xbebd57dc, 0x3d721bf0, 0xbe295dd2, 0xbe98cd9b, 0x3eafbdf8, 0x3bc9f900, 0x3ebd57a4, 0xbee2f252, 0xbe83e971, 0x3e261b9c, 0x3e4f3564, 0x3e7b6660, 0x3e8e0cba, 0x3e33fa44, 0x3db646b0, 0x3e382b04, 0xbd673410, 0x3edbdbde, 0x3ebdb73a, 0xbec71c7c, 0xbe87a208, 0x3c8be180, 0xbeb073c8, 0x3ec7411a, 0x3d2882b8, 0x3e0a5954, 0x3dd43780, 0xbe27d2d8, 0x3eca0944, 0xbe8f3f38, 0x3e62db50, 0xbd87a1dc, 0x3ecd16fc, 0xbea1dc41, 0x3eabc840, 0xbea317e4, 0x3ba04b00, 0x3e8c10dc, 0xbe4216de, 0xbe136b9a, 0xbe01fea6, 0x3ebcdbe4, 0xbe90c29a, 0x3e06b148, 0x3a3bae00, 0xbe19a60a, 0x3d64ada0, 0x3e4d6418, 0x3e1735dc, 0x3e6bc304, 0x3ed76812, 0xbeda1e9d, 0xbcc9dc90, 0xbe8b56d8, 0xbde3f398, 0x3e9a494e, 0xbc03b300, 0x3d898450, 0x3ecfc37a, 0x3ca54f60, 0xbe47ad20, 0xbeac6e30, 0xbe3b8b06, 0x3e9cea58, 0x3d85a140, 0xbde68434, 0xbeb09ec1, 0x3e87de1e, 0xbec116de, 0x3dd939f0, 0xbe18ef8e, 0x3df90638, 0x3dc5e080, 0xbe94b2a7, 0xbe9a126e, 0xbdfff1d8, 0xbe58ace5, 0xbe807ef0, 0xbd506310, 0xbeb9158a, 0x3e074a8c, 0xbe574539, 0xbecc25a9, 0x3e0332e4, 0x3eb682ba, 0x3ebc395c, 0xbed87cba, 0x3ec8c806, 0x3c696e40, 0x3d952498}; uint32_t biases0_shape[] = {2, 5}; uint32_t biases0_values[] = { 0x3c9a1ea0, 0x3e9399fc, 0xbead15e7, 0xbe9d3169, 0xbe84f4be, 0x3ed6d390, 0x3eb76f78, 0xbecc7bce, 0xbe9c4230, 0xbd93fe10, 0xbe7c17a9, 0xbe856c8e, 0x3e1c8044, 0xbe8872c0, 0xbc1fdba0, 0xbe9aebe8, 0xbee1e40d, 0xbeb7e0dd, 0x3eb4c482, 0x3e77c3f8, 0x3ea04420, 0xbe249da6, 0x3ec122ee, 0x3e2598d4, 0x3d67f3b0, 0xbe94b3e4, 0x3e9eff90, 0xbead1b0c, 0xbe5f6ed0, 0xbedd358e}; uint32_t hidden_weights0_shape[] = {2, 5, 5}; uint32_t hidden_weights0_values[] = { 0xbe591a24, 0xbed64902, 0xbedcd447, 0xbdb06a40, 0x3bbd8300, 0x3e9be8be, 0xbec14162, 0x3e8ed458, 0xbdb3d438, 0xbe5008a0, 0xbb3dfe00, 0xbdb9c6e0, 0xbeb32c7f, 0xbecd7820, 0x3e2c8218, 0xbe639ee9, 0x3e7b2408, 0xbdc1a118, 0xbec5b44b, 0xbece16e2, 0xbeaf7709, 0x3e7795b4, 0xbe39af54, 0xbd8f518c, 0xbcf73e90, 0xbebbb5a4, 0x3e987cda, 0x3d190310, 0x3ece54c0, 0xbebdbf60, 0xbd8d3050, 0xbe6f1e1b, 0x3d64ba10, 0x3e86944e, 0xbec4e626, 0x3e1f0c64, 0x3b9084c0, 0xbeb401c3, 0x3d757710, 0x3ee46d12, 0xbe271822, 0x3e3d5c4c, 0x3d0ff4f8, 0x3e55de1c, 0x3e915990, 0x3e2dd3f4, 0x3d0f9250, 0x3e9e8ea0, 0xbe5ec821, 0xbe9e462c, 0x3e33b614, 0xbe87b6cc, 0xbdc2d30c, 0xbd3c4ee0, 0x3ed8e4e6, 0x3cdb72e0, 0xbde54684, 0x3dc3c730, 0x3c4ba340, 0x3e916930, 0xbe5f7204, 0xbe5f126c, 0xbe952b16, 0xbd1e06b8, 0x3ed963f2, 0x3e58b204, 0xbe20347e, 0xbcbc0320, 0x3db95c18, 0xbd047a58, 0xbedba477, 0xbebbabe9, 0x3ea3e928, 0x3e91971e, 0xbecdb113, 0x3ebdf640, 0xbe8b7474, 0xbe8d2560, 0xbe5cf1d4, 0xbeaa02a3, 0xbe1985b8, 0x3e1ae0c4, 0x3e9e5868, 0x3da48928, 0x3d987eb0, 0x3e06e404, 0x3e10c984, 0xbeaa740b, 0xbe6de235, 0x3e430d88, 0xbdd1716c, 0xbc172600, 0x3e3b9ae0, 0x3dd306b8, 0x3e354500, 0xbca2ec60, 0xbdcdfc84, 0xbe19fc78, 0x3db3dd28, 0xbd669538, 0x3ec95d16, 0x3e90def0, 0x3d448f50, 0x3e21ba5c, 0x3eb5ccc2, 0xbe3acaf4, 0xbd5360c8, 0xbdbfc268, 0xbddc3fcc, 0x3e9cab54, 0x3ecec37e, 0xbe4c6e38, 0x3ea38344, 0xbdc09e0c, 0xbea1834a, 0x3e25d8dc, 0x3eb7196c, 0x3dffaaa8, 0xbebcb154, 0x3ca36520, 0xbecea3b7, 0xbeb90843, 0x3e5c0bbc, 0x3e7822c0, 0xbea16940, 0x3e332b14, 0xbdd1fa20, 0x3ecdd9da, 0xbe2089f6, 0x3e42d780, 0x3eace9cc, 0xbe20b66c, 0x3e5d42c8, 0x3eb2e8ec, 0xbe1b9f76, 0x3ee4e29a, 0x3ebbff92, 0x3e79a49c, 0xbda4ce70, 0x3e5f481c, 0x3ec83690, 0x3e804fe0, 0xbe8f83dc, 0x3e3248cc, 0xbe9fee66, 0x3eb165e2, 0xbe89ca96, 0x3e036284, 0x3da2aec0, 0x3dcedbf0}; uint32_t hidden_biases0_shape[] = {2, 5}; uint32_t hidden_biases0_values[] = { 0x3d69b920, 0xbeb31aa8, 0xbe700636, 0x3eb8e4f2, 0xbeb9d294, 0x3ecb999a, 0xbdea86c4, 0x3e497f5c, 0x3ecbffd4, 0x3e177f54, 0xbb5a2c80, 0xbdb50e24, 0x3d65d3e0, 0xbdd123b0, 0xbb4def80, 0xbe81ffa5, 0x3ebc5350, 0x3ebb7968, 0x3ea3e864, 0x3eb0cbec, 0xbd0388a0, 0x3ee28262, 0x3e256d64, 0x3c4f7420, 0xbec66e3b, 0x3ee4e636, 0x3e6d851c, 0x3e8e5746, 0xbe20471c, 0x3e5bbc44}; uint32_t all_ts_out0_shape[] = {5, 2, 2, 5}; uint32_t all_ts_out0_exp_values[] = { 0x3ef5b84b, 0xbdc926d0, 0x3f497c28, 0xbdfc36e0, 0x3e607fa7, 0x3f82f3c5, 0xbe8cee08, 0x3f14bc02, 0x3f188fa6, 0x3e241ab6, 0x3eac5206, 0xbedcec07, 0xbe3aac82, 0xbefbfe4a, 0x3d0ad0f8, 0xbda044a0, 0xbbf714b4, 0xbee36d2e, 0xbee0ad51, 0xbe2f3894, 0x3f13e1fa, 0xbf189b8e, 0x3f2c5fec, 0x3dc15418, 0xbc762fd0, 0x3f76bfe3, 0xbf2b3644, 0x3f21d8d1, 0x3ede3af5, 0xbc315408, 0x3e8d057a, 0xbeb31b94, 0xbe3ae016, 0xbefdfa09, 0xbc714a80, 0x3e15b5fa, 0xbd251f38, 0xbec45527, 0xbe918512, 0xbb884180, 0x3ef72c4b, 0xbf41095a, 0x3f193819, 0x3e22c8d5, 0xbc6dc4e6, 0x3f42b484, 0xbf1bf022, 0x3eedea11, 0x3eb9245f, 0xbdfb31b3, 0x3ecf949d, 0xbea0e868, 0xbde5266b, 0xbecc0f8c, 0x3d2635b8, 0x3ed43076, 0x3e94113c, 0xbe8f5d00, 0x3e26030d, 0x3e5ae9d3, 0x3f3f74e5, 0xbf47bebc, 0x3f40cc76, 0xbe345ea9, 0xbd596022, 0x3f5486e7, 0xbf33d933, 0x3edef9ca, 0x3ee99606, 0xbe2fe4f9, 0x3ec22476, 0xbe846bbc, 0x3ec65d70, 0xbebc0ca3, 0xbd2b4ab0, 0x3f239afa, 0x3ee52450, 0xbdbb9c94, 0x3f011b6e, 0x3ef79e50, 0x3f51084e, 0xbf65575e, 0x3f388490, 0x3debd8da, 0xbcaa7ed3, 0x3f58d051, 0xbf2f19e6, 0x3f027aa7, 0x3d9a45a2, 0xbe5edb76, 0x3edce200, 0xbe25588a, 0xbde12298, 0xbce7e6a0, 0x3e6c86cc, 0x3f932f62, 0x3f32daf3, 0x3f4d9d22, 0x3f9152b4, 0x3f61d3b8}; zdnn_ztensor *input0 = alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (void *)input0_values); zdnn_ztensor *all_ts_out0 = test_layer( input0, h00_shape, (void *)h00_values, weights0_shape, (void *)weights0_values, biases0_shape, (void *)biases0_values, hidden_weights0_shape, (void *)hidden_weights0_values, hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape, (void *)all_ts_out0_exp_values, false, is_layer_bidir[0]); // second layer uint32_t h01_shape[] = {1, 2, 4}; uint32_t h01_values[] = {0x3f62957c, 0x3f9e9191, 0x3fc827a5, 0x3fc7d2ab, 0x3fe27e59, 0x3ea84764, 0x3e9400d4, 0x3f8e916a}; uint32_t weights1_shape[] = {1, 10, 4}; uint32_t weights1_values[] = { 0x3e7e5dec, 0x3cbaca20, 0xbecd44ac, 0xbec67b5a, 0xbee86a24, 0xbee6d710, 0xbe1343c8, 0xbe1df5e4, 0xbef61752, 0x3ed44ee8, 0xbefb5c54, 0x3e60bf20, 0xbef8bec0, 0x3e89d76e, 0xbe476b90, 0x3efc847a, 0xbdcfbb68, 0x3efe7680, 0x3ddce8a0, 0x3e93351a, 0x3eac2490, 0x3e815596, 0xbec9005c, 0xbd669fb0, 0xbef24c72, 0xbea8fa48, 0x3e233510, 0x3e338400, 0x3ed4c8ae, 0x3ed5a748, 0x3e896c2c, 0xbefb26f0, 0xbe4ccfcc, 0x3cdc2320, 0x3d8ea718, 0xbedaa662, 0x3e15f4e8, 0x3e72cc80, 0xbeab490c, 0x3e6ee73c, 0xbe9424c4, 0xbe3a9e8c, 0x3d43feb0, 0xbe5a7688, 0x3ec5dd22, 0x3e8fe95c, 0x3eecc1a2, 0x3e387860, 0x3ea3b58c, 0xbe9174d6, 0x3cdb4d20, 0xbeb5cb18, 0x3d183c70, 0xbda079b8, 0xbe9e108c, 0x3e3e52fc, 0xbe71bbb8, 0x3ed95eb2, 0x3cd1f000, 0x3ed94986, 0x3eeb46b8, 0x3ca93e40, 0x3e757f58, 0x3d065330, 0x3e5160ac, 0xbeb50c40, 0x3e7df8fc, 0xbeaa9ef0, 0xbec2575a, 0xbe2b2094, 0xbee9f7e0, 0xbe377120, 0x3ef50362, 0xbe0afadc, 0xbdb73cb0, 0x3ddf9ad8, 0x3ec26652, 0xbdc58f20, 0xbebe3eb8, 0xbec32746, 0xbe910096, 0x3c83b620, 0x3ee2836a, 0xbe174ae8, 0x3e76522c, 0xbe1e4c94, 0x3eea1e74, 0x3e2b57a8, 0xbeb4b7f8, 0xbddea668, 0xbeed20aa, 0xbe134f2c, 0xbe7d9964, 0x3d881718, 0x3eb48e6e, 0x3e9e4660, 0xbed2dd48, 0x3e7dcda4, 0x3e804bf8, 0xbe0e0e88, 0x3e85975a, 0xbeb359dc, 0x3e9787f8, 0xbe3edf14, 0xbd50ae60, 0x3ed6daea, 0x3ed8b624, 0x3e00e540, 0x3ec50494, 0xbd5eade0, 0xbe89f8a6, 0x3e359a68, 0x3e9e6e68, 0xbed6839a, 0x3e21ad5c, 0xbe7a2610, 0x3e8da7dc, 0xbe8a82c4, 0x3e518704, 0x3d350a30}; uint32_t biases1_shape[] = {1, 4}; uint32_t biases1_values[] = {0x3ed91e6a, 0x3e9414ee, 0xbe1b5134, 0xbea9d954, 0xbde41328, 0xbdb7df18, 0x3ec89742, 0x3e80aae6, 0xbd1860a0, 0x3ed3e00e, 0xbe2bd65c, 0xbeed681e}; uint32_t hidden_weights1_shape[] = {1, 4, 4}; uint32_t hidden_weights1_values[] = { 0xbec20bd4, 0xbe37a3e0, 0xbdead1c8, 0xbead1388, 0xbb1e0800, 0x3dc17718, 0xbe7818b0, 0x3cbe3200, 0xbe0282c4, 0xbe85c1f4, 0x3d8caec8, 0xbe3ccf20, 0xbea7904e, 0x3de2e688, 0x3ed27f84, 0x3efb36e4, 0x3e945c74, 0x3e3374b0, 0x3eeb444c, 0x3eff8ff0, 0xbd4bc4f0, 0xbeb971e6, 0xbe09c564, 0x3efa070e, 0x3e1bd1a8, 0xbe96890e, 0xbab2f000, 0xbec11260, 0xbdf6f9b8, 0xbe81f174, 0xbe780fcc, 0xbecf8810, 0xbef2e226, 0x3dc45320, 0x3ea2ac3c, 0xbe2e8a7c, 0xbef56ad2, 0xbd30c140, 0x3cc3c6c0, 0x3e80d2ca, 0x3efc4230, 0xbdd7b678, 0xbef93ece, 0xbea5aa8e, 0xbea1f7f8, 0xbde4b548, 0xbe9721d8, 0x3ef1632e}; uint32_t hidden_biases1_shape[] = {1, 4}; uint32_t hidden_biases1_values[] = { 0xbee83510, 0x3e004e90, 0xbd1b12f0, 0xbe8146d8, 0x3e51e224, 0x3ef9356c, 0xbe11c200, 0xbed3f95a, 0x3dcefba8, 0x3e426fc0, 0x3ecb9a06, 0x3ec6c0fc}; uint32_t all_ts_out1_shape[] = {5, 1, 2, 4}; uint32_t all_ts_out1_exp_values[] = { 0xbe93b296, 0x3f6c52a6, 0x3df2ed90, 0x3ef58c75, 0xbedbef50, 0x3eed420e, 0x3ec9725f, 0x3ec154ec, 0xbeeff3f1, 0x3f4f798a, 0xbe9a656d, 0x3d7b8358, 0xbf152f9e, 0x3ef51830, 0x3cccae54, 0xbd1913d8, 0xbf05fe08, 0x3f3bc79e, 0xbeb73f4b, 0xbe1f8736, 0xbefd88cc, 0x3ee483a5, 0x3e477805, 0xbe95932c, 0xbf043d99, 0x3f2ccf54, 0xbefa4aaa, 0xbebf8337, 0xbe99bc9a, 0x3ebeeba4, 0x3ec71822, 0xbef39d98, 0xbf09c6e7, 0x3f1c7ff1, 0xbe53e20e, 0xbef9fb1e, 0x3cfaaa80, 0x3e6a580a, 0x3ee7dd5b, 0xbf2cbac5}; zdnn_ztensor *all_ts_out1 = test_layer( all_ts_out0, h01_shape, (void *)h01_values, weights1_shape, (void *)weights1_values, biases1_shape, (void *)biases1_values, hidden_weights1_shape, (void *)hidden_weights1_values, hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape, (void *)all_ts_out1_exp_values, is_layer_bidir[0], is_layer_bidir[1]); free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1); } int main() { UNITY_BEGIN(); #ifdef TEST_AIU RUN_TEST_ALL_DATATYPES(gru_fwd_to_fwd); RUN_TEST_ALL_DATATYPES(gru_fwd_to_bidir); RUN_TEST_ALL_DATATYPES(gru_bidir_to_bidir); RUN_TEST_ALL_DATATYPES(gru_bidir_to_fwd); #endif return UNITY_END(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_gru_rnn.c����������������������������������������������������������0000664�0000000�0000000�00000074762�14364043643�0020575�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_rnn.h" /****************************************************************************** default_input ******************************************************************************/ uint32_t default_input_shape[] = {5, 2, 4}; /* Visualization of values in shape (timestep, batch, feature) order [ [ # timestep_0 [.000, .001, .002, .003], # batch_0 [.010, .011, .012, .013], # batch_1 # feat_0 feat_1 feat_2 feat_3 ], [ # timestep_1 [.100, .101, .102, .103], # batch_0 [.110, .111, .112, .113], # batch 1 # feat_0 feat_1 feat_2 feat_3 ], [ # timestep_2 [.200, .201, .202, .203], # batch_0 [.210, .211, .212, .213], # batch_1 # feat_0 feat_1 feat_2 feat_3 ], [ # timestep_3 [.300, .301, .302, .303], # batch_0 [.310, .311, .312, .313], # batch_1 # feat_0 feat_1 feat_2 feat_3 ], [ # timestep_4 [.400, .401, .402, .403], # batch_0 [.410, .411, .412, .413], # batch_1 # feat_0 feat_1 feat_2 feat_3 ], ] */ float default_input_values[] = { 0.0, 0.001, 0.002, 0.003, 0.01, 0.011, 0.012, 0.013, 0.1, 0.101, 0.102, 0.103, 0.11, 0.111, 0.112, 0.113, 0.2, 0.201, 0.202, 0.203, 0.21, 0.211, 0.212, 0.213, 0.3, 0.301, 0.302, 0.303, 0.31, 0.311, 0.312, 0.313, 0.4, 0.401, 0.402, 0.403, 0.41, 0.411, 0.412, 0.413}; /****************************************************************************** default_uni_h0 ******************************************************************************/ uint32_t default_uni_h0_shape[] = {1, 2, 3}; /* Visualization of values in shape order [[[0. 0. 0.] [0. 0. 0.]]] */ float default_uni_h0_values[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; /****************************************************************************** default_uni_input_weights ******************************************************************************/ uint32_t default_uni_input_weights_shape[] = {1, 4, 3}; /* Visualization of z concatenation values in shape order [[[-0.4937358 0.5553266 0.1960275] [ 0.1839888 0.1733883 -0.2754271] [ 0.2482673 -0.5119551 -0.5303364] [ 0.0915996 0.4851032 0.329131 ]]] */ float default_uni_input_weights_z_values[] = { -0.4937358, 0.5553266, 0.1960275, 0.1839888, 0.1733883, -0.2754271, 0.2482673, -0.5119551, -0.5303364, 0.0915996, 0.4851032, 0.329131}; /* Visualization of r concatenation values in shape order [[[ 0.381342 0.4850937 -0.5389395] [-0.4317299 -0.44266 0.5706354] [ 0.4705055 -0.3875273 0.1228931] [ 0.3694199 0.2747256 0.0745605]]] */ float default_uni_input_weights_r_values[] = { 0.381342, 0.4850937, -0.5389395, -0.4317299, -0.44266, 0.5706354, 0.4705055, -0.3875273, 0.1228931, 0.3694199, 0.2747256, 0.0745605}; /* Visualization of h concatenation values in shape order [[[ 0.548669 -0.2726471 -0.5263513] [-0.4730297 -0.1263285 -0.0133806] [ 0.0315526 -0.385514 0.3423259] [ 0.2071373 -0.2729528 0.2808076]]] */ float default_uni_input_weights_h_values[] = { 0.548669, -0.2726471, -0.5263513, -0.4730297, -0.1263285, -0.0133806, 0.0315526, -0.385514, 0.3423259, 0.2071373, -0.2729528, 0.2808076}; /****************************************************************************** default_uni_input_biases ******************************************************************************/ uint32_t default_uni_input_biases_shape[] = {1, 3}; /* Visualization of z concatenation values in shape order [[0.0643551 0.2632221 0.4282453]] */ float default_uni_input_biases_z_values[] = {0.0643551, 0.2632221, 0.4282453}; /* Visualization of r concatenation values in shape order [[-0.1866051 -0.392639 0.4665768]] */ float default_uni_input_biases_r_values[] = {-0.1866051, -0.392639, 0.4665768}; /* Visualization of h concatenation values in shape order [[-0.3741214 0.4407408 -0.2892259]] */ float default_uni_input_biases_h_values[] = {-0.3741214, 0.4407408, -0.2892259}; /****************************************************************************** default_uni_hidden_weights ******************************************************************************/ uint32_t default_uni_hidden_weights_shape[] = {1, 3, 3}; /* Visualization of z concatenation values in shape order [[[ 0.4629621 0.4114995 -0.049397 ] [ 0.4833339 -0.1453276 -0.1190602] [ 0.113032 0.4688771 -0.2869941]]] */ float default_uni_hidden_weights_z_values[] = { 0.4629621, 0.4114995, -0.049397, 0.4833339, -0.1453276, -0.1190602, 0.113032, 0.4688771, -0.2869941}; /* Visualization of r concatenation values in shape order [[[ 0.5423677 0.5621256 -0.5199673] [-0.5070595 0.0945408 0.2686667] [-0.0710383 -0.1628114 0.4383084]]] */ float default_uni_hidden_weights_r_values[] = { 0.5423677, 0.5621256, -0.5199673, -0.5070595, 0.0945408, 0.2686667, -0.0710383, -0.1628114, 0.4383084}; /* Visualization of h concatenation values in shape order [[[ 0.3073992 -0.3689663 -0.3204532] [ 0.233599 -0.3069769 -0.3292732] [ 0.3672419 0.5463605 -0.1544762]]] */ float default_uni_hidden_weights_h_values[] = { 0.3073992, -0.3689663, -0.3204532, 0.233599, -0.3069769, -0.3292732, 0.3672419, 0.5463605, -0.1544762}; /****************************************************************************** default_uni_hidden_biases ******************************************************************************/ uint32_t default_uni_hidden_biases_shape[] = {1, 3}; /* Visualization of z concatenation values in shape order [[0.5068286 0.3320496 0.5366269]] */ float default_uni_hidden_biases_z_values[] = {0.5068286, 0.3320496, 0.5366269}; /* Visualization of r concatenation values in shape order [[-0.0919193 0.4369227 0.5323023]] */ float default_uni_hidden_biases_r_values[] = {-0.0919193, 0.4369227, 0.5323023}; /* Visualization of h concatenation values in shape order [[-0.2080224 -0.0367477 -0.1974721]] */ float default_uni_hidden_biases_h_values[] = {-0.2080224, -0.0367477, -0.1974721}; /****************************************************************************** default_bidir_h0 ******************************************************************************/ uint32_t default_bidir_h0_shape[] = {2, 2, 3}; /* Visualization of values in shape order [[[0. 0. 0.] [0. 0. 0.]] [[0. 0. 0.] [0. 0. 0.]]] */ float default_bidir_h0_values[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; /****************************************************************************** default_bidir_input_weights ******************************************************************************/ uint32_t default_bidir_input_weights_shape[] = {2, 4, 3}; /* Visualization of z concatenation values in shape order [[[-0.4937358 0.5553266 0.1960275] [ 0.1839888 0.1733883 -0.2754271] [ 0.2482673 -0.5119551 -0.5303364] [ 0.0915996 0.4851032 0.329131 ]] [[-0.4937358 0.5553266 0.1960275] [ 0.1839888 0.1733883 -0.2754271] [ 0.2482673 -0.5119551 -0.5303364] [ 0.0915996 0.4851032 0.329131 ]]] */ float default_bidir_input_weights_z_values[] = { -0.4937358, 0.5553266, 0.1960275, 0.1839888, 0.1733883, -0.2754271, 0.2482673, -0.5119551, -0.5303364, 0.0915996, 0.4851032, 0.329131, -0.4937358, 0.5553266, 0.1960275, 0.1839888, 0.1733883, -0.2754271, 0.2482673, -0.5119551, -0.5303364, 0.0915996, 0.4851032, 0.329131}; /* Visualization of r concatenation values in shape order [[[ 0.381342 0.4850937 -0.5389395] [-0.4317299 -0.44266 0.5706354] [ 0.4705055 -0.3875273 0.1228931] [ 0.3694199 0.2747256 0.0745605]] [[ 0.381342 0.4850937 -0.5389395] [-0.4317299 -0.44266 0.5706354] [ 0.4705055 -0.3875273 0.1228931] [ 0.3694199 0.2747256 0.0745605]]] */ float default_bidir_input_weights_r_values[] = { 0.381342, 0.4850937, -0.5389395, -0.4317299, -0.44266, 0.5706354, 0.4705055, -0.3875273, 0.1228931, 0.3694199, 0.2747256, 0.0745605, 0.381342, 0.4850937, -0.5389395, -0.4317299, -0.44266, 0.5706354, 0.4705055, -0.3875273, 0.1228931, 0.3694199, 0.2747256, 0.0745605}; /* Visualization of h concatenation values in shape order [[[ 0.548669 -0.2726471 -0.5263513] [-0.4730297 -0.1263285 -0.0133806] [ 0.0315526 -0.385514 0.3423259] [ 0.2071373 -0.2729528 0.2808076]] [[ 0.548669 -0.2726471 -0.5263513] [-0.4730297 -0.1263285 -0.0133806] [ 0.0315526 -0.385514 0.3423259] [ 0.2071373 -0.2729528 0.2808076]]] */ float default_bidir_input_weights_h_values[] = { 0.548669, -0.2726471, -0.5263513, -0.4730297, -0.1263285, -0.0133806, 0.0315526, -0.385514, 0.3423259, 0.2071373, -0.2729528, 0.2808076, 0.548669, -0.2726471, -0.5263513, -0.4730297, -0.1263285, -0.0133806, 0.0315526, -0.385514, 0.3423259, 0.2071373, -0.2729528, 0.2808076}; /****************************************************************************** default_bidir_input_biases ******************************************************************************/ uint32_t default_bidir_input_biases_shape[] = {2, 3}; /* Visualization of z concatenation values in shape order [[0.0643551 0.2632221 0.4282453] [0.0643551 0.2632221 0.4282453]] */ float default_bidir_input_biases_z_values[] = {0.0643551, 0.2632221, 0.4282453, 0.0643551, 0.2632221, 0.4282453}; /* Visualization of r concatenation values in shape order [[-0.1866051 -0.392639 0.4665768] [-0.1866051 -0.392639 0.4665768]] */ float default_bidir_input_biases_r_values[] = { -0.1866051, -0.392639, 0.4665768, -0.1866051, -0.392639, 0.4665768}; /* Visualization of h concatenation values in shape order [[-0.3741214 0.4407408 -0.2892259] [-0.3741214 0.4407408 -0.2892259]] */ float default_bidir_input_biases_h_values[] = { -0.3741214, 0.4407408, -0.2892259, -0.3741214, 0.4407408, -0.2892259}; /****************************************************************************** default_bidir_hidden_weights ******************************************************************************/ uint32_t default_bidir_hidden_weights_shape[] = {2, 3, 3}; /* Visualization of z concatenation values in shape order [[[ 0.4629621 0.4114995 -0.049397 ] [ 0.4833339 -0.1453276 -0.1190602] [ 0.113032 0.4688771 -0.2869941]] [[ 0.4629621 0.4114995 -0.049397 ] [ 0.4833339 -0.1453276 -0.1190602] [ 0.113032 0.4688771 -0.2869941]]] */ float default_bidir_hidden_weights_z_values[] = { 0.4629621, 0.4114995, -0.049397, 0.4833339, -0.1453276, -0.1190602, 0.113032, 0.4688771, -0.2869941, 0.4629621, 0.4114995, -0.049397, 0.4833339, -0.1453276, -0.1190602, 0.113032, 0.4688771, -0.2869941}; /* Visualization of r concatenation values in shape order [[[ 0.5423677 0.5621256 -0.5199673] [-0.5070595 0.0945408 0.2686667] [-0.0710383 -0.1628114 0.4383084]] [[ 0.5423677 0.5621256 -0.5199673] [-0.5070595 0.0945408 0.2686667] [-0.0710383 -0.1628114 0.4383084]]] */ float default_bidir_hidden_weights_r_values[] = { 0.5423677, 0.5621256, -0.5199673, -0.5070595, 0.0945408, 0.2686667, -0.0710383, -0.1628114, 0.4383084, 0.5423677, 0.5621256, -0.5199673, -0.5070595, 0.0945408, 0.2686667, -0.0710383, -0.1628114, 0.4383084}; /* Visualization of h concatenation values in shape order [[[ 0.3073992 -0.3689663 -0.3204532] [ 0.233599 -0.3069769 -0.3292732] [ 0.3672419 0.5463605 -0.1544762]] [[ 0.3073992 -0.3689663 -0.3204532] [ 0.233599 -0.3069769 -0.3292732] [ 0.3672419 0.5463605 -0.1544762]]] */ float default_bidir_hidden_weights_h_values[] = { 0.3073992, -0.3689663, -0.3204532, 0.233599, -0.3069769, -0.3292732, 0.3672419, 0.5463605, -0.1544762, 0.3073992, -0.3689663, -0.3204532, 0.233599, -0.3069769, -0.3292732, 0.3672419, 0.5463605, -0.1544762}; /****************************************************************************** default_bidir_hidden_biases ******************************************************************************/ uint32_t default_bidir_hidden_biases_shape[] = {2, 3}; /* Visualization of z concatenation values in shape order [[0.5068286 0.3320496 0.5366269] [0.5068286 0.3320496 0.5366269]] */ float default_bidir_hidden_biases_z_values[] = { 0.5068286, 0.3320496, 0.5366269, 0.5068286, 0.3320496, 0.5366269}; /* Visualization of r concatenation values in shape order [[-0.0919193 0.4369227 0.5323023] [-0.0919193 0.4369227 0.5323023]] */ float default_bidir_hidden_biases_r_values[] = { -0.0919193, 0.4369227, 0.5323023, -0.0919193, 0.4369227, 0.5323023}; /* Visualization of h concatenation values in shape order [[-0.2080224 -0.0367477 -0.1974721] [-0.2080224 -0.0367477 -0.1974721]] */ float default_bidir_hidden_biases_h_values[] = { -0.2080224, -0.0367477, -0.1974721, -0.2080224, -0.0367477, -0.1974721}; /****************************************************************************** default_fwd_exp_hn_out_all_ts ******************************************************************************/ uint32_t default_fwd_hn_out_all_ts_shape[] = {5, 1, 2, 3}; /* Visualization of values in shape order [[[-0.1562103 0.1410986 -0.1123356] [-0.1553763 0.1372994 -0.1123919]] [[-0.253498 0.1940096 -0.1891814] [-0.2523776 0.1878957 -0.1889893]] [[-0.3126792 0.1866586 -0.2388406] [-0.3114854 0.179318 -0.2382826]] [[-0.3473134 0.1435677 -0.2676416] [-0.3461194 0.1356744 -0.2667077]] [[-0.3660706 0.0814286 -0.2807784] [-0.3648955 0.0733736 -0.2795098]]] */ float default_fwd_exp_hn_out_all_ts_values[] = { -0.1562103, 0.1410986, -0.1123356, -0.1553763, 0.1372994, -0.1123919, -0.253498, 0.1940096, -0.1891814, -0.2523776, 0.1878957, -0.1889893, -0.3126792, 0.1866586, -0.2388406, -0.3114854, 0.179318, -0.2382826, -0.3473134, 0.1435677, -0.2676416, -0.3461194, 0.1356744, -0.2667077, -0.3660706, 0.0814286, -0.2807784, -0.3648955, 0.0733736, -0.2795098}; /****************************************************************************** default_fwd_exp_hn_out_final_ts ******************************************************************************/ uint32_t default_fwd_hn_out_final_ts_shape[] = {1, 1, 2, 3}; /* Visualization of values in shape order [[[-0.3660706 0.0814286 -0.2807784] [-0.3648955 0.0733736 -0.2795098]]] */ float default_fwd_exp_hn_out_final_ts_values[] = { -0.3660706, 0.0814286, -0.2807784, -0.3648955, 0.0733736, -0.2795098}; /****************************************************************************** default_bwd_exp_hn_out_all_ts ******************************************************************************/ uint32_t default_bwd_hn_out_all_ts_shape[] = {5, 1, 2, 3}; /* Visualization of values in shape order [[[-0.4037485 0.2564563 -0.2790346] [-0.4026485 0.2477951 -0.2778324]] [[-0.3612258 0.1689991 -0.2550354] [-0.3600727 0.1606691 -0.2541449]] [[-0.3028114 0.0906047 -0.224893 ] [-0.3015861 0.083261 -0.2243577]] [[-0.223746 0.0309375 -0.1819546] [-0.2225393 0.025346 -0.1817581]] [[-0.1217477 -0.0007261 -0.1141484] [-0.1208584 -0.0038126 -0.1141814]]] */ float default_bwd_exp_hn_out_all_ts_values[] = { -0.4037485, 0.2564563, -0.2790346, -0.4026485, 0.2477951, -0.2778324, -0.3612258, 0.1689991, -0.2550354, -0.3600727, 0.1606691, -0.2541449, -0.3028114, 0.0906047, -0.224893, -0.3015861, 0.083261, -0.2243577, -0.223746, 0.0309375, -0.1819546, -0.2225393, 0.025346, -0.1817581, -0.1217477, -0.0007261, -0.1141484, -0.1208584, -0.0038126, -0.1141814}; /****************************************************************************** default_bwd_exp_hn_out_final_ts ******************************************************************************/ uint32_t default_bwd_hn_out_final_ts_shape[] = {1, 1, 2, 3}; /* Visualization of values in shape order [[[-0.4037485 0.2564563 -0.2790346] [-0.4026485 0.2477951 -0.2778324]]] */ float default_bwd_exp_hn_out_final_ts_values[] = { -0.4037485, 0.2564563, -0.2790346, -0.4026485, 0.2477951, -0.2778324}; /****************************************************************************** default_bidir_exp_hn_out_all_ts ******************************************************************************/ uint32_t default_bidir_hn_out_all_ts_shape[] = {5, 2, 2, 3}; /* Visualization of values in shape order [[[-0.1562103 0.1410986 -0.1123356 -0.1553763 0.1372994 -0.1123919] [-0.4037485 0.2564563 -0.2790346 -0.4026485 0.2477951 -0.2778324]] [[-0.253498 0.1940096 -0.1891814 -0.2523776 0.1878956 -0.1889893] [-0.3612258 0.1689991 -0.2550354 -0.3600727 0.1606691 -0.2541449]] [[-0.3126791 0.1866586 -0.2388406 -0.3114854 0.179318 -0.2382826] [-0.3028114 0.0906047 -0.2248929 -0.3015861 0.083261 -0.2243577]] [[-0.3473134 0.1435677 -0.2676416 -0.3461194 0.1356744 -0.2667077] [-0.223746 0.0309375 -0.1819546 -0.2225393 0.025346 -0.1817581]] [[-0.3660705 0.0814286 -0.2807783 -0.3648955 0.0733736 -0.2795098] [-0.1217477 -0.0007261 -0.1141484 -0.1208584 -0.0038126 -0.1141814]]] */ float default_bidir_exp_hn_out_all_ts_values[] = { -0.1562103, 0.1410986, -0.1123356, -0.1553763, 0.1372994, -0.1123919, -0.4037485, 0.2564563, -0.2790346, -0.4026485, 0.2477951, -0.2778324, -0.253498, 0.1940096, -0.1891814, -0.2523776, 0.1878956, -0.1889893, -0.3612258, 0.1689991, -0.2550354, -0.3600727, 0.1606691, -0.2541449, -0.3126791, 0.1866586, -0.2388406, -0.3114854, 0.179318, -0.2382826, -0.3028114, 0.0906047, -0.2248929, -0.3015861, 0.083261, -0.2243577, -0.3473134, 0.1435677, -0.2676416, -0.3461194, 0.1356744, -0.2667077, -0.223746, 0.0309375, -0.1819546, -0.2225393, 0.025346, -0.1817581, -0.3660705, 0.0814286, -0.2807783, -0.3648955, 0.0733736, -0.2795098, -0.1217477, -0.0007261, -0.1141484, -0.1208584, -0.0038126, -0.1141814}; /****************************************************************************** default_bidir_exp_hn_out_final_ts ******************************************************************************/ uint32_t default_bidir_hn_out_final_ts_shape[] = {1, 2, 2, 3}; /* Visualization of values in shape order [[[-0.3660705 0.0814286 -0.2807783 -0.3648955 0.0733736 -0.2795098] [-0.4037485 0.2564563 -0.2790346 -0.4026485 0.2477951 -0.2778324]]] */ float default_bidir_exp_hn_out_final_ts_values[] = { -0.3660705, 0.0814286, -0.2807783, -0.3648955, 0.0733736, -0.2795098, -0.4037485, 0.2564563, -0.2790346, -0.4026485, 0.2477951, -0.2778324}; /****************************************************************************** Unity Methods ******************************************************************************/ void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } /****************************************************************************** Tests ******************************************************************************/ // Confirm that gru returns OK and expected values when set to return hn // results from all timesteps void gru_basic_fwd_hn_all() { test_zdnn_api_lstm_gru( NNPA_GRUACT, default_input_shape, ZDNN_3DS, default_input_values, default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, // The test method also supports LSTM which requires c0, pass in h0 again // as a stand-in for c0 which the test will ignore for GRU networks. default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_input_weights_shape, ZDNN_3DS, default_uni_input_weights_z_values, default_uni_input_weights_r_values, default_uni_input_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_input_biases_shape, ZDNN_2DS, default_uni_input_biases_z_values, default_uni_input_biases_r_values, default_uni_input_biases_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_hidden_weights_shape, ZDNN_3DS, default_uni_hidden_weights_z_values, default_uni_hidden_weights_r_values, default_uni_hidden_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_hidden_biases_shape, ZDNN_2DS, default_uni_hidden_biases_z_values, default_uni_hidden_biases_r_values, default_uni_hidden_biases_h_values, ZERO_ARRAY, default_fwd_hn_out_all_ts_shape, ZDNN_4DS, default_fwd_exp_hn_out_all_ts_values, // The test method also supports LSTM which requires cf, pass NULL for GRU NULL, ZDNN_3DS, NULL, FWD, ZDNN_OK); } // Confirm that gru returns OK and expected values when set to return only // the final hn result void gru_basic_fwd_hn_final() { test_zdnn_api_lstm_gru( NNPA_GRUACT, default_input_shape, ZDNN_3DS, default_input_values, default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, // The test method also supports LSTM which requires c0, pass in h0 again // as a stand-in for c0 which the test will ignore for GRU networks. default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_input_weights_shape, ZDNN_3DS, default_uni_input_weights_z_values, default_uni_input_weights_r_values, default_uni_input_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_input_biases_shape, ZDNN_2DS, default_uni_input_biases_z_values, default_uni_input_biases_r_values, default_uni_input_biases_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_hidden_weights_shape, ZDNN_3DS, default_uni_hidden_weights_z_values, default_uni_hidden_weights_r_values, default_uni_hidden_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_hidden_biases_shape, ZDNN_2DS, default_uni_hidden_biases_z_values, default_uni_hidden_biases_r_values, default_uni_hidden_biases_h_values, ZERO_ARRAY, default_fwd_hn_out_final_ts_shape, ZDNN_4DS, default_fwd_exp_hn_out_final_ts_values, // The test method also supports LSTM which requires cf, pass NULL for GRU NULL, ZDNN_3DS, NULL, FWD, ZDNN_OK); } // Confirm that gru returns OK and expected values when set to return hn // results from all timesteps void gru_basic_bwd_hn_all() { test_zdnn_api_lstm_gru( NNPA_GRUACT, default_input_shape, ZDNN_3DS, default_input_values, default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, // The test method also supports LSTM which requires c0, pass in h0 again // as a stand-in for c0 which the test will ignore for GRU networks. default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_input_weights_shape, ZDNN_3DS, default_uni_input_weights_z_values, default_uni_input_weights_r_values, default_uni_input_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_input_biases_shape, ZDNN_2DS, default_uni_input_biases_z_values, default_uni_input_biases_r_values, default_uni_input_biases_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_hidden_weights_shape, ZDNN_3DS, default_uni_hidden_weights_z_values, default_uni_hidden_weights_r_values, default_uni_hidden_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_hidden_biases_shape, ZDNN_2DS, default_uni_hidden_biases_z_values, default_uni_hidden_biases_r_values, default_uni_hidden_biases_h_values, ZERO_ARRAY, default_bwd_hn_out_all_ts_shape, ZDNN_4DS, default_bwd_exp_hn_out_all_ts_values, // The test method also supports LSTM which requires cf, pass NULL for GRU NULL, ZDNN_3DS, NULL, BWD, ZDNN_OK); } // Confirm that gru returns OK and expected values when set to return only // the final hn result void gru_basic_bwd_hn_final() { test_zdnn_api_lstm_gru( NNPA_GRUACT, default_input_shape, ZDNN_3DS, default_input_values, default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, // The test method also supports LSTM which requires c0, pass in h0 again // as a stand-in for c0 which the test will ignore for GRU networks. default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_input_weights_shape, ZDNN_3DS, default_uni_input_weights_z_values, default_uni_input_weights_r_values, default_uni_input_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_input_biases_shape, ZDNN_2DS, default_uni_input_biases_z_values, default_uni_input_biases_r_values, default_uni_input_biases_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_hidden_weights_shape, ZDNN_3DS, default_uni_hidden_weights_z_values, default_uni_hidden_weights_r_values, default_uni_hidden_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_uni_hidden_biases_shape, ZDNN_2DS, default_uni_hidden_biases_z_values, default_uni_hidden_biases_r_values, default_uni_hidden_biases_h_values, ZERO_ARRAY, default_bwd_hn_out_final_ts_shape, ZDNN_4DS, default_bwd_exp_hn_out_final_ts_values, // The test method also supports LSTM which requires cf, pass NULL for GRU NULL, ZDNN_3DS, NULL, BWD, ZDNN_OK); } // Confirm that gru returns OK and expected values when set to return hn // results from all timesteps void gru_basic_bidir_hn_all() { test_zdnn_api_lstm_gru( NNPA_GRUACT, default_input_shape, ZDNN_3DS, default_input_values, default_bidir_h0_shape, ZDNN_3DS, default_bidir_h0_values, // The test method also supports LSTM which requires c0, pass in h0 again // as a stand-in for c0 which the test will ignore for GRU networks. default_bidir_h0_shape, ZDNN_3DS, default_bidir_h0_values, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_bidir_input_weights_shape, ZDNN_3DS, default_bidir_input_weights_z_values, default_bidir_input_weights_r_values, default_bidir_input_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_bidir_input_biases_shape, ZDNN_2DS, default_bidir_input_biases_z_values, default_bidir_input_biases_r_values, default_bidir_input_biases_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_bidir_hidden_weights_shape, ZDNN_3DS, default_bidir_hidden_weights_z_values, default_bidir_hidden_weights_r_values, default_bidir_hidden_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_bidir_hidden_biases_shape, ZDNN_2DS, default_bidir_hidden_biases_z_values, default_bidir_hidden_biases_r_values, default_bidir_hidden_biases_h_values, ZERO_ARRAY, default_bidir_hn_out_all_ts_shape, ZDNN_4DS, default_bidir_exp_hn_out_all_ts_values, // The test method also supports LSTM which requires cf, pass NULL for GRU NULL, ZDNN_3DS, NULL, BIDIR, ZDNN_OK); } // Confirm that gru returns OK and expected values when set to return only // the final hn result void gru_basic_bidir_hn_final() { test_zdnn_api_lstm_gru( NNPA_GRUACT, default_input_shape, ZDNN_3DS, default_input_values, default_bidir_h0_shape, ZDNN_3DS, default_bidir_h0_values, // The test method also supports LSTM which requires c0, pass in h0 again // as a stand-in for c0 which the test will ignore for GRU networks. default_bidir_h0_shape, ZDNN_3DS, default_bidir_h0_values, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_bidir_input_weights_shape, ZDNN_3DS, default_bidir_input_weights_z_values, default_bidir_input_weights_r_values, default_bidir_input_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_bidir_input_biases_shape, ZDNN_2DS, default_bidir_input_biases_z_values, default_bidir_input_biases_r_values, default_bidir_input_biases_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_bidir_hidden_weights_shape, ZDNN_3DS, default_bidir_hidden_weights_z_values, default_bidir_hidden_weights_r_values, default_bidir_hidden_weights_h_values, ZERO_ARRAY, // The fourth gate isn't used for GRU so send ZERO_ARRAY default_bidir_hidden_biases_shape, ZDNN_2DS, default_bidir_hidden_biases_z_values, default_bidir_hidden_biases_r_values, default_bidir_hidden_biases_h_values, ZERO_ARRAY, default_bidir_hn_out_final_ts_shape, ZDNN_4DS, default_bidir_exp_hn_out_final_ts_values, // The test method also supports LSTM which requires cf, pass NULL for GRU NULL, ZDNN_3DS, NULL, BIDIR, ZDNN_OK); } int main() { UNITY_BEGIN(); // GRU tests with good input requires AIU to get results and // validate values. #ifdef TEST_AIU // FWD direction tests RUN_TEST_ALL_DATATYPES(gru_basic_fwd_hn_all); RUN_TEST_ALL_DATATYPES(gru_basic_fwd_hn_final); // BWD direction tests RUN_TEST_ALL_DATATYPES(gru_basic_bwd_hn_all); RUN_TEST_ALL_DATATYPES(gru_basic_bwd_hn_final); // BIDIR direction tests RUN_TEST_ALL_DATATYPES(gru_basic_bidir_hn_all); RUN_TEST_ALL_DATATYPES(gru_basic_bidir_hn_final); #endif return UNITY_END(); } ��������������zDNN-1.0.1/tests/testDriver_zdnn_log_elwise.c�������������������������������������������������������0000664�0000000�0000000�00000007720�14364043643�0021242�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_elwise.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} /* * Simple test to drive a full log api. */ void api_log_basic() { /* Input values as true NHWC sized (1,2,2,2) [[ [[3, 30], [6, 60]], [[8, 80], [3, 10]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {1, 2, 2, 2}; float input_values[] = {3, 30, 6, 60, 8, 80, 3, 10}; /* Expected values as true NHWC sized (1,2,2,2) [[ [[1.09861228, 3.40119738], [1.79175946, 4.09434456]], [[2.07944154, 4.38202663], [1.09861228, 2.30258509]] ]] */ test_elwise_api_1_input(shape, ZDNN_NHWC, input_values, NNPA_LOG, ZDNN_OK); } // test to drive input tensors with 280 values in their buffer. void api_log_med_dims() { uint32_t shape[] = {1, 7, 10, 4}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input_values); test_elwise_api_1_input(shape, ZDNN_NHWC, input_values, NNPA_LOG, ZDNN_OK); } // test to drive an input tensor with 6825 values in its buffer void api_log_high_dims() { uint32_t shape[] = {1, 3, 33, 65}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input_values); test_elwise_api_1_input(shape, ZDNN_NHWC, input_values, NNPA_LOG, ZDNN_OK); } /* * Simple test to drive a full log api using Data type and a * 3D layout */ void api_log_3D() { /* Input 1 values as true NHWC sized (1,2,2,2) [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2, 2}; float input_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Expected values as true NHWC sized (1,2,2,2) [[ [[1.09861228, 3.40119738], [1.79175946, 4.09434456]], [[2.07944154, 4.38202663], [2.19722457, 4.49980967]] ]] */ test_elwise_api_1_input(shape, ZDNN_3D, input_values, NNPA_LOG, ZDNN_OK); } /* * Simple test to drive a full log api using the data type * and 2 dimensional tensors */ void api_log_2D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[1, 10], [2, 6]] ]] */ float input_values[] = {1, 10, 2, 6}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[0, 2.30258509], [0.69314718, 1.79175946]] ]] */ test_elwise_api_1_input(shape, ZDNN_2D, input_values, NNPA_LOG, ZDNN_OK); } /* * Simple test to drive a full log api using the data type * and 1 dimensional tensors */ void api_log_1D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[6, 7]] ]] */ float input_values[] = {6, 7}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[1.79175946, 1.94591014]] ]] */ test_elwise_api_1_input(shape, ZDNN_1D, input_values, NNPA_LOG, ZDNN_OK); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(api_log_basic); RUN_TEST_ALL_DATATYPES(api_log_med_dims); RUN_TEST_ALL_DATATYPES(api_log_high_dims); RUN_TEST_ALL_DATATYPES(api_log_3D); RUN_TEST_ALL_DATATYPES(api_log_2D); RUN_TEST_ALL_DATATYPES(api_log_1D); return UNITY_END(); } ������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_lstm_dual_layers.c�������������������������������������������������0000664�0000000�0000000�00000176351�14364043643�0022463�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } zdnn_ztensor * test_layer(zdnn_ztensor *input, uint32_t *h0_shape, void *h0_values, uint32_t *c0_shape, void *c0_values, uint32_t *weights_shape, void *weights_values, uint32_t *biases_shape, void *biases_values, uint32_t *hidden_weights_shape, void *hidden_weights_values, uint32_t *hidden_biases_shape, void *hidden_biases_values, uint32_t *all_ts_out_shape, void *all_ts_out_exp_values, uint32_t *cell_out_shape, void *cell_out_exp_values, bool is_prev_layer_bidir, bool is_this_layer_bidir) { zdnn_ztensor *h0, *c0, *weights, *biases, *hidden_weights, *hidden_biases, *all_ts_out, *cell_out; h0 = alloc_ztensor_with_values(h0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (float *)h0_values); c0 = alloc_ztensor_with_values(c0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (float *)c0_values); // FICO/ZRH elements coming in as one pointer instead of four or three // pointers uint32_t num_elements_weights = weights_shape[0] * weights_shape[1] * weights_shape[2]; weights = alloc_ztensor_with_values( weights_shape, ZDNN_3DS, test_datatype, RNN_TYPE_LSTM | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI) | USAGE_WEIGHTS, false, (float *)weights_values, (float *)weights_values + num_elements_weights, (float *)weights_values + 2 * num_elements_weights, (float *)weights_values + 3 * num_elements_weights); uint32_t num_elements_biases = biases_shape[0] * biases_shape[1]; biases = alloc_ztensor_with_values( biases_shape, ZDNN_2DS, test_datatype, RNN_TYPE_LSTM | USAGE_BIASES, false, (float *)biases_values, (float *)biases_values + num_elements_biases, (float *)biases_values + 2 * num_elements_biases, (float *)biases_values + 3 * num_elements_biases); uint32_t num_elements_hidden_weights = hidden_weights_shape[0] * hidden_weights_shape[1] * hidden_weights_shape[2]; hidden_weights = alloc_ztensor_with_values( hidden_weights_shape, ZDNN_3DS, test_datatype, RNN_TYPE_LSTM | USAGE_HIDDEN_WEIGHTS, false, (float *)hidden_weights_values, (float *)hidden_weights_values + num_elements_hidden_weights, (float *)hidden_weights_values + 2 * num_elements_hidden_weights, (float *)hidden_weights_values + 3 * num_elements_hidden_weights); uint32_t num_elements_hidden_biases = hidden_biases_shape[0] * hidden_biases_shape[1]; hidden_biases = alloc_ztensor_with_values( hidden_biases_shape, ZDNN_2DS, test_datatype, RNN_TYPE_LSTM | USAGE_HIDDEN_BIASES, false, (float *)hidden_biases_values, (float *)hidden_biases_values + num_elements_hidden_biases, (float *)hidden_biases_values + 2 * num_elements_hidden_biases, (float *)hidden_biases_values + 3 * num_elements_hidden_biases); all_ts_out = alloc_ztensor_with_values( all_ts_out_shape, ZDNN_4DS, test_datatype, NO_CONCAT, true, ZERO_ARRAY); cell_out = alloc_ztensor_with_values(cell_out_shape, ZDNN_4DS, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_status status = zdnn_lstm(input, h0, c0, weights, biases, hidden_weights, hidden_biases, is_this_layer_bidir ? BIDIR : FWD, NULL, all_ts_out, cell_out); if (status != ZDNN_OK) { TEST_FAIL_MESSAGE_FORMATTED("%s() - zdnn_lstm() not ZDNN_OK, status = %08x", __func__, status); } assert_ztensor_values(all_ts_out, false, all_ts_out_exp_values); assert_ztensor_values(cell_out, false, cell_out_exp_values); free_ztensor_buffers(7, h0, c0, weights, biases, hidden_weights, hidden_biases, cell_out); return all_ts_out; } void lstm_fwd_to_fwd() { // num_timesteps = 5 // num_batches = 2 // num_features = 4 // num_hidden = 4, 5 bool is_layer_bidir[] = {false, false}; // first layer uint32_t input0_shape[] = {5, 2, 4}; uint32_t input0_values[] = { 0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a, 0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e, 0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0, 0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48, 0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8, 0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b, 0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80}; uint32_t h00_shape[] = {1, 2, 4}; uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f, 0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4}; uint32_t c00_shape[] = {1, 2, 4}; uint32_t c00_values[] = {0x3fb8c472, 0x3f849e59, 0x3eb88b80, 0x3bc03f00, 0x3f1a65ee, 0x3f5d6a8e, 0x3ea8b604, 0x3fcb5de0}; uint32_t weights0_shape[] = {1, 4, 4}; uint32_t weights0_values[] = { 0x3e493898, 0x3dcbca78, 0xbeee948c, 0x3dbfaa08, 0x3ed41bd0, 0xbede9cf8, 0x3ee3743e, 0xbdac80c8, 0x3edec5e8, 0x3d3c6690, 0x3ec2a6f0, 0xbda882b8, 0x3ee1e222, 0xbea027ac, 0xbeff5dfe, 0xbe6a5f1c, 0x3dbed0f8, 0x3e67aa8c, 0x3e8c896e, 0x3e9ed100, 0xbec67a6c, 0x3e4de7f8, 0xbd813f20, 0x3ef5cf48, 0xbeb16e18, 0xbe97a46a, 0x3c9c6440, 0xbec54796, 0xbe843ed2, 0x3e1aadc8, 0x3ded4400, 0xbe3ba1ec, 0x3e44e48c, 0x3eb7435c, 0x3e7fa638, 0x3ef0d4f2, 0xbe97a134, 0x3e3f7148, 0x3dd65318, 0x3eac7f54, 0x3e3bb1dc, 0xbefd5f4a, 0xbec7b396, 0xbe5f3eb0, 0x3e817616, 0xbea61100, 0xbe9368e8, 0xbe00dcd4, 0xbef3dd78, 0xbce1b020, 0xbe9bc938, 0xbdfedb88, 0xbc133e80, 0x3d99bfa0, 0x3ee84968, 0x3cb8d280, 0xbec0c878, 0xbe51adf4, 0x3eaf6fd0, 0x3d956718, 0xbec577a2, 0x3e97e798, 0xbed7e164, 0x3df2ddd0}; uint32_t biases0_shape[] = {1, 4}; uint32_t biases0_values[] = {0xbed2f700, 0x3e8ab64c, 0x3ecb4226, 0x3eaf295c, 0x3e7604cc, 0x3e34d140, 0xbdf63f00, 0xbdd75a50, 0xbeb493ac, 0x3cb6ae60, 0xbeb47690, 0xbe8cec88, 0xbe952c30, 0x3e2ef934, 0xbe988dc4, 0xbc32ba00}; uint32_t hidden_weights0_shape[] = {1, 4, 4}; uint32_t hidden_weights0_values[] = { 0x3c63ac80, 0x3ef27eba, 0xbee5f866, 0xbe7e7cdc, 0xbd30adc0, 0x3ea29306, 0xbe72ba40, 0xbec42d02, 0x3dcf3d10, 0x3ef30cc4, 0x3eae4fce, 0xbeef9400, 0x3ea2c660, 0xbd141d60, 0xbb546b00, 0xbed810ec, 0x3e48ec5c, 0xbef59156, 0xbe331d5c, 0xbea6c676, 0x3cf559e0, 0xbe97bba0, 0xbed1d2ba, 0xbcd23440, 0xbe79d1cc, 0xbe002b3c, 0xbdd9d200, 0x3eb74200, 0x3e7245d4, 0xbe7966ec, 0x3ddae2f8, 0xbd5288f0, 0xbdcfb470, 0x3e9fb02e, 0xbdc53cf0, 0xbda03c28, 0x3e8c6456, 0xbec8528a, 0xbdc90e10, 0x3bd3e180, 0x3e8a6774, 0xbdd87bf0, 0xbee5b8ba, 0xbe6896b8, 0xbef6e502, 0xbe4f9a1c, 0xbedd0a44, 0x3e40deb8, 0xbee66a3a, 0x3ee72b36, 0xbd6c53f0, 0x3d5bc2b0, 0xbd0a36c0, 0x3e396c38, 0xbe648f70, 0xbdd664c0, 0x3ee121a2, 0xbee707ae, 0x3eccb614, 0x3eb6d016, 0xbe50d738, 0x3ea1f874, 0xbecedf54, 0x3e0eec08}; uint32_t hidden_biases0_shape[] = {1, 4}; uint32_t hidden_biases0_values[] = { 0xbe94a63c, 0x3eb32ed6, 0xbe380bcc, 0x3ed7eee0, 0x3cac4fa0, 0x3ea50604, 0xbec183fa, 0xbeafbf44, 0x3e3924a0, 0x3d81aa40, 0xbb73ed00, 0xbdca6d08, 0x3d807a40, 0xbde9d330, 0xbb663e00, 0x3d82a7c0}; uint32_t all_ts_out0_shape[] = {5, 1, 2, 4}; uint32_t all_ts_out0_exp_values[] = { 0x3d7dec3b, 0x3ec321c6, 0xbd33532c, 0xbd2813ae, 0x3d517efa, 0x3ee7cc40, 0xbd18113a, 0x3e9092b4, 0x3df21ddc, 0xbb310d91, 0xbe18e945, 0xbce56e8b, 0x3d359756, 0x3e238b20, 0xbe0c1333, 0x3e987c64, 0x3dd11579, 0xbe65fb8f, 0xbe55c118, 0xbda5413b, 0x3d7d912d, 0xbcbef32e, 0xbe3ba9c3, 0x3e30db74, 0x3dc41819, 0xbd0f17f6, 0xbdbe76a3, 0x3beeb838, 0x3cc76662, 0x3d477816, 0xbe6299de, 0x3e62029a, 0x3d3e7a2d, 0xbe47d763, 0xbe4eef76, 0x3d90d525, 0x3cfd8dfe, 0x3de03933, 0xbdb0d31e, 0x3e51f80d}; uint32_t cell_out0_shape[] = {1, 1, 2, 4}; uint32_t cell_out0_values[] = {0x3f3626d4, 0xbeab179c, 0xbf0f2c94, 0x3e03c918, 0x3e366377, 0x3e49c51e, 0xbea2454d, 0x3eeb4eda}; zdnn_ztensor *input0 = alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (void *)input0_values); zdnn_ztensor *all_ts_out0 = test_layer(input0, h00_shape, (void *)h00_values, c00_shape, (void *)c00_values, weights0_shape, (void *)weights0_values, biases0_shape, (void *)biases0_values, hidden_weights0_shape, (void *)hidden_weights0_values, hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape, (void *)all_ts_out0_exp_values, cell_out0_shape, (void *)cell_out0_values, false, is_layer_bidir[0]); // second layer uint32_t h01_shape[] = {1, 2, 5}; uint32_t h01_values[] = {0x3fe41f4c, 0x3fc316bd, 0x3e4520a0, 0x3fe7e0c3, 0x3f8930f2, 0x3c305000, 0x3f2385f8, 0x3f78c07a, 0x3feeed13, 0x3f012eea}; uint32_t c01_shape[] = {1, 2, 5}; uint32_t c01_values[] = {0x3fdb2c04, 0x3fa455aa, 0x3faaf233, 0x3f92f487, 0x3f7d3326, 0x3e3365a8, 0x3f600a90, 0x3dd59f00, 0x3ec6cda0, 0x3fd0ec63}; uint32_t weights1_shape[] = {1, 4, 5}; uint32_t weights1_values[] = { 0xbee2f252, 0xbe83e971, 0x3e261b9c, 0x3ebc395c, 0xbed87cba, 0x3e4eb6e0, 0x3e83a64e, 0xbe18ef8e, 0x3df90638, 0x3dc5e080, 0xbe5bef69, 0x3e72843c, 0xbdfff1d8, 0xbe58ace5, 0xbe807ef0, 0xbe98cd9b, 0x3eafbdf8, 0x3e074a8c, 0xbe574539, 0xbecc25a9, 0x3e4d6418, 0x3e1735dc, 0x3e6bc304, 0x3bc9f900, 0x3ebd57a4, 0xbea1dc41, 0x3eabc840, 0xbedd7037, 0xbd9bb79c, 0xbe05dde4, 0xbe4216de, 0xbe136b9a, 0x3ea58b16, 0xbe71302b, 0xbe87f0ac, 0x3e06b148, 0x3a3bae00, 0xbebd57dc, 0x3d721bf0, 0xbe295dd2, 0x3ec8c806, 0x3c696e40, 0x3d952498, 0xbdd1716c, 0x3e10c984, 0xbe94b2a7, 0xbe9a126e, 0x3ebdf640, 0xbca2ec60, 0xbc172600, 0xbd506310, 0xbeb9158a, 0xbe1985b8, 0xbe8b7474, 0xbdcdfc84, 0x3e0332e4, 0x3eb682ba, 0x3e06e404, 0x3e1ae0c4, 0xbe8d2560, 0x3e9e5868, 0xbe5cf1d4, 0x3db3dd28, 0x3e354500, 0x3e1f0c64, 0xbeaa740b, 0x3da48928, 0xbeaa02a3, 0xbd669538, 0xbe271822, 0x3e3b9ae0, 0xbe6de235, 0x3d987eb0, 0xbebbb5a4, 0x3e2dd3f4, 0xbe19fc78, 0x3dd306b8, 0x3e430d88, 0xbd8d3050, 0x3e987cda}; uint32_t biases1_shape[] = {1, 5}; uint32_t biases1_values[] = {0xbe8d6097, 0x3cbbc620, 0x3e5b9460, 0x3e6328f4, 0xbed14480, 0xbdf89d64, 0xbdb0b3c4, 0x3d2f4d98, 0x3ed3c2e8, 0x3cc42620, 0xbda3e468, 0xbeaa2909, 0xbe436636, 0x3e24fec4, 0xbea299d4, 0x3e2a3b28, 0x3ec258fa, 0x3cf049b0, 0xbe989ba1, 0xbe24134e}; uint32_t hidden_weights1_shape[] = {1, 5, 5}; uint32_t hidden_weights1_values[] = { 0xbe20b66c, 0x3e5d42c8, 0x3eb2e8ec, 0xbe1b9f76, 0xbee1e40d, 0x3ebbff92, 0x3e79a49c, 0xbda4ce70, 0x3e5f481c, 0xbeb7e0dd, 0x3e804fe0, 0xbe8f83dc, 0x3e3248cc, 0xbe9fee66, 0x3eb4c482, 0xbe89ca96, 0x3e036284, 0x3da2aec0, 0x3dcedbf0, 0x3e77c3f8, 0x3ecdd9da, 0xbe2089f6, 0x3e42d780, 0xbe9aebe8, 0x3ed6d390, 0xbe6f1e1b, 0x3d64ba10, 0x3e86944e, 0xbec4e626, 0x3eace9cc, 0x3b9084c0, 0xbeb401c3, 0x3d757710, 0x3ee46d12, 0x3ee4e29a, 0x3e3d5c4c, 0x3d0ff4f8, 0x3e55de1c, 0x3e915990, 0x3ec83690, 0x3d0f9250, 0x3e9e8ea0, 0xbe5ec821, 0xbe9e462c, 0x3eb165e2, 0x3d190310, 0x3ece54c0, 0xbebdbf60, 0x3e332b14, 0xbdd1fa20, 0x3eb76f78, 0x3e9eff90, 0x3ebc5350, 0xbdea86c4, 0x3e6d851c, 0xbecc7bce, 0xbead1b0c, 0x3ebb7968, 0x3e497f5c, 0x3e8e5746, 0xbe9c4230, 0xbe5f6ed0, 0x3ea3e864, 0x3ecbffd4, 0xbe20471c, 0xbd93fe10, 0xbedd358e, 0x3eb0cbec, 0x3e177f54, 0x3e5bbc44, 0xbe94b3e4, 0xbe81ffa5, 0x3ecb999a, 0x3ee4e636, 0x3d527bf8, 0xbddabb30, 0x3ea2c8c8, 0x3d082a00, 0x3edb2580, 0xbd8f889c, 0xbe811315, 0xbd507b08, 0xbe58367b, 0x3eade05a, 0x3ec26bea, 0xbe807b12, 0xbe8480f1, 0x3ed26ffe, 0xbe26eada, 0x3c976030, 0xbeb030cc, 0x3eb0f98a, 0x3e3b45e4, 0x3e80b7ea, 0xbea1ef22, 0x3e99b77e, 0x3e926d0a, 0xbeadd2f6, 0xbe8219a4, 0xbe190f96}; uint32_t hidden_biases1_shape[] = {1, 5}; uint32_t hidden_biases1_values[] = { 0xbede7c01, 0xbdb9cd1c, 0x3e99f81e, 0xbed8b7ed, 0x3ebe51d8, 0x3dc7ff90, 0xbeae8cee, 0x3e63833c, 0xbecfe0c1, 0xbedc1c4e, 0xbe37306c, 0x3e062014, 0x3ca711d0, 0xbece783b, 0x3ebde4ee, 0x3e769414, 0x3ee39938, 0x3e675c3c, 0xbe972362, 0x3ebf18f2}; uint32_t all_ts_out1_shape[] = {5, 1, 2, 5}; uint32_t all_ts_out1_exp_values[] = { 0x3e10591e, 0x3ea4c525, 0x3ede5521, 0x3ee29046, 0x3ebfbb06, 0xbdf93f6b, 0xbd444231, 0x3e873334, 0x3e5763af, 0x3ecbdbf2, 0xbd65671e, 0xbd55c4a2, 0x3efdcab4, 0x3e2c772b, 0x3eac09f7, 0xbe4fcd44, 0xbe0e3377, 0x3e535bcd, 0x3dbbe197, 0x3ead8e9b, 0xbe1ad9da, 0xbdfa7c72, 0x3ee06835, 0x3dbbcd47, 0x3e6c8300, 0xbe44c5f7, 0xbe0ce1ad, 0x3e0a1251, 0x3d4e3a71, 0x3e54c2a1, 0xbe35533e, 0xbe198119, 0x3ea44292, 0x3d3cfc26, 0x3e0b0c38, 0xbe2a6eaa, 0xbdee377c, 0x3d8c79a9, 0x3cb2aedd, 0x3ddb9885, 0xbe238eaf, 0xbde48ec9, 0x3e3951bc, 0x3cb1df06, 0x3d89af34, 0xbe15c676, 0xbde42498, 0x3c0f48aa, 0xbc2b888c, 0x3d376f4d}; uint32_t cell_out1_shape[] = {1, 1, 2, 5}; uint32_t cell_out1_values[] = {0xbe89ae92, 0xbe286430, 0x3e9ceb6f, 0x3d86d03b, 0x3dffb46f, 0xbe804ee8, 0xbe24adf4, 0x3c7cc930, 0xbd0309c4, 0x3da7c588}; zdnn_ztensor *all_ts_out1 = test_layer( all_ts_out0, h01_shape, (void *)h01_values, c01_shape, (void *)c01_values, weights1_shape, (void *)weights1_values, biases1_shape, (void *)biases1_values, hidden_weights1_shape, (void *)hidden_weights1_values, hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape, (void *)all_ts_out1_exp_values, cell_out1_shape, (void *)cell_out1_values, is_layer_bidir[0], is_layer_bidir[1]); free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1); } void lstm_fwd_to_bidir() { // num_timesteps = 5 // num_batches = 2 // num_features = 4 // num_hidden = 4, 5 bool is_layer_bidir[] = {false, true}; // first layer uint32_t input0_shape[] = {5, 2, 4}; uint32_t input0_values[] = { 0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a, 0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e, 0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0, 0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48, 0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8, 0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b, 0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80}; uint32_t h00_shape[] = {1, 2, 4}; uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f, 0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4}; uint32_t c00_shape[] = {1, 2, 4}; uint32_t c00_values[] = {0x3fb8c472, 0x3f849e59, 0x3eb88b80, 0x3bc03f00, 0x3f1a65ee, 0x3f5d6a8e, 0x3ea8b604, 0x3fcb5de0}; uint32_t weights0_shape[] = {1, 4, 4}; uint32_t weights0_values[] = { 0x3e493898, 0x3dcbca78, 0xbeee948c, 0x3dbfaa08, 0x3ed41bd0, 0xbede9cf8, 0x3ee3743e, 0xbdac80c8, 0x3edec5e8, 0x3d3c6690, 0x3ec2a6f0, 0xbda882b8, 0x3ee1e222, 0xbea027ac, 0xbeff5dfe, 0xbe6a5f1c, 0x3dbed0f8, 0x3e67aa8c, 0x3e8c896e, 0x3e9ed100, 0xbec67a6c, 0x3e4de7f8, 0xbd813f20, 0x3ef5cf48, 0xbeb16e18, 0xbe97a46a, 0x3c9c6440, 0xbec54796, 0xbe843ed2, 0x3e1aadc8, 0x3ded4400, 0xbe3ba1ec, 0x3e44e48c, 0x3eb7435c, 0x3e7fa638, 0x3ef0d4f2, 0xbe97a134, 0x3e3f7148, 0x3dd65318, 0x3eac7f54, 0x3e3bb1dc, 0xbefd5f4a, 0xbec7b396, 0xbe5f3eb0, 0x3e817616, 0xbea61100, 0xbe9368e8, 0xbe00dcd4, 0xbef3dd78, 0xbce1b020, 0xbe9bc938, 0xbdfedb88, 0xbc133e80, 0x3d99bfa0, 0x3ee84968, 0x3cb8d280, 0xbec0c878, 0xbe51adf4, 0x3eaf6fd0, 0x3d956718, 0xbec577a2, 0x3e97e798, 0xbed7e164, 0x3df2ddd0}; uint32_t biases0_shape[] = {1, 4}; uint32_t biases0_values[] = {0xbed2f700, 0x3e8ab64c, 0x3ecb4226, 0x3eaf295c, 0x3e7604cc, 0x3e34d140, 0xbdf63f00, 0xbdd75a50, 0xbeb493ac, 0x3cb6ae60, 0xbeb47690, 0xbe8cec88, 0xbe952c30, 0x3e2ef934, 0xbe988dc4, 0xbc32ba00}; uint32_t hidden_weights0_shape[] = {1, 4, 4}; uint32_t hidden_weights0_values[] = { 0x3c63ac80, 0x3ef27eba, 0xbee5f866, 0xbe7e7cdc, 0xbd30adc0, 0x3ea29306, 0xbe72ba40, 0xbec42d02, 0x3dcf3d10, 0x3ef30cc4, 0x3eae4fce, 0xbeef9400, 0x3ea2c660, 0xbd141d60, 0xbb546b00, 0xbed810ec, 0x3e48ec5c, 0xbef59156, 0xbe331d5c, 0xbea6c676, 0x3cf559e0, 0xbe97bba0, 0xbed1d2ba, 0xbcd23440, 0xbe79d1cc, 0xbe002b3c, 0xbdd9d200, 0x3eb74200, 0x3e7245d4, 0xbe7966ec, 0x3ddae2f8, 0xbd5288f0, 0xbdcfb470, 0x3e9fb02e, 0xbdc53cf0, 0xbda03c28, 0x3e8c6456, 0xbec8528a, 0xbdc90e10, 0x3bd3e180, 0x3e8a6774, 0xbdd87bf0, 0xbee5b8ba, 0xbe6896b8, 0xbef6e502, 0xbe4f9a1c, 0xbedd0a44, 0x3e40deb8, 0xbee66a3a, 0x3ee72b36, 0xbd6c53f0, 0x3d5bc2b0, 0xbd0a36c0, 0x3e396c38, 0xbe648f70, 0xbdd664c0, 0x3ee121a2, 0xbee707ae, 0x3eccb614, 0x3eb6d016, 0xbe50d738, 0x3ea1f874, 0xbecedf54, 0x3e0eec08}; uint32_t hidden_biases0_shape[] = {1, 4}; uint32_t hidden_biases0_values[] = { 0xbe94a63c, 0x3eb32ed6, 0xbe380bcc, 0x3ed7eee0, 0x3cac4fa0, 0x3ea50604, 0xbec183fa, 0xbeafbf44, 0x3e3924a0, 0x3d81aa40, 0xbb73ed00, 0xbdca6d08, 0x3d807a40, 0xbde9d330, 0xbb663e00, 0x3d82a7c0}; uint32_t all_ts_out0_shape[] = {5, 1, 2, 4}; uint32_t all_ts_out0_exp_values[] = { 0x3d7dec3b, 0x3ec321c6, 0xbd33532c, 0xbd2813ae, 0x3d517efa, 0x3ee7cc40, 0xbd18113a, 0x3e9092b4, 0x3df21ddc, 0xbb310d91, 0xbe18e945, 0xbce56e8b, 0x3d359756, 0x3e238b20, 0xbe0c1333, 0x3e987c64, 0x3dd11579, 0xbe65fb8f, 0xbe55c118, 0xbda5413b, 0x3d7d912d, 0xbcbef32e, 0xbe3ba9c3, 0x3e30db74, 0x3dc41819, 0xbd0f17f6, 0xbdbe76a3, 0x3beeb838, 0x3cc76662, 0x3d477816, 0xbe6299de, 0x3e62029a, 0x3d3e7a2d, 0xbe47d763, 0xbe4eef76, 0x3d90d525, 0x3cfd8dfe, 0x3de03933, 0xbdb0d31e, 0x3e51f80d}; uint32_t cell_out0_shape[] = {1, 1, 2, 4}; uint32_t cell_out0_values[] = {0x3f3626d4, 0xbeab179c, 0xbf0f2c94, 0x3e03c918, 0x3e366377, 0x3e49c51e, 0xbea2454d, 0x3eeb4eda}; zdnn_ztensor *input0 = alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (void *)input0_values); zdnn_ztensor *all_ts_out0 = test_layer(input0, h00_shape, (void *)h00_values, c00_shape, (void *)c00_values, weights0_shape, (void *)weights0_values, biases0_shape, (void *)biases0_values, hidden_weights0_shape, (void *)hidden_weights0_values, hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape, (void *)all_ts_out0_exp_values, cell_out0_shape, (void *)cell_out0_values, false, is_layer_bidir[0]); // second layer uint32_t h01_shape[] = {2, 2, 5}; uint32_t h01_values[] = {0x3fe41f4c, 0x3fc316bd, 0x3e4520a0, 0x3fe7e0c3, 0x3f8930f2, 0x3c305000, 0x3f2385f8, 0x3f78c07a, 0x3feeed13, 0x3f012eea, 0x3fdb2c04, 0x3fa455aa, 0x3faaf233, 0x3f92f487, 0x3f7d3326, 0x3e3365a8, 0x3f600a90, 0x3dd59f00, 0x3ec6cda0, 0x3fd0ec63}; uint32_t c01_shape[] = {2, 2, 5}; uint32_t c01_values[] = {0x3f0d2ed6, 0x3fda7b92, 0x3fb63fe7, 0x3f34b460, 0x3f2b7888, 0x3e7fc438, 0x3fa9348a, 0x3f7f9716, 0x3ef8690c, 0x3ffbc9ad, 0x3e8dd57c, 0x3fe9d898, 0x3f7c78c0, 0x3f95c31c, 0x3fc36a05, 0x3f5e2a0a, 0x3e313c38, 0x3fa56aba, 0x3fcbfe2b, 0x3faf56e1}; uint32_t weights1_shape[] = {2, 4, 5}; uint32_t weights1_values[] = { 0x3ec8c806, 0x3c696e40, 0x3d952498, 0xbdd1716c, 0x3e10c984, 0xbe94b2a7, 0xbe9a126e, 0x3ebdf640, 0xbca2ec60, 0xbc172600, 0xbd506310, 0xbeb9158a, 0xbe1985b8, 0xbe8b7474, 0xbdcdfc84, 0x3e0332e4, 0x3eb682ba, 0x3e06e404, 0x3e1ae0c4, 0xbe8d2560, 0xbebfde02, 0xbed417e7, 0x3ec1d528, 0xbe0751fa, 0xbdfe1e6c, 0xbe77c691, 0x3ea17e98, 0xbe76cf7f, 0x3e1940d8, 0xbe2ab878, 0x3eca9984, 0x3e658114, 0x3e109bc4, 0xbe03c1e6, 0x3de69348, 0x3ed16702, 0x3e878898, 0x3e3b6830, 0x3e8d90bc, 0x3e226e48, 0xbee2f252, 0xbe83e971, 0x3e261b9c, 0x3ebc395c, 0xbed87cba, 0x3e4eb6e0, 0x3e83a64e, 0xbe18ef8e, 0x3df90638, 0x3dc5e080, 0xbe5bef69, 0x3e72843c, 0xbdfff1d8, 0xbe58ace5, 0xbe807ef0, 0xbe98cd9b, 0x3eafbdf8, 0x3e074a8c, 0xbe574539, 0xbecc25a9, 0xbec39102, 0xbea1a3c0, 0xbd3aa670, 0x3c6b9ce0, 0x3e630230, 0x3e55ae7c, 0xbe62d375, 0x3eb037d8, 0xbe0d9648, 0xbea06a9a, 0xbe81b1a9, 0xbebc9a53, 0x3e8db48a, 0xbdc724ec, 0x3ec02c1a, 0x3e5c50f0, 0x3e6ef9a8, 0x3e7d66c4, 0x3d737210, 0xbd472b98, 0x3e9e5868, 0xbe5cf1d4, 0x3db3dd28, 0x3e354500, 0x3e1f0c64, 0xbeaa740b, 0x3da48928, 0xbeaa02a3, 0xbd669538, 0xbe271822, 0x3e3b9ae0, 0xbe6de235, 0x3d987eb0, 0xbebbb5a4, 0x3e2dd3f4, 0xbe19fc78, 0x3dd306b8, 0x3e430d88, 0xbd8d3050, 0x3e987cda, 0xbe5fbd62, 0x3e0b5e64, 0xbe86a497, 0xbaa00c00, 0xbeacb04b, 0x3d21ed48, 0xbddce6cc, 0xbe68730d, 0xbe5ddf86, 0xbeb99f2f, 0x3e84b2c0, 0x3e208298, 0x3ed26dd4, 0x3ee494f2, 0xbead8f69, 0xbd3641c0, 0xbea5ddf2, 0xbdf673cc, 0x3edfa1a6, 0xbb0d5900, 0xbe6f1e1b, 0x3d190310, 0x3e9e8ea0, 0x3e55de1c, 0x3ee46d12, 0x3b9084c0, 0x3d64ba10, 0x3ece54c0, 0xbe5ec821, 0x3e915990, 0x3e3d5c4c, 0xbeb401c3, 0x3e86944e, 0xbebdbf60, 0xbe9e462c, 0x3d0f9250, 0x3d0ff4f8, 0x3d757710, 0xbec4e626, 0x3e332b14, 0xbde97700, 0xbe6f45de, 0x3d7ba930, 0xbe28e040, 0x3ee1a07c, 0xbe95df9f, 0x3dcaf230, 0x3ebc4676, 0x3ee0b168, 0xbe90de80, 0xbe2440b2, 0xbdd20768, 0xbe9acddc, 0xbed93dd3, 0x3daf9920, 0x3dad0a60, 0xbe5de779, 0x3caa1db0, 0xbedb8204, 0xbd1e1828}; uint32_t biases1_shape[] = {2, 5}; uint32_t biases1_values[] = { 0xbede7c01, 0xbdb9cd1c, 0x3e99f81e, 0xbed8b7ed, 0x3ebe51d8, 0xbdc69f70, 0x3ea85d6a, 0xbeb1737d, 0x3d428f68, 0x3ed75422, 0x3dc7ff90, 0xbeae8cee, 0x3e63833c, 0xbecfe0c1, 0xbedc1c4e, 0x3d940df8, 0x3ed2d41c, 0xbe5a9fca, 0x3e23c650, 0xbde59ef4, 0xbe37306c, 0x3e062014, 0x3ca711d0, 0xbece783b, 0x3ebde4ee, 0xbd7bb5b8, 0x3eb1c89c, 0xbe0d071e, 0x3eb8509c, 0xbedd7e2d, 0x3e769414, 0x3ee39938, 0x3e675c3c, 0xbe972362, 0x3ebf18f2, 0xbd840080, 0xbda0df98, 0x3e1469e4, 0x3e33aa40, 0x3eafcf42}; uint32_t hidden_weights1_shape[] = {2, 5, 5}; uint32_t hidden_weights1_values[] = { 0xbee1e40d, 0x3eb76f78, 0x3e9eff90, 0x3ebc5350, 0xbdea86c4, 0xbeb7e0dd, 0xbecc7bce, 0xbead1b0c, 0x3ebb7968, 0x3e497f5c, 0x3eb4c482, 0xbe9c4230, 0xbe5f6ed0, 0x3ea3e864, 0x3ecbffd4, 0x3e77c3f8, 0xbd93fe10, 0xbedd358e, 0x3eb0cbec, 0x3e177f54, 0x3ed6d390, 0xbe94b3e4, 0xbe81ffa5, 0x3ecb999a, 0x3ee4e636, 0xbebd9868, 0x3db92198, 0xbec9e6b4, 0xbec61cd1, 0xbe2ccb44, 0xbecfb148, 0x3e2de8c8, 0xbecee7d6, 0x3ed4086e, 0xbe9d7ac6, 0x3de585b8, 0x3eb61b5a, 0x3ed5ca40, 0x3ed8ea94, 0x3ed8d474, 0xbd0ab3d0, 0x3eb1c556, 0x3e4a7010, 0x3ecebb20, 0xbe44c542, 0xbe6741db, 0xbd891828, 0x3e479f54, 0xbec12893, 0xbe5113e1, 0x3eace9cc, 0xbe20b66c, 0x3e5d42c8, 0x3eb2e8ec, 0xbe1b9f76, 0x3ee4e29a, 0x3ebbff92, 0x3e79a49c, 0xbda4ce70, 0x3e5f481c, 0x3ec83690, 0x3e804fe0, 0xbe8f83dc, 0x3e3248cc, 0xbe9fee66, 0x3eb165e2, 0xbe89ca96, 0x3e036284, 0x3da2aec0, 0x3dcedbf0, 0xbdd1fa20, 0x3ecdd9da, 0xbe2089f6, 0x3e42d780, 0xbe9aebe8, 0xbdc0f07c, 0xbe872d40, 0xbdcbff10, 0x3e8472c6, 0xbe19b22c, 0xbdcc9010, 0xbe1c1d3a, 0xbda475ac, 0xbe0aeb80, 0xbed457d0, 0x3e917fbc, 0x3e667240, 0x3eb369f6, 0xbe97eae2, 0x3e3bb9b4, 0x3caf1b90, 0xbe942d27, 0x3e662ae4, 0xbd084a60, 0x3edee626, 0xbedeee8a, 0x3ed7e74a, 0x3ec2326c, 0x3ebd81c8, 0xbe025ea8, 0x3e6d851c, 0xbddabb30, 0x3ea2c8c8, 0x3d082a00, 0x3edb2580, 0x3e8e5746, 0xbe811315, 0xbd507b08, 0xbe58367b, 0x3eade05a, 0xbe20471c, 0xbe807b12, 0xbe8480f1, 0x3ed26ffe, 0xbe26eada, 0x3e5bbc44, 0xbeb030cc, 0x3eb0f98a, 0x3e3b45e4, 0x3e80b7ea, 0x3d527bf8, 0x3e99b77e, 0x3e926d0a, 0xbeadd2f6, 0xbe8219a4, 0x3e6fec98, 0xbeb25d85, 0x3e66f338, 0x3ed89bd2, 0x3ec8c0ca, 0xbe53d7b8, 0x3ebee346, 0x3d81ac10, 0x3dd8c630, 0xbd97418c, 0xbe618c84, 0xbe4a029f, 0x3ec2d2d6, 0xbedf67a9, 0xbed0b705, 0xbd203aa8, 0x3e2270c4, 0x3d763d80, 0xbe025fa2, 0xbce64df0, 0xbd301208, 0x3ec72844, 0xbe53df41, 0xbe9bf81e, 0x3e8fcc58, 0xbd8f889c, 0xbdf89d64, 0xbe8d6097, 0xbda3e468, 0x3e2a3b28, 0x3ec26bea, 0xbdb0b3c4, 0x3cbbc620, 0xbeaa2909, 0x3ec258fa, 0x3c976030, 0x3d2f4d98, 0x3e5b9460, 0xbe436636, 0x3cf049b0, 0xbea1ef22, 0x3ed3c2e8, 0x3e6328f4, 0x3e24fec4, 0xbe989ba1, 0xbe190f96, 0x3cc42620, 0xbed14480, 0xbea299d4, 0xbe24134e, 0x3dedf310, 0xbe362bda, 0x3d836668, 0xbe8525dc, 0xbe3b1bb2, 0x3e10ce08, 0xbed605fa, 0x3e122c34, 0x3ebc54aa, 0x3ec058f2, 0x3d2a1fb8, 0xbeac7e7c, 0x3d01b298, 0xbeb62674, 0xbe9d91cb, 0x3e2abb28, 0x3e4679ac, 0xbe94746f, 0xbddc5118, 0xbec0490a, 0xbddf28c4, 0xbe879404, 0x3edaf946, 0x3e791bd4, 0xbe4e7f38}; uint32_t hidden_biases1_shape[] = {2, 5}; uint32_t hidden_biases1_values[] = { 0xbe325de8, 0x3dc59638, 0xbeb3c7f8, 0x3e11fa20, 0x3e75d434, 0xbe987408, 0xbd4637a8, 0xbcc4c620, 0x3e4c5720, 0x3e9c8b2a, 0x3cc4e590, 0x3e592a78, 0xbeb798f6, 0xbe03b7b6, 0xbee0d2e5, 0xbd88748c, 0xbc914780, 0x3e9ccdb4, 0xbdf7d0f0, 0x3ec8b9ca, 0x3d7f2f50, 0xbe9933c8, 0xbeb1870e, 0xbe0d48c0, 0x3e4904fc, 0xbd912c2c, 0xbebdb332, 0x3e62e8b8, 0x3e08fc84, 0x3e37f4f4, 0x3ee1dbc6, 0x3e83aa94, 0xbd4e46b0, 0x3e20904c, 0xbee0a324, 0xbe8d3f0b, 0x3e935dc2, 0x3ed8df8e, 0x3d1ef258, 0xbed5df49}; uint32_t all_ts_out1_shape[] = {5, 2, 2, 5}; uint32_t all_ts_out1_exp_values[] = { 0x3ece7c30, 0x3e0ade44, 0x3ea77833, 0x3d8a1542, 0x3ec14d90, 0x3e0f6de1, 0xbcc5b015, 0x3e3d01bd, 0x3ddc92d0, 0x3ed872c6, 0xbdb78493, 0x3e4d107e, 0x3d629dbb, 0x3e81d6dc, 0xbe282ecb, 0xbda067b0, 0x3d215190, 0xbc606d8e, 0x3e9d2a63, 0xbe17d42e, 0x3e4adf52, 0xbc961bd7, 0x3e1f1361, 0xbcd7e3b3, 0x3ea4f150, 0x3b1279df, 0xbd0fc6b2, 0x3ce5e595, 0xbc901e15, 0x3ee2c9e3, 0xbde63869, 0x3e83c0d4, 0x3ddda844, 0x3e83a426, 0xbd9c714e, 0xbdbdde95, 0x3dbfb398, 0x3ca6b42f, 0x3e9b0b9e, 0xbd832c54, 0x3da00061, 0xbd3cde78, 0x3d0c9de8, 0xbdce55e5, 0x3e8c68d8, 0xbd389116, 0xbc3aea77, 0xbcdead41, 0xbdcf5f14, 0x3ec552b2, 0xbdf64801, 0x3ea190d7, 0x3e43aea4, 0x3e90136c, 0x3d1c6530, 0xbdb73956, 0x3e1a74cf, 0x3d91c0d8, 0x3e9f6f28, 0x3d0d3abe, 0xbb2c613b, 0xbd29ebe1, 0xbd1e8311, 0xbe0a8488, 0x3e7dc919, 0xbdadd9a7, 0x3c9a6539, 0xbd8b9ccc, 0xbe0bde89, 0x3eaf4cea, 0xbdcda1c7, 0x3ec24b51, 0x3e9f2fd6, 0x3ea62629, 0x3e1f64a3, 0xbd7dae5d, 0x3e4a2633, 0x3e13742c, 0x3eaf0a3c, 0x3e0b9059, 0xbd110365, 0xbcb1df00, 0xbd897780, 0xbe1bafd2, 0x3e63dc44, 0xbdc911b3, 0x3cd0cccd, 0xbdcc05ba, 0xbe19b36a, 0x3e95fa6d, 0xbd9d8379, 0x3e60bed7, 0x3f00a623, 0x3eb132b8, 0x3e57d24f, 0x3d00a823, 0x3e3e6cd3, 0x3e9d532b, 0x3f01cead, 0x3e8b3a37}; uint32_t cell_out1_shape[] = {1, 2, 2, 5}; uint32_t cell_out1_values[] = { 0xbd5edee1, 0xbd04585f, 0xbe0fefd7, 0xbeab8c8a, 0x3efb1f43, 0xbe19186a, 0x3d1c1ce0, 0xbe48d1fc, 0xbebf107e, 0x3f29bd16, 0xbe65346c, 0x3ec43b22, 0x3dacd5ad, 0x3ee2a358, 0xbebe8bd4, 0xbe48f9a6, 0x3d90ece4, 0xbcaaee82, 0x3f187263, 0xbeb46694}; zdnn_ztensor *all_ts_out1 = test_layer( all_ts_out0, h01_shape, (void *)h01_values, c01_shape, (void *)c01_values, weights1_shape, (void *)weights1_values, biases1_shape, (void *)biases1_values, hidden_weights1_shape, (void *)hidden_weights1_values, hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape, (void *)all_ts_out1_exp_values, cell_out1_shape, (void *)cell_out1_values, is_layer_bidir[0], is_layer_bidir[1]); free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1); } void lstm_bidir_to_bidir() { // num_timesteps = 5 // num_batches = 2 // num_features = 4 // num_hidden = 4, 5 bool is_layer_bidir[] = {true, true}; // first layer uint32_t input0_shape[] = {5, 2, 4}; uint32_t input0_values[] = { 0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a, 0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e, 0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0, 0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48, 0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8, 0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b, 0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80}; uint32_t h00_shape[] = {2, 2, 4}; uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f, 0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4, 0x3fb8c472, 0x3f849e59, 0x3eb88b80, 0x3bc03f00, 0x3f1a65ee, 0x3f5d6a8e, 0x3ea8b604, 0x3fcb5de0}; uint32_t c00_shape[] = {2, 2, 4}; uint32_t c00_values[] = {0x3f504bc2, 0x3fe33d36, 0x3fd8b70c, 0x3fc21f69, 0x3f0c2aba, 0x3f190c04, 0x3fcbd235, 0x3f32a91c, 0x3ee6ed24, 0x3f9027e4, 0x3f7639bc, 0x3f44af00, 0x3ec25e00, 0x3d230b80, 0x3fe2a3cb, 0x3faee87b}; uint32_t weights0_shape[] = {2, 4, 4}; uint32_t weights0_values[] = { 0x3e44e48c, 0x3eb7435c, 0x3e7fa638, 0x3ef0d4f2, 0xbe97a134, 0x3e3f7148, 0x3dd65318, 0x3eac7f54, 0x3e3bb1dc, 0xbefd5f4a, 0xbec7b396, 0xbe5f3eb0, 0x3e817616, 0xbea61100, 0xbe9368e8, 0xbe00dcd4, 0x3be1d000, 0x3ed3b0f2, 0xbefdbbe6, 0xbe937b62, 0xbdae18e0, 0xbe15aae8, 0x3e671d1c, 0x3e933052, 0xbe86d40a, 0xbe97fc56, 0xbe75e520, 0x3e879224, 0x3d8757d8, 0xbe3d5b84, 0xbeaad6d0, 0x3ec47c50, 0x3e493898, 0x3dcbca78, 0xbeee948c, 0x3dbfaa08, 0x3ed41bd0, 0xbede9cf8, 0x3ee3743e, 0xbdac80c8, 0x3edec5e8, 0x3d3c6690, 0x3ec2a6f0, 0xbda882b8, 0x3ee1e222, 0xbea027ac, 0xbeff5dfe, 0xbe6a5f1c, 0x3d7fab80, 0x3e65a254, 0x3e290ef0, 0x3e83cb7a, 0x3ee54c20, 0xbeb4f724, 0x3ec00ef2, 0xbef7935a, 0x3e9c9930, 0xbe58ff9c, 0xbe24d228, 0x3eb91542, 0xbea1d8c6, 0x3e169740, 0x3a51d400, 0xbed3b130, 0xbef3dd78, 0xbce1b020, 0xbe9bc938, 0xbdfedb88, 0xbc133e80, 0x3d99bfa0, 0x3ee84968, 0x3cb8d280, 0xbec0c878, 0xbe51adf4, 0x3eaf6fd0, 0x3d956718, 0xbec577a2, 0x3e97e798, 0xbed7e164, 0x3df2ddd0, 0x3e39b6d8, 0x3ed270de, 0xbef20a42, 0x3ee07afa, 0xbe2afcc4, 0x3e0b3574, 0x3ddd3bb0, 0xbea63fd0, 0xbe0f13d4, 0xbe72401c, 0xbe8fa9a8, 0xbd68fbd0, 0x3e174298, 0xbe70adfc, 0xbee43e50, 0x3e12af48, 0x3e48ec5c, 0xbef59156, 0xbe331d5c, 0xbea6c676, 0x3cf559e0, 0xbe97bba0, 0xbed1d2ba, 0xbcd23440, 0xbe79d1cc, 0xbe002b3c, 0xbdd9d200, 0x3eb74200, 0x3e7245d4, 0xbe7966ec, 0x3ddae2f8, 0xbd5288f0, 0x3c827de0, 0x3da6bf30, 0xbdea2a18, 0x3e21e080, 0xbeac41fa, 0x3ed46246, 0xbcb62760, 0xbc28fd40, 0xbeceee2c, 0xbe2ba4a8, 0xbe9bea52, 0xbde64cc0, 0x3ecc0d98, 0x3e16cff8, 0x3e2d28ac, 0xbe9dce58}; uint32_t biases0_shape[] = {2, 4}; uint32_t biases0_values[] = { 0xbe94a63c, 0x3eb32ed6, 0xbe380bcc, 0x3ed7eee0, 0x3e8a8150, 0x3ef02ee8, 0x3ecd1648, 0xbee49ea0, 0x3cac4fa0, 0x3ea50604, 0xbec183fa, 0xbeafbf44, 0xbead3520, 0xbefc8dba, 0xbecd9510, 0x3eca1ab6, 0x3e3924a0, 0x3d81aa40, 0xbb73ed00, 0xbdca6d08, 0xbeaeb3ce, 0xbda575e8, 0xbea64132, 0x3eb1c3f8, 0x3d807a40, 0xbde9d330, 0xbb663e00, 0x3d82a7c0, 0xbec189ba, 0xbe79ce38, 0xbef751c4, 0xbe9157c6}; uint32_t hidden_weights0_shape[] = {2, 4, 4}; uint32_t hidden_weights0_values[] = { 0xbdcfb470, 0x3e9fb02e, 0xbdc53cf0, 0xbda03c28, 0x3e8c6456, 0xbec8528a, 0xbdc90e10, 0x3bd3e180, 0x3e8a6774, 0xbdd87bf0, 0xbee5b8ba, 0xbe6896b8, 0xbef6e502, 0xbe4f9a1c, 0xbedd0a44, 0x3e40deb8, 0x3e31d250, 0xbe85abba, 0x3d2b1290, 0x3eb145b4, 0xbe3ad12c, 0x3ba19380, 0x3d7fb970, 0x3ee6af64, 0x3e425874, 0x3e53b624, 0xbec940fa, 0x3e9676d8, 0x3eaa7c86, 0x3d208490, 0x3d20f2e0, 0x3d893818, 0x3c63ac80, 0x3ef27eba, 0xbee5f866, 0xbe7e7cdc, 0xbd30adc0, 0x3ea29306, 0xbe72ba40, 0xbec42d02, 0x3dcf3d10, 0x3ef30cc4, 0x3eae4fce, 0xbeef9400, 0x3ea2c660, 0xbd141d60, 0xbb546b00, 0xbed810ec, 0x3eb10914, 0xbe77060c, 0x3dc91810, 0x3e4aaa5c, 0xbebe9294, 0x3db7f4e0, 0xbebe13ca, 0xbd80e658, 0x3e51bfac, 0xbe84fb22, 0x3daa7e98, 0xbed1dd9a, 0xbe2c296c, 0x3debef40, 0x3e5a1364, 0xbd9dda90, 0xbee66a3a, 0x3ee72b36, 0xbd6c53f0, 0x3d5bc2b0, 0xbd0a36c0, 0x3e396c38, 0xbe648f70, 0xbdd664c0, 0x3ee121a2, 0xbee707ae, 0x3eccb614, 0x3eb6d016, 0xbe50d738, 0x3ea1f874, 0xbecedf54, 0x3e0eec08, 0x3e6f1c7c, 0x3eff635a, 0x3ec152aa, 0xbdeac2f0, 0xbe7913dc, 0x3ea2818e, 0x3effe6c2, 0xbe33aea0, 0xbed424ec, 0xbeb0f4b2, 0x3edfd858, 0x3ed23042, 0xbedc23ca, 0x3e4850f4, 0x3ec65644, 0x3e8f750a, 0x3e7604cc, 0xbed2f700, 0xbeb493ac, 0xbe952c30, 0x3e34d140, 0x3e8ab64c, 0x3cb6ae60, 0x3e2ef934, 0xbdf63f00, 0x3ecb4226, 0xbeb47690, 0xbe988dc4, 0xbdd75a50, 0x3eaf295c, 0xbe8cec88, 0xbc32ba00, 0xbe9a0e30, 0xbea0746a, 0xbdb84258, 0xbe2dfde0, 0x3ee625fe, 0x3e12e488, 0x3e4753f8, 0x3e79a2f4, 0x3e776090, 0xbe337cec, 0x3db5e280, 0xbeb2cefe, 0x3e8b8e00, 0x3ec806fc, 0x3e59d6f8, 0x3de74688}; uint32_t hidden_biases0_shape[] = {2, 4}; uint32_t hidden_biases0_values[] = { 0xbd130f20, 0x3efd3ec0, 0x3e38f410, 0x3c67f0c0, 0x3ee3a1ba, 0xbe031ab0, 0x3e6147f4, 0x3ee41404, 0xbec83e98, 0xbe862d7a, 0x3eceb7d8, 0xbecfc186, 0x3ed28de2, 0x3ed19a42, 0x3eb74124, 0x3ec5aa22, 0xbeddda26, 0x3e7da22c, 0xbeb65808, 0xbe1156a8, 0x3e296114, 0x3effeaca, 0x3e84c718, 0x3e9f2458, 0xbe2bc8cc, 0xbd97a438, 0x3bb33680, 0x3ed32696, 0xbe33322c, 0x3e75abf4, 0x3d6b5420, 0xbdf48c88}; uint32_t all_ts_out0_shape[] = {5, 2, 2, 4}; uint32_t all_ts_out0_exp_values[] = { 0xbe7a53bc, 0x3e9f7692, 0xbc9ed153, 0x3ee831ab, 0xbe77d13d, 0x3e31f762, 0x3d8ddd1a, 0x3e6762b7, 0xbd9698a5, 0x3e4d00b0, 0xbe496231, 0x3e91c291, 0xbe1c9299, 0x3ed36114, 0xbe45f6fb, 0x3ed3744e, 0xbec68241, 0x3e276d3e, 0xbdd85a96, 0x3ec34484, 0xbed55ee0, 0x3dc4d879, 0x3c76e7a9, 0x3e49a5fe, 0xbd67a64d, 0x3e9192cf, 0xbe51be30, 0x3ea200ca, 0xbe09e0cc, 0x3ed8b4cc, 0xbe37dffa, 0x3eba17c2, 0xbecd3af4, 0x3dfa0768, 0xbe162afb, 0x3e8c28d0, 0xbea2f4b5, 0x3e259552, 0xbd4ff47a, 0x3deba7d9, 0xbcda2de0, 0x3e82d495, 0xbe3a1843, 0x3e90a6e1, 0xbe23555a, 0x3e8f0959, 0xbda17677, 0x3ebd8b84, 0xbf0b5dde, 0x3dc3eca8, 0xbe264ef9, 0x3e0dfb28, 0xbec6e89f, 0x3d867695, 0xbc05f6c6, 0x3cc15a89, 0x3d7d9314, 0x3eeaeca2, 0xbe61c09e, 0x3e8a8119, 0xbdcf0300, 0x3eb7170f, 0xbc19745a, 0x3ec402a2, 0xbf02ead9, 0x3d31e00b, 0xbdf09f2e, 0x3ddd5180, 0xbede6b61, 0x3da42fd6, 0xbdeab752, 0xbd45daf2, 0x3d57812b, 0x3ec346a9, 0xbd12e422, 0x3e53ccf4, 0xbc8ff60e, 0x3ea5b06e, 0x3e9c34b9, 0x3ed3c79c}; uint32_t cell_out0_shape[] = {1, 2, 2, 4}; uint32_t cell_out0_values[] = { 0xbfd5981b, 0x3eab93df, 0xbeb6282e, 0x3e2b0ac4, 0xbf94f0fd, 0x3e9d97ae, 0xbe856685, 0xbdb00498, 0xbe5181d2, 0x3eaf261e, 0xbf2f0982, 0x3fcb5ba8, 0xbf0caf39, 0x3f471fab, 0xbf2da98a, 0x3fb4fadd}; zdnn_ztensor *input0 = alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (void *)input0_values); zdnn_ztensor *all_ts_out0 = test_layer(input0, h00_shape, (void *)h00_values, c00_shape, (void *)c00_values, weights0_shape, (void *)weights0_values, biases0_shape, (void *)biases0_values, hidden_weights0_shape, (void *)hidden_weights0_values, hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape, (void *)all_ts_out0_exp_values, cell_out0_shape, (void *)cell_out0_values, false, is_layer_bidir[0]); // second layer uint32_t h01_shape[] = {2, 2, 5}; uint32_t h01_values[] = {0x3fc827a5, 0x3fc7d2ab, 0x3fe27e59, 0x3ea84764, 0x3e9400d4, 0x3f8e916a, 0x3fca1262, 0x3e688b78, 0x3eb894e8, 0x3f6cf872, 0x3fbc6eee, 0x3da5ca40, 0x3f174faa, 0x3fe12bad, 0x3d2fc9e0, 0x3e7666b8, 0x3faea7a3, 0x3ee02d48, 0x3fc8ba6b, 0x3f940f37}; uint32_t c01_shape[] = {2, 2, 5}; uint32_t c01_values[] = {0x3e1a8538, 0x3f756c1c, 0x3fda8620, 0x3faac825, 0x3fa2beb7, 0x3f98b1e4, 0x3f67802a, 0x3d99f2f0, 0x3f724b2e, 0x3fcf0846, 0x3f72e100, 0x3f054054, 0x3f010382, 0x3ff4fbf0, 0x3f96e796, 0x3fdf1f5c, 0x3fb69da2, 0x3f23c3d0, 0x3fdae58c, 0x3f20d682}; uint32_t weights1_shape[] = {2, 8, 5}; uint32_t weights1_values[] = { 0x3e83aa94, 0xbea1a3c0, 0x3c6b9ce0, 0xbebfde02, 0x3ec1d528, 0xbd4e46b0, 0xbe62d375, 0xbe0d9648, 0xbe77c691, 0xbe76cf7f, 0x3e20904c, 0xbebc9a53, 0xbdc724ec, 0x3eca9984, 0x3e109bc4, 0xbee0a324, 0x3e6ef9a8, 0x3d737210, 0x3ed16702, 0x3e3b6830, 0xbec39102, 0xbd3aa670, 0x3e630230, 0xbed417e7, 0xbe0751fa, 0x3e55ae7c, 0x3eb037d8, 0xbea06a9a, 0x3ea17e98, 0x3e1940d8, 0xbe81b1a9, 0x3e8db48a, 0x3ec02c1a, 0x3e658114, 0xbe03c1e6, 0x3e5c50f0, 0x3e7d66c4, 0xbd472b98, 0x3e878898, 0x3e8d90bc, 0x3e7b0bac, 0xbecc0226, 0x3cbe6420, 0xbe927f99, 0x3aa69a00, 0x3e6e6210, 0x3e8ca274, 0x3da1fbe0, 0xbe9eba88, 0x3ecdd426, 0x3e8e02b2, 0x3d3f7208, 0xb9c68000, 0xbd938128, 0x3ee3b00e, 0xbe91fb37, 0x3cd35960, 0x3e13e288, 0xbda1fd74, 0xbe84a2b8, 0x3ee40ec6, 0xbe7d9782, 0x3ed942f8, 0x3e4bb92c, 0x3da325a8, 0xbe87ba02, 0xbe4018f0, 0x3df38580, 0xbe43be48, 0x3d586020, 0x3ee497e8, 0xbe05e5dc, 0xbe27a444, 0x3eb689d4, 0xbe56b587, 0xbedbbe59, 0xbedf0e3e, 0xbe3c776a, 0xbea0aa84, 0xbe1e37de, 0x3ec258fa, 0xbedc1c4e, 0x3ca711d0, 0x3cc4e590, 0x3e11fa20, 0x3cf049b0, 0xbede7c01, 0xbece783b, 0x3e592a78, 0x3e75d434, 0xbe989ba1, 0xbdb9cd1c, 0x3ebde4ee, 0xbeb798f6, 0x3d7f2f50, 0xbe24134e, 0x3e99f81e, 0x3e769414, 0xbe03b7b6, 0xbe9933c8, 0x3dc7ff90, 0xbed8b7ed, 0x3ee39938, 0xbee0d2e5, 0xbeb1870e, 0xbeae8cee, 0x3ebe51d8, 0x3e675c3c, 0xbe325de8, 0xbe0d48c0, 0x3e63833c, 0xbe37306c, 0xbe972362, 0x3dc59638, 0x3e4904fc, 0xbecfe0c1, 0x3e062014, 0x3ebf18f2, 0xbeb3c7f8, 0x3ee1dbc6, 0xbdcf25dc, 0xbeb5b12a, 0xbd48ccd8, 0xbe46414a, 0x3e24bcd8, 0x3d26cb70, 0x3cdf2e90, 0xbe101be0, 0x3eacd6bc, 0xbea06bf2, 0xbea00f51, 0x3eb58a42, 0xbeb81f6b, 0xbe3e8e36, 0xbdc54a50, 0x3ec2e956, 0xbe019774, 0x3941c000, 0xbe9f0e96, 0x3ec6a716, 0xbd6ccb78, 0x3e578a54, 0x3eac49a0, 0x3d8d0aa8, 0xbeafad22, 0xbea7780c, 0x3ec4c2fc, 0x3ec0e9e4, 0x3e893e48, 0xbe05d8ee, 0x3e061770, 0x3e97de7c, 0x3d2ae830, 0xbece70c1, 0x3e163290, 0xbea2cdd5, 0xbe703894, 0x3dd00540, 0x3ecefc06, 0xbec899a2, 0xbdfe1e6c, 0x3e0b5e64, 0xbaa00c00, 0xbde97700, 0x3d7ba930, 0xbe2ab878, 0xbddce6cc, 0xbe5ddf86, 0xbe95df9f, 0x3ebc4676, 0x3de69348, 0x3e208298, 0x3ee494f2, 0xbe2440b2, 0xbe9acddc, 0x3e226e48, 0xbea5ddf2, 0x3edfa1a6, 0x3dad0a60, 0x3caa1db0, 0xbe5fbd62, 0xbe86a497, 0xbeacb04b, 0xbe6f45de, 0xbe28e040, 0x3d21ed48, 0xbe68730d, 0xbeb99f2f, 0x3dcaf230, 0x3ee0b168, 0x3e84b2c0, 0x3ed26dd4, 0xbead8f69, 0xbdd20768, 0xbed93dd3, 0xbd3641c0, 0xbdf673cc, 0xbb0d5900, 0xbe5de779, 0xbedb8204, 0x3df812c8, 0x3ee2c0f8, 0x3dd6ac68, 0x3d6a6440, 0x3e478690, 0xbe9f3858, 0xbe0bfad6, 0x3c8a0b80, 0xbe376674, 0xbde0babc, 0x3d971e50, 0x3e78da1c, 0x3e9124d4, 0xbe1ad584, 0x3e462330, 0x3e462a34, 0xbe02fc74, 0xbdb961b8, 0x3def8690, 0x3ea8f792, 0xbe347690, 0xbd85c98c, 0x3d37b120, 0xbda59be8, 0x3ca89770, 0x3ebe31d8, 0xbd9b37b0, 0xbe2a5a0c, 0x3e95a0ea, 0x3db33be0, 0xbcf119f0, 0xbb361500, 0xbebfc12d, 0x3ccf8430, 0x3c851e40, 0x3e4fc6b8, 0xbe2cff70, 0x3e3950e8, 0x3e2cfbb8, 0x3e9e88a0, 0x3ee1a07c, 0xbedeee8a, 0x3eb369f6, 0xbe19b22c, 0xbd0ab3d0, 0xbe90de80, 0xbe872d40, 0x3e662ae4, 0xbed457d0, 0xbe6741db, 0x3daf9920, 0xbe1c1d3a, 0x3ec2326c, 0x3e3bb9b4, 0x3db92198, 0xbd1e1828, 0x3e667240, 0x3e8472c6, 0x3edee626, 0x3e2de8c8, 0xbdc0f07c, 0xbe942d27, 0xbe0aeb80, 0xbe025ea8, 0x3eb61b5a, 0xbdcc9010, 0x3ed7e74a, 0xbe97eae2, 0xbebd9868, 0x3eb1c556, 0x3e917fbc, 0xbdcbff10, 0xbd084a60, 0xbecfb148, 0xbd891828, 0x3caf1b90, 0xbda475ac, 0x3ebd81c8, 0x3de585b8, 0xbec9e6b4, 0xbe4157cc, 0x3e8ad580, 0xbd7cdcb8, 0x3eaf736e, 0x3e858166, 0xbe736e40, 0x3ee2894e, 0x3dc70f30, 0x3ede9074, 0x3e75fc90, 0x3e478d4c, 0x3db95270, 0x3d74a7f0, 0xbe87d88c, 0x3e7e8034, 0xbec7475c, 0xbcf41780, 0xbdacfd44, 0xbce470b0, 0xbeb5ea1e, 0x3beaf1c0, 0x3ee163d0, 0xbee4efd6, 0xbe377cb8, 0x3d405f70, 0xbe529b09, 0xbe43b460, 0x3cbb9700, 0xbed30845, 0x3ed51bde, 0x3e97214e, 0xbd12c9a0, 0xbc590b60, 0xbea69d53, 0xbe7f92d8, 0xbed52ee3, 0xbe488982, 0x3d89c8b8, 0x3ed6e7ce, 0x3ecbb182}; uint32_t biases1_shape[] = {2, 5}; uint32_t biases1_values[] = { 0xbea9c5c8, 0x3dd289d0, 0x3d851878, 0xbe5655f7, 0x3e1f747c, 0xbe134938, 0x3ad25d00, 0xbdb01a08, 0xbd1bbbd0, 0xbeb29254, 0x3e935dc2, 0x3ed8df8e, 0x3d1ef258, 0xbed5df49, 0x3ea0bcaa, 0x3daba420, 0xbe13420a, 0x3e9b1762, 0x3cc83240, 0x3dabe7d8, 0xbecccd1f, 0x3dd09a78, 0xbe91286a, 0xbd4613f0, 0x3d6b9ee0, 0xbb343e80, 0xbebe0edb, 0xbdc50970, 0x3e84b35e, 0xbe9f3779, 0x3ec31294, 0xbe5a7ee4, 0x3e92b048, 0xbd68b2e8, 0xbe597ddb, 0xbe9a5704, 0xbddfa3c0, 0xbdfb13dc, 0x3d9b0ca0, 0x3d980d78}; uint32_t hidden_weights1_shape[] = {2, 5, 5}; uint32_t hidden_weights1_values[] = { 0x3d81ac10, 0x3dd8c630, 0xbd97418c, 0x3e10ce08, 0xbed605fa, 0x3ec2d2d6, 0xbedf67a9, 0xbed0b705, 0x3d2a1fb8, 0xbeac7e7c, 0x3d763d80, 0xbe025fa2, 0xbce64df0, 0x3e2abb28, 0x3e4679ac, 0xbe53df41, 0xbe9bf81e, 0x3e8fcc58, 0xbddf28c4, 0xbe879404, 0x3ed89bd2, 0x3ec8c0ca, 0x3dedf310, 0xbe362bda, 0x3d836668, 0xbea63515, 0xbed34fff, 0xbeb2cae3, 0xbedc6d5d, 0xbec0db92, 0x3e49d700, 0x3e8c699a, 0x3ead673e, 0x3e9acf32, 0x3ea5bbea, 0x3d79a270, 0x3e92763a, 0x3e0fb304, 0x3ecb49b0, 0xbed82f3e, 0x3e5f5638, 0xbecf279c, 0x3ee267e6, 0x3e8c4992, 0x3dcc9cb0, 0xbee4ae25, 0x3e2dd470, 0xbee1c411, 0x3e983a74, 0xbe95fc4a, 0xbecee7d6, 0x3ed4086e, 0xbe9d7ac6, 0xbe53d7b8, 0x3ebee346, 0x3ed5ca40, 0x3ed8ea94, 0x3ed8d474, 0xbe618c84, 0xbe4a029f, 0x3e4a7010, 0x3ecebb20, 0xbe44c542, 0xbd203aa8, 0x3e2270c4, 0x3e479f54, 0xbec12893, 0xbe5113e1, 0xbd301208, 0x3ec72844, 0xbec61cd1, 0xbe2ccb44, 0x3e6fec98, 0xbeb25d85, 0x3e66f338, 0x3df0bb68, 0xbce89ee0, 0x3ed04f64, 0xbe2a0094, 0x3d93c7f8, 0x3ea117be, 0x3e18bfa8, 0x3e99bb1e, 0xbd4da508, 0x3ddd3e70, 0xbe442dc0, 0x3e0955f0, 0x3ea0fb84, 0xbe7777df, 0x3ec92466, 0x3e531f20, 0x3ebf9b54, 0xbd6c5ae0, 0x3e6a16c8, 0x3e26cc6c, 0xbecafb69, 0x3ee10096, 0xbeb1b1ae, 0x3e20c074, 0xbec8cbb7, 0x3e122c34, 0x3ebc54aa, 0x3ec058f2, 0x3ed2d41c, 0x3ea85d6a, 0x3d01b298, 0xbeb62674, 0xbe9d91cb, 0xbe5a9fca, 0xbeb1737d, 0xbe94746f, 0xbddc5118, 0xbec0490a, 0x3e23c650, 0x3d428f68, 0x3edaf946, 0x3e791bd4, 0xbe4e7f38, 0xbde59ef4, 0x3ed75422, 0xbe8525dc, 0xbe3b1bb2, 0x3d940df8, 0xbdc69f70, 0xbd7bb5b8, 0xbe35e4f4, 0xbed7e492, 0xbebb3390, 0xbe7a2866, 0x3ed07d84, 0x3da22d18, 0x3e316444, 0xbeb70a96, 0x3e185bfc, 0xbee1383b, 0xbe340e34, 0xbe41d6c8, 0x3e8902e6, 0x3ca49640, 0xbee3b077, 0xbd90ea54, 0xbe8b4e16, 0x3e68bf70, 0xbea3a41a, 0x3d6ab290, 0xbed906ca, 0xbe34b29a, 0x3d740020, 0x3dc51748, 0x3eac6c0c, 0x3eb1c89c, 0xbda0df98, 0xbc914780, 0xbd4637a8, 0xbebdb332, 0xbe0d071e, 0x3e1469e4, 0x3e9ccdb4, 0xbcc4c620, 0x3e62e8b8, 0x3eb8509c, 0x3e33aa40, 0xbdf7d0f0, 0x3e4c5720, 0x3e08fc84, 0xbedd7e2d, 0x3eafcf42, 0x3ec8b9ca, 0x3e9c8b2a, 0x3e37f4f4, 0xbd840080, 0xbd88748c, 0xbe987408, 0xbd912c2c, 0xbe8d3f0b, 0xbe8b53f4, 0x3ee473e2, 0x3ec9ef0c, 0x3dcb4df8, 0xbd1b6dd0, 0x3dc99f48, 0x3e952b7e, 0xbee3d029, 0xbe794ffd, 0xbe19d608, 0x3ea0f704, 0xbe80c7e3, 0x3e77fb08, 0x3d81cb10, 0x3e85eb20, 0x3e0d3144, 0x3d1e5550, 0xbe04f4de, 0xbe94a906, 0x3d1deee8, 0x3dc63590, 0x3e69f3cc, 0xbee03730, 0xbeac4f21, 0x3eb2ba24}; uint32_t hidden_biases1_shape[] = {2, 5}; uint32_t hidden_biases1_values[] = { 0x3df84f58, 0x3e9ba3fc, 0x3ec36c40, 0x3eb9b38a, 0xbea9a47a, 0xbd059ee0, 0xbe847d16, 0x3e03a480, 0x3e826528, 0xbe8f0d14, 0xbec763d2, 0xbed21657, 0x3edf9e2a, 0xbde46c64, 0x3cb6fdc0, 0x3e683924, 0xbe9dbc3c, 0xbd014578, 0x3e801014, 0x3ec60e30, 0xbd92bdd4, 0xbe877dfe, 0xbe82d308, 0x3dd941a0, 0x3ed6ece6, 0xbe84df2a, 0x3e4a6960, 0xbd005890, 0xbed843d9, 0xbe8405ca, 0xbeb76e74, 0x3e8a9360, 0xbe6d6e1d, 0xbdb26478, 0x3eb5c09c, 0x3e39b660, 0xbe1b530c, 0x3e9e0b48, 0x3eb50338, 0x3d853c28}; uint32_t all_ts_out1_shape[] = {5, 2, 2, 5}; uint32_t all_ts_out1_exp_values[] = { 0xbdd1fa2b, 0xbd3f4ead, 0x3e0461ac, 0x3ee96b3b, 0x3eb74b45, 0x3e90e20c, 0x3cc3de88, 0xbe6c0e8e, 0x3e8982be, 0x3e9c9c61, 0xbcc322be, 0xbde8fc7c, 0xbd1c8d3e, 0xbd2b6c1d, 0xbe42fb01, 0x3c57f78f, 0xbdc04b1a, 0xbd33a392, 0xbb95a554, 0xbe5066f9, 0xbd9fc1a4, 0xbe477008, 0xbdf132ab, 0x3e9bcf26, 0x3eb93873, 0x3ddaf977, 0xbdd3166c, 0xbe619ffb, 0x3e4adfd0, 0x3e9fccd2, 0xbcc2dbcd, 0xbdf980ee, 0xbccdb7ad, 0xba30c49d, 0xbe42c10d, 0x3b83d9f7, 0xbdcf460e, 0xbd25edf3, 0x3ccf389e, 0xbe583262, 0xbdab0f55, 0xbe7eb2ff, 0xbe4f90b5, 0x3e3ad707, 0x3eaa53e0, 0x3bddcfca, 0xbe1775a7, 0xbe7ea785, 0x3dfb50db, 0x3e94d66d, 0xbd37abbd, 0xbe0e311e, 0x3b99893a, 0x3d3ff63a, 0xbe32a8f4, 0xbc20a1ff, 0xbdd2936b, 0xbca7aae4, 0x3dceaf3e, 0xbe526074, 0xbda8f646, 0xbea1ae04, 0xbe7407c4, 0x3de07121, 0x3eab13d6, 0xbd35fd1d, 0xbe3dd8b8, 0xbe8900d2, 0x3d99c517, 0x3e8fad14, 0xbd509783, 0xbe25d588, 0x3d1331e9, 0x3e1c1ebc, 0xbdde9924, 0x3cc65017, 0xbdb670f0, 0x3b42adb7, 0x3e92ec47, 0xbe359c1f, 0xbdb2ab28, 0xbea20225, 0xbe84c3cf, 0x3d93e6e6, 0x3e9ee28e, 0xbd8f777c, 0xbe39d1e1, 0xbe997113, 0x3d0e7f2b, 0x3e6fee78, 0xbc9bfb45, 0xbe70f085, 0x3da7354e, 0x3e8801bd, 0x3db26c6d, 0x3e37c0bd, 0xbc2f97f7, 0x3d7034b4, 0x3e824266, 0xbde7ae61}; uint32_t cell_out1_shape[] = {1, 2, 2, 5}; uint32_t cell_out1_values[] = { 0xbe64bd12, 0xbf184520, 0xbf34c5c0, 0x3e25569a, 0x3f2f7ae7, 0xbe274afb, 0xbeabac90, 0xbf47b603, 0x3db135ad, 0x3f08b30b, 0xbd87fabc, 0xbe95e9f6, 0xbd845920, 0xbd816afa, 0xbebb7434, 0x3d1341a1, 0xbe8512e6, 0xbd941748, 0xbbe9b318, 0xbeb82cf6}; zdnn_ztensor *all_ts_out1 = test_layer( all_ts_out0, h01_shape, (void *)h01_values, c01_shape, (void *)c01_values, weights1_shape, (void *)weights1_values, biases1_shape, (void *)biases1_values, hidden_weights1_shape, (void *)hidden_weights1_values, hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape, (void *)all_ts_out1_exp_values, cell_out1_shape, (void *)cell_out1_values, is_layer_bidir[0], is_layer_bidir[1]); free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1); } void lstm_bidir_to_fwd() { // num_timesteps = 5 // num_batches = 2 // num_features = 4 // num_hidden = 5, 4 bool is_layer_bidir[] = {true, false}; // first layer uint32_t input0_shape[] = {5, 2, 4}; uint32_t input0_values[] = { 0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a, 0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e, 0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0, 0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48, 0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8, 0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b, 0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80}; uint32_t h00_shape[] = {2, 2, 5}; uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f, 0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4, 0x3fb8c472, 0x3f849e59, 0x3eb88b80, 0x3bc03f00, 0x3f1a65ee, 0x3f5d6a8e, 0x3ea8b604, 0x3fcb5de0, 0x3f504bc2, 0x3fe33d36, 0x3fd8b70c, 0x3fc21f69}; uint32_t c00_shape[] = {2, 2, 5}; uint32_t c00_values[] = {0x3f0c2aba, 0x3f190c04, 0x3fcbd235, 0x3f32a91c, 0x3ee6ed24, 0x3f9027e4, 0x3f7639bc, 0x3f44af00, 0x3ec25e00, 0x3d230b80, 0x3fe2a3cb, 0x3faee87b, 0x3f1b63b4, 0x3e2f90c0, 0x3e04e860, 0x3df0eef0, 0x3f4d0d62, 0x3fef4e7c, 0x3f68732e, 0x3fd013d6}; uint32_t weights0_shape[] = {2, 4, 5}; uint32_t weights0_values[] = { 0x3ed76812, 0xbeda1e9d, 0xbcc9dc90, 0xbe8b56d8, 0xbde3f398, 0x3e9a494e, 0xbc03b300, 0x3d898450, 0x3ecfc37a, 0x3ca54f60, 0xbe47ad20, 0xbeac6e30, 0xbe3b8b06, 0x3e9cea58, 0x3d85a140, 0xbde68434, 0xbeb09ec1, 0x3e87de1e, 0xbec116de, 0x3dd939f0, 0x3d190310, 0x3e9e8ea0, 0x3e55de1c, 0x3ee46d12, 0x3eace9cc, 0x3d64ba10, 0x3ece54c0, 0xbe5ec821, 0x3e915990, 0x3ee4e29a, 0xbeb401c3, 0x3e86944e, 0xbebdbf60, 0xbe9e462c, 0x3ec83690, 0x3d0ff4f8, 0x3d757710, 0xbec4e626, 0x3e332b14, 0x3eb165e2, 0xbed56486, 0x3dab6e00, 0x3e301b34, 0x3ea3ea60, 0x3e64a8e0, 0x3ecb70ec, 0xbd9a4a9c, 0xbe879f2a, 0x3e2b3b3c, 0x3dbfb2a0, 0x3eae1a26, 0xbd96b870, 0x3e27e118, 0xbee29f7d, 0xbeb29e53, 0xbee46847, 0xbe51a0d6, 0x3e67965c, 0xbe9488c8, 0xbe83d8ea, 0xbe5cf1d4, 0x3db3dd28, 0x3e354500, 0x3e1f0c64, 0xbe6f1e1b, 0x3da48928, 0xbeaa02a3, 0xbd669538, 0xbe271822, 0x3b9084c0, 0xbe6de235, 0x3d987eb0, 0xbebbb5a4, 0x3e2dd3f4, 0x3e3d5c4c, 0x3dd306b8, 0x3e430d88, 0xbd8d3050, 0x3e987cda, 0x3d0f9250, 0x3e33b614, 0xbedba477, 0xbe20347e, 0xbe952b16, 0x3c4ba340, 0x3cdb72e0, 0xbe87b6cc, 0xbebbabe9, 0xbcbc0320, 0xbd1e06b8, 0xbe5f7204, 0xbde54684, 0xbdc2d30c, 0x3ea3e928, 0x3db95c18, 0x3e58b204, 0xbe5f126c, 0x3dc3c730, 0xbd3c4ee0, 0x3e91971e, 0xbdd1fa20, 0xbe89ca96, 0xbe8f83dc, 0xbda4ce70, 0xbe1b9f76, 0xbe20b66c, 0x3ecdd9da, 0x3e036284, 0x3e3248cc, 0x3e5f481c, 0x3ebbff92, 0x3e5d42c8, 0xbe2089f6, 0x3da2aec0, 0xbe9fee66, 0x3e804fe0, 0x3e79a49c, 0x3eb2e8ec, 0x3e42d780, 0x3dcedbf0, 0x3ed8e4e6, 0xbecdb113, 0xbe639ee9, 0xbdb9c6e0, 0x3e8ed458, 0x3e916930, 0xbe591a24, 0xbeaf7709, 0x3e7b2408, 0xbeb32c7f, 0x3ed963f2, 0x3e9be8be, 0xbed64902, 0x3e7795b4, 0xbdc1a118, 0xbd047a58, 0xbb3dfe00, 0xbec14162, 0xbedcd447, 0xbe39af54, 0xbe9aebe8, 0x3e77c3f8, 0xbe9c4230, 0xbead1b0c, 0x3ebc5350, 0xbee1e40d, 0x3ed6d390, 0xbd93fe10, 0xbe5f6ed0, 0x3ebb7968, 0xbeb7e0dd, 0x3eb76f78, 0xbe94b3e4, 0xbedd358e, 0x3ea3e864, 0x3eb4c482, 0xbecc7bce, 0x3e9eff90, 0xbe81ffa5, 0x3eb0cbec}; uint32_t biases0_shape[] = {2, 5}; uint32_t biases0_values[] = { 0xbe18ef8e, 0xbdfff1d8, 0x3e074a8c, 0x3ebc395c, 0x3df90638, 0x3eb037d8, 0x3e8db48a, 0x3e7d66c4, 0x3c6b9ce0, 0xbe0d9648, 0xbe83e971, 0x3e83a64e, 0x3e72843c, 0x3eafbdf8, 0x3e261b9c, 0xbea1a3c0, 0xbe62d375, 0xbebc9a53, 0x3e6ef9a8, 0xbd3aa670, 0xbe58ace5, 0xbe574539, 0xbed87cba, 0x3dc5e080, 0xbe807ef0, 0xbdc724ec, 0x3d737210, 0x3e630230, 0xbea06a9a, 0x3ec02c1a, 0xbecc25a9, 0x3ec8c806, 0xbe94b2a7, 0xbd506310, 0x3e0332e4, 0xbd472b98, 0xbebfde02, 0xbe77c691, 0x3eca9984, 0x3ed16702}; uint32_t hidden_weights0_shape[] = {2, 5, 5}; uint32_t hidden_weights0_values[] = { 0x3e21ba5c, 0x3eb5ccc2, 0xbe7c17a9, 0x3c9a1ea0, 0x3ea04420, 0xbddc3fcc, 0x3e9cab54, 0xbe856c8e, 0x3e9399fc, 0xbe249da6, 0xbdc09e0c, 0xbea1834a, 0x3e1c8044, 0xbead15e7, 0x3ec122ee, 0xbebcb154, 0x3ca36520, 0xbe8872c0, 0xbe9d3169, 0x3e2598d4, 0x3e7822c0, 0xbea16940, 0xbc1fdba0, 0xbe84f4be, 0x3d67f3b0, 0xbeadd2f6, 0xbe8219a4, 0xbe190f96, 0x3cc42620, 0xbed14480, 0x3edb2580, 0xbd8f889c, 0xbdf89d64, 0xbe8d6097, 0xbda3e468, 0x3eade05a, 0x3ec26bea, 0xbdb0b3c4, 0x3cbbc620, 0xbeaa2909, 0xbe26eada, 0x3c976030, 0x3d2f4d98, 0x3e5b9460, 0xbe436636, 0x3e80b7ea, 0xbea1ef22, 0x3ed3c2e8, 0x3e6328f4, 0x3e24fec4, 0xbdb06a40, 0x3bbd8300, 0x3ec95d16, 0x3e90def0, 0x3d448f50, 0xbdb3d438, 0xbe5008a0, 0xbe3acaf4, 0xbd5360c8, 0xbdbfc268, 0xbecd7820, 0x3e2c8218, 0x3ecec37e, 0xbe4c6e38, 0x3ea38344, 0xbec5b44b, 0xbece16e2, 0x3e25d8dc, 0x3eb7196c, 0x3dffaaa8, 0xbd8f518c, 0xbcf73e90, 0xbecea3b7, 0xbeb90843, 0x3e5c0bbc, 0x3ecb999a, 0x3ee4e636, 0x3d527bf8, 0x3e99b77e, 0x3e926d0a, 0xbdea86c4, 0x3e6d851c, 0xbddabb30, 0x3ea2c8c8, 0x3d082a00, 0x3e497f5c, 0x3e8e5746, 0xbe811315, 0xbd507b08, 0xbe58367b, 0x3ecbffd4, 0xbe20471c, 0xbe807b12, 0xbe8480f1, 0x3ed26ffe, 0x3e177f54, 0x3e5bbc44, 0xbeb030cc, 0x3eb0f98a, 0x3e3b45e4, 0xbb5a2c80, 0x3d69b920, 0xbd0388a0, 0x3e62db50, 0x3ba04b00, 0xbdb50e24, 0xbeb31aa8, 0x3ee28262, 0xbea317e4, 0x3ebcdbe4, 0x3d65d3e0, 0xbe700636, 0x3e256d64, 0xbe01fea6, 0x3d64ada0, 0xbdd123b0, 0x3eb8e4f2, 0x3c4f7420, 0xbe19a60a, 0x3ecd16fc, 0xbb4def80, 0xbeb9d294, 0xbec66e3b, 0xbd87a1dc, 0x3e8c10dc, 0xbea299d4, 0xbe24134e, 0xbedc1c4e, 0x3ebe51d8, 0x3ebde4ee, 0x3e2a3b28, 0x3dc7ff90, 0xbede7c01, 0xbe37306c, 0x3e769414, 0x3ec258fa, 0xbeae8cee, 0xbdb9cd1c, 0x3e062014, 0x3ee39938, 0x3cf049b0, 0x3e63833c, 0x3e99f81e, 0x3ca711d0, 0x3e675c3c, 0xbe989ba1, 0xbecfe0c1, 0xbed8b7ed, 0xbece783b, 0xbe972362, 0xbe90c29a, 0x3e1735dc, 0xbedd7037, 0xbe71302b, 0xbe295dd2, 0x3e4d6418, 0x3eabc840, 0x3ea58b16, 0x3d721bf0, 0xbee2f252, 0xbea1dc41, 0xbe136b9a, 0xbebd57dc, 0x3ebd57a4, 0x3e4eb6e0, 0xbe4216de, 0x3a3bae00, 0x3bc9f900, 0xbe05dde4, 0xbe5bef69, 0x3e06b148, 0x3e6bc304, 0xbd9bb79c, 0xbe87f0ac, 0xbe98cd9b, 0x3ebf18f2, 0xbee0d2e5, 0x3e75d434, 0x3e4904fc, 0xbee0a324, 0x3cc4e590, 0xbe325de8, 0x3d7f2f50, 0x3ee1dbc6, 0xbec39102, 0x3e592a78, 0x3dc59638, 0xbe9933c8, 0x3e83aa94, 0x3e55ae7c, 0xbeb798f6, 0xbeb3c7f8, 0xbeb1870e, 0xbd4e46b0, 0xbe81b1a9, 0xbe03b7b6, 0x3e11fa20, 0xbe0d48c0, 0x3e20904c, 0x3e5c50f0}; uint32_t hidden_biases0_shape[] = {2, 5}; uint32_t hidden_biases0_values[] = { 0x3ebdf640, 0xbe1985b8, 0x3e06e404, 0xbdd1716c, 0xbca2ec60, 0xbe76cf7f, 0x3e109bc4, 0x3e3b6830, 0xbe0751fa, 0x3e1940d8, 0x3c696e40, 0xbe9a126e, 0xbeb9158a, 0x3eb682ba, 0x3d952498, 0xbed417e7, 0x3ea17e98, 0x3e658114, 0x3e878898, 0x3ec1d528, 0xbe8b7474, 0x3e1ae0c4, 0x3e10c984, 0xbc172600, 0xbdcdfc84, 0xbe03c1e6, 0x3e8d90bc, 0xbdfe1e6c, 0xbe2ab878, 0x3de69348, 0xbe8d2560, 0x3e9e5868, 0xbeaa740b, 0x3e3b9ae0, 0xbe19fc78, 0x3e226e48, 0xbe5fbd62, 0x3d21ed48, 0x3e84b2c0, 0xbd3641c0}; uint32_t all_ts_out0_shape[] = {5, 2, 2, 5}; uint32_t all_ts_out0_exp_values[] = { 0x3dd6eff8, 0xbda76b31, 0x3c6ef7c1, 0x3a8b388f, 0x3dae9ed6, 0x3e89e8f4, 0xbb4586cb, 0xbc9f3675, 0x3cc8b2ea, 0x3dfe784b, 0x3dbb39fe, 0x3edafae8, 0xbd3c005a, 0xbe072b73, 0x3ef9a34c, 0xbc786331, 0x3eafda4e, 0xbdad66db, 0xbe976dfa, 0x3ee8b575, 0x3c002849, 0xbe597b0f, 0xbcc51dc1, 0x3d32e3f7, 0x3e51f770, 0x3e959d05, 0xbe4629d9, 0xbd0f892a, 0xbb62976b, 0x3de59bf1, 0x3dac9b77, 0x3ee69149, 0xbd32d750, 0xbe094cd1, 0x3f0894c9, 0xbb945ae6, 0x3ec70e1c, 0xbd0701f9, 0xbe079847, 0x3f19f4f5, 0xbdb2f5c6, 0xbe6a4e4b, 0xbd405672, 0x3dd3f4cc, 0x3e178532, 0x3b19974b, 0xbe5f5abf, 0xbdc69fcb, 0x3df1954a, 0x3d01bdbf, 0x3e1c36e6, 0x3ec6ffdf, 0xbbd5b4c9, 0xbd7a61de, 0x3f084cd4, 0xbbf96418, 0x3e21a121, 0x3ca90e88, 0xbe61fed1, 0x3f0518e3, 0xbd13ed8d, 0xbe3bded3, 0xbd99b60d, 0xbd102e12, 0x3dfeec81, 0xbe1233ea, 0xbe61b886, 0xbd95006c, 0x3dfef1ce, 0xbd3d39b1, 0x3e843fa8, 0x3e94e115, 0x3d84b656, 0x3cbd3390, 0x3f0ea868, 0xbc26d2c6, 0x3e28e672, 0x3d9b7799, 0xbc5c9196, 0x3f3aef4b, 0xbd8473f6, 0xbe51d0bc, 0xbd172f10, 0xbb8eeb58, 0x3dcde949, 0xbddf3a74, 0xbe4f4c2e, 0xbe02e647, 0xbca72b3d, 0xbdb6fbf5, 0x3e44f9ce, 0x3ee3b9b2, 0x3d5241b9, 0x3d90a145, 0x3ee73202, 0xbc911f4e, 0xb9c44b8a, 0x3e04e5ab, 0x3e8f7fe2, 0x3f11f168}; uint32_t cell_out0_shape[] = {1, 2, 2, 5}; uint32_t cell_out0_values[] = { 0xbdb0381d, 0xbec713e6, 0xbf77a646, 0xbc19d620, 0x3e8fb6a4, 0xbe499947, 0xbecf624a, 0xbf4b69e0, 0xbd2dd5de, 0xbe1f50a7, 0x3e71bac2, 0x3fe517ec, 0xbdfa26c5, 0xbedb0254, 0x3f1f2b76, 0xbd5f952c, 0x3f279d82, 0xbe9c2544, 0xbf4a2172, 0x3f1eaed8}; zdnn_ztensor *input0 = alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype, NO_CONCAT, false, (void *)input0_values); zdnn_ztensor *all_ts_out0 = test_layer(input0, h00_shape, (void *)h00_values, c00_shape, (void *)c00_values, weights0_shape, (void *)weights0_values, biases0_shape, (void *)biases0_values, hidden_weights0_shape, (void *)hidden_weights0_values, hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape, (void *)all_ts_out0_exp_values, cell_out0_shape, (void *)cell_out0_values, false, is_layer_bidir[0]); // second layer uint32_t h01_shape[] = {1, 2, 4}; uint32_t h01_values[] = {0x3f32172c, 0x3f9edf37, 0x3f2645a8, 0x3fdcb8f3, 0x3fcb4487, 0x3fc0f8ba, 0x3da5dda0, 0x3fa27159}; uint32_t c01_shape[] = {1, 2, 4}; uint32_t c01_values[] = {0x3f805978, 0x3fbe03f3, 0x3ae02000, 0x3cbf1e40, 0x3fe08930, 0x3fe7c408, 0x3fe105ea, 0x3f809e08}; uint32_t weights1_shape[] = {1, 10, 4}; uint32_t weights1_values[] = { 0xbe2bd65c, 0x3dcefba8, 0xbedd7f20, 0x3e861f28, 0xbeed681e, 0x3e426fc0, 0x3eed0f5e, 0xbe6cd8e8, 0x3e51e224, 0x3ecb9a06, 0x3ef28514, 0xbe7c2bdc, 0x3ef9356c, 0x3ec6c0fc, 0x3ee721da, 0xbd332440, 0xbe11c200, 0xbd9946b0, 0xbed7f530, 0xbd44da50, 0xbed3f95a, 0xbee1bb7e, 0xbe413088, 0xbec76b22, 0xbee83510, 0xbee753d8, 0xbeb0114a, 0x3ed56b46, 0x3e004e90, 0x3eef0648, 0x3ef26c56, 0xbe61dab4, 0xbd1b12f0, 0x3e625510, 0xbe5bff04, 0x3e359d30, 0xbe8146d8, 0x3e5f2f40, 0xbe69c184, 0x3edeaa24, 0xbe0282c4, 0xbead1388, 0xbdd7b678, 0xbde41328, 0xbea7904e, 0x3cbe3200, 0xbde4b548, 0xbdb7df18, 0xbe37a3e0, 0xbe3ccf20, 0x3ea2ac3c, 0x3ec89742, 0x3dc17718, 0x3efb36e4, 0x3cc3c6c0, 0x3e80aae6, 0xbe85c1f4, 0xbef2e226, 0xbef93ece, 0x3ed91e6a, 0x3de2e688, 0xbef56ad2, 0xbe9721d8, 0x3e9414ee, 0xbdead1c8, 0x3efc4230, 0xbe2e8a7c, 0xbe1b5134, 0xbe7818b0, 0xbea1f7f8, 0x3e80d2ca, 0xbea9d954, 0x3d8caec8, 0x3dc45320, 0xbea5aa8e, 0xbd1860a0, 0x3ed27f84, 0xbd30c140, 0x3ef1632e, 0x3ed3e00e, 0x3e811ae2, 0x3ee072e2, 0xbe4bac78, 0xbe94dd26, 0x3d90fa50, 0xbda91c00, 0xbeef490e, 0x3ed28f66, 0x3ed9d1c4, 0xbee959b2, 0xbec0dab0, 0xbecba66e, 0x3d89a708, 0xbd00be80, 0x3e5de6f0, 0xbdf65258, 0xbe6ce154, 0x3ea0c574, 0xbe9794be, 0x3e8b418a, 0x3ef22d06, 0x3e050490, 0x3d92e8e0, 0xbe51317c, 0x3df25c60, 0x3e21e58c, 0x3e236d10, 0x3ed70d0e, 0xbef9c638, 0x3d3e3450, 0x3d1101a0, 0xbeb02b06, 0xbe11c318, 0x3e3ee218, 0xbea5fa40, 0xbed6fb44, 0xbeae60fe, 0xbdf97fe8, 0x3ef4d1f0, 0xbe66dee0, 0x3da587b0, 0xbd8cb5c8, 0xbd988fc8, 0xbda24ed0, 0x3eebb6a8, 0x3ec6c4a6, 0xbca26d60, 0xbed4174e, 0xbe746de4, 0xbe1dac84, 0x3eaf4fca, 0x3e7db128, 0x3e371b0c, 0x3ece1200, 0xbe0a8890, 0x3e1927cc, 0xbe005cac, 0xbef7a2f6, 0x3ee06b10, 0x3e4dab88, 0xbdde1128, 0xbd939528, 0xbeaa72aa, 0xbe9deb0a, 0x3ebc3cd8, 0xbdb3dca8, 0xbd5d9d20, 0x3ea4c2ae, 0xbec6657a, 0x3e25ee78, 0xbcdc0000, 0x3ef278c0, 0x3d598660, 0x3e48df24, 0x3e6475a0, 0x3d31b530, 0x3ef0bea8, 0x3ec48fa6, 0x3eaf0566, 0xbeef1dcc}; uint32_t biases1_shape[] = {1, 4}; uint32_t biases1_values[] = {0x3e382eac, 0xbeb35b5c, 0xbddc93c8, 0x3ede19b8, 0x3d9db078, 0x3e997152, 0xbee6ceb4, 0x3ee76a6a, 0xbec4697e, 0xbe15a55c, 0x3e27ed08, 0xbee0471c, 0x3e8c56b8, 0x3e85429c, 0x3e9ec5ca, 0xbea3364a}; uint32_t hidden_weights1_shape[] = {1, 4, 4}; uint32_t hidden_weights1_values[] = { 0xbedeecba, 0x3ccc9720, 0x3ecf9ed2, 0xbe92441c, 0xbeeae27c, 0x3e0acf3c, 0xbebdaa84, 0x3df2e668, 0x3efa0328, 0x3eae02ee, 0xbda40fe0, 0x3ef04b3c, 0xbdff6298, 0x3eda7d48, 0xbe977c1e, 0xbecd1526, 0x3eb3b59c, 0xbe6fa27c, 0xbea24a9c, 0xbe74491c, 0xbebdcfc0, 0x3e3246b0, 0xbd5d7530, 0x3ea400ba, 0x3deb6398, 0xbee4f98a, 0x3d83b748, 0xbd821528, 0x3d94ce30, 0x3de939c8, 0x3eda1908, 0xbe7329bc, 0x3e9aeeae, 0xbde79930, 0xbd845f50, 0xbecb234c, 0xbe84ba3c, 0x3d3a7b70, 0xbebb3c68, 0x3cf98660, 0xbdc772e8, 0xbeb2f3cc, 0x3e15eb3c, 0x3ecaf7cc, 0x3ecb3492, 0x3ed9eaec, 0xbeb6053c, 0xbe10e348, 0x3e70fb40, 0xbd608060, 0x3ec09f96, 0xbe5da7e8, 0x3edbfc7a, 0xbe211e60, 0x3ed7af1a, 0x3ec13d5a, 0x3ea9cb78, 0xbecddb00, 0x3d3f1470, 0xbe550c2c, 0xbe8649a2, 0x3958a000, 0x3de892f0, 0xbeb1d4c4}; uint32_t hidden_biases1_shape[] = {1, 4}; uint32_t hidden_biases1_values[] = { 0xbee4169c, 0x3e9d3bf8, 0x3d560ae0, 0x3cec4ba0, 0x3efef9ec, 0xbe97bf38, 0x3eff933e, 0xbef5ae46, 0xbe8dc31c, 0xbe56c57c, 0xbe15b3d0, 0xbef96240, 0x3cd4dd20, 0x3db51a80, 0xb9ddf000, 0x3e255720}; uint32_t all_ts_out1_shape[] = {5, 1, 2, 4}; uint32_t all_ts_out1_exp_values[] = { 0x3d83a5ef, 0x3ec5ab29, 0xbe96f2a9, 0xbdf8dcd8, 0x3de2bd50, 0x3ed99a83, 0x3e415f85, 0x3cfbc484, 0xbe8c59a2, 0x3e5053ab, 0x3c0308c4, 0xbe9ffe19, 0xbe8faac0, 0x3e83c5a5, 0x3e14e22c, 0xbe1cad7e, 0xbec9f76f, 0xbd0a8fd7, 0x3e1e0707, 0xbebd7c2d, 0xbecd1305, 0x3c73fc9e, 0x3e550bbb, 0xbe8989fa, 0xbedd0f9f, 0xbe0144b8, 0x3e53529a, 0xbebd2a6c, 0xbef77903, 0xbe2d44ac, 0x3e92e511, 0xbea59a45, 0xbee650d7, 0xbe2e4cba, 0x3e64bf3b, 0xbecdd76e, 0xbefc2978, 0xbe72658c, 0x3e8fef57, 0xbeb46b98}; uint32_t cell_out1_shape[] = {1, 1, 2, 4}; uint32_t cell_out1_values[] = {0xbf638f5a, 0xbe9a2d53, 0x3edea444, 0xbf91ec0e, 0xbf8d6301, 0xbec78653, 0x3f0e8a9f, 0xbf885ceb}; zdnn_ztensor *all_ts_out1 = test_layer( all_ts_out0, h01_shape, (void *)h01_values, c01_shape, (void *)c01_values, weights1_shape, (void *)weights1_values, biases1_shape, (void *)biases1_values, hidden_weights1_shape, (void *)hidden_weights1_values, hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape, (void *)all_ts_out1_exp_values, cell_out1_shape, (void *)cell_out1_values, is_layer_bidir[0], is_layer_bidir[1]); free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1); } int main() { UNITY_BEGIN(); #ifdef TEST_AIU RUN_TEST_ALL_DATATYPES(lstm_fwd_to_fwd); RUN_TEST_ALL_DATATYPES(lstm_fwd_to_bidir); RUN_TEST_ALL_DATATYPES(lstm_bidir_to_bidir); RUN_TEST_ALL_DATATYPES(lstm_bidir_to_fwd); #endif return UNITY_END(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_lstm_rnn.c���������������������������������������������������������0000664�0000000�0000000�00000104014�14364043643�0020737�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_rnn.h" /****************************************************************************** default_input ******************************************************************************/ uint32_t default_input_shape[] = {5, 2, 4}; /* Visualization of values in shape (timestep, batch, feature) order [ [ # timestep_0 [.000, .001, .002, .003], # batch_0 [.010, .011, .012, .013], # batch_1 # feat_0 feat_1 feat_2 feat_3 ], [ # timestep_1 [.100, .101, .102, .103], # batch_0 [.110, .111, .112, .113], # batch 1 # feat_0 feat_1 feat_2 feat_3 ], [ # timestep_2 [.200, .201, .202, .203], # batch_0 [.210, .211, .212, .213], # batch_1 # feat_0 feat_1 feat_2 feat_3 ], [ # timestep_3 [.300, .301, .302, .303], # batch_0 [.310, .311, .312, .313], # batch_1 # feat_0 feat_1 feat_2 feat_3 ], [ # timestep_4 [.400, .401, .402, .403], # batch_0 [.410, .411, .412, .413], # batch_1 # feat_0 feat_1 feat_2 feat_3 ], ] */ float default_input_values[] = { 0.0, 0.001, 0.002, 0.003, 0.01, 0.011, 0.012, 0.013, 0.1, 0.101, 0.102, 0.103, 0.11, 0.111, 0.112, 0.113, 0.2, 0.201, 0.202, 0.203, 0.21, 0.211, 0.212, 0.213, 0.3, 0.301, 0.302, 0.303, 0.31, 0.311, 0.312, 0.313, 0.4, 0.401, 0.402, 0.403, 0.41, 0.411, 0.412, 0.413}; /****************************************************************************** default_uni_h0_shape ******************************************************************************/ uint32_t default_uni_h0_shape[] = {1, 2, 3}; /* Visualization of values in shape order [[[0. 0. 0.] [0. 0. 0.]]] */ float default_uni_h0_values[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; /****************************************************************************** default_uni_c0_shape ******************************************************************************/ uint32_t default_uni_c0_shape[] = {1, 2, 3}; /* Visualization of values in shape order [[[0. 0. 0.] [0. 0. 0.]]] */ float default_uni_c0_values[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; /****************************************************************************** default_uni_input_weights ******************************************************************************/ uint32_t default_uni_input_weights_shape[] = {1, 4, 3}; /* Visualization of f concatenation values in shape order [[[-0.4937358 0.5553266 0.1960275] [ 0.1839888 0.1733883 -0.2754271] [ 0.2482673 -0.5119551 -0.5303364] [ 0.0915996 0.4851032 0.329131 ]]] */ float default_uni_input_weights_f_values[] = { -0.4937358, 0.5553266, 0.1960275, 0.1839888, 0.1733883, -0.2754271, 0.2482673, -0.5119551, -0.5303364, 0.0915996, 0.4851032, 0.329131}; /* Visualization of i concatenation values in shape order [[[ 0.381342 0.4850937 -0.5389395] [-0.4317299 -0.44266 0.5706354] [ 0.4705055 -0.3875273 0.1228931] [ 0.3694199 0.2747256 0.0745605]]] */ float default_uni_input_weights_i_values[] = { 0.381342, 0.4850937, -0.5389395, -0.4317299, -0.44266, 0.5706354, 0.4705055, -0.3875273, 0.1228931, 0.3694199, 0.2747256, 0.0745605}; /* Visualization of c concatenation values in shape order [[[ 0.548669 -0.2726471 -0.5263513] [-0.4730297 -0.1263285 -0.0133806] [ 0.0315526 -0.385514 0.3423259] [ 0.2071373 -0.2729528 0.2808076]]] */ float default_uni_input_weights_c_values[] = { 0.548669, -0.2726471, -0.5263513, -0.4730297, -0.1263285, -0.0133806, 0.0315526, -0.385514, 0.3423259, 0.2071373, -0.2729528, 0.2808076}; /* Visualization of o concatenation values in shape order [[[ 0.5423677 0.0945408 0.4383084] [-0.5070595 -0.1628114 0.4629621] [-0.0710383 -0.5199673 0.4833339] [ 0.5621256 0.2686667 0.113032 ]]] */ float default_uni_input_weights_o_values[] = { 0.5423677, 0.0945408, 0.4383084, -0.5070595, -0.1628114, 0.4629621, -0.0710383, -0.5199673, 0.4833339, 0.5621256, 0.2686667, 0.113032}; /****************************************************************************** default_uni_input_biases ******************************************************************************/ uint32_t default_uni_input_biases_shape[] = {1, 3}; /* Visualization of f concatenation values in shape order [[-0.1775665 0.0771791 -0.2241169]] */ float default_uni_input_biases_f_values[] = {-0.1775665, 0.0771791, -0.2241169}; /* Visualization of i concatenation values in shape order [[ 0.3968375 -0.4157575 -0.3188125]] */ float default_uni_input_biases_i_values[] = {0.3968375, -0.4157575, -0.3188125}; /* Visualization of c concatenation values in shape order [[-0.3590846 -0.1054496 -0.2817501]] */ float default_uni_input_biases_c_values[] = {-0.3590846, -0.1054496, -0.2817501}; /* Visualization of o concatenation values in shape order [[ 0.0158953 -0.4273889 -0.1443277]] */ float default_uni_input_biases_o_values[] = {0.0158953, -0.4273889, -0.1443277}; /****************************************************************************** default_uni_hidden_weights ******************************************************************************/ uint32_t default_uni_hidden_weights_shape[] = {1, 3, 3}; /* Visualization of f concatenation values in shape order [[[-0.3689663 -0.3204532 -0.1866051] [-0.3069769 -0.3292732 -0.392639 ] [ 0.5463605 -0.1544762 0.4665768]]] */ float default_uni_hidden_weights_f_values[] = { -0.3689663, -0.3204532, -0.1866051, -0.3069769, -0.3292732, -0.392639, 0.5463605, -0.1544762, 0.4665768}; /* Visualization of i concatenation values in shape order [[[ 0.4114995 -0.049397 0.3073992] [-0.1453276 -0.1190602 0.233599 ] [ 0.4688771 -0.2869941 0.3672419]]] */ float default_uni_hidden_weights_i_values[] = { 0.4114995, -0.049397, 0.3073992, -0.1453276, -0.1190602, 0.233599, 0.4688771, -0.2869941, 0.3672419}; /* Visualization of c concatenation values in shape order [[[ 0.0643551 -0.3741214 -0.0919193] [ 0.2632221 0.4407408 0.4369227] [ 0.4282453 -0.2892259 0.5323023]]] */ float default_uni_hidden_weights_c_values[] = { 0.0643551, -0.3741214, -0.0919193, 0.2632221, 0.4407408, 0.4369227, 0.4282453, -0.2892259, 0.5323023}; /* Visualization of o concatenation values in shape order [[[ 0.5068286 -0.2080224 -0.0424343] [ 0.3320496 -0.0367477 -0.0702022] [ 0.5366269 -0.1974721 0.3084639]]] */ float default_uni_hidden_weights_o_values[] = { 0.5068286, -0.2080224, -0.0424343, 0.3320496, -0.0367477, -0.0702022, 0.5366269, -0.1974721, 0.3084639}; /****************************************************************************** default_uni_hidden_biases ******************************************************************************/ uint32_t default_uni_hidden_biases_shape[] = {1, 3}; /* Visualization of f concatenation values in shape order [[ 0.3785818 -0.186314 -0.5293279]] */ float default_uni_hidden_biases_f_values[] = {0.3785818, -0.186314, -0.5293279}; /* Visualization of i concatenation values in shape order [[-0.2130262 -0.0797516 0.4536392]] */ float default_uni_hidden_biases_i_values[] = {-0.2130262, -0.0797516, 0.4536392}; /* Visualization of c concatenation values in shape order [[-0.4129714 -0.4429338 -0.0547802]] */ float default_uni_hidden_biases_c_values[] = {-0.4129714, -0.4429338, -0.0547802}; /* Visualization of o concatenation values in shape order [[-0.2563944 -0.4034805 0.1280097]] */ float default_uni_hidden_biases_o_values[] = {-0.2563944, -0.4034805, 0.1280097}; /****************************************************************************** default_bidir_h0 ******************************************************************************/ uint32_t default_bidir_h0_shape[] = {2, 2, 3}; /* Visualization of values in shape order [[[0. 0. 0.] [0. 0. 0.]] [[0. 0. 0.] [0. 0. 0.]]] */ float default_bidir_h0_values[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; /****************************************************************************** default_bidir_c0 ******************************************************************************/ uint32_t default_bidir_c0_shape[] = {2, 2, 3}; /* Visualization of values in shape order [[[0. 0. 0.] [0. 0. 0.]] [[0. 0. 0.] [0. 0. 0.]]] */ float default_bidir_c0_values[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; /****************************************************************************** default_bidir_input_weights ******************************************************************************/ uint32_t default_bidir_input_weights_shape[] = {2, 4, 3}; /* Visualization of f concatenation values in shape order [[[-0.4937358 0.5553266 0.1960275] [ 0.1839888 0.1733883 -0.2754271] [ 0.2482673 -0.5119551 -0.5303364] [ 0.0915996 0.4851032 0.329131 ]] [[-0.4937358 0.5553266 0.1960275] [ 0.1839888 0.1733883 -0.2754271] [ 0.2482673 -0.5119551 -0.5303364] [ 0.0915996 0.4851032 0.329131 ]]] */ float default_bidir_input_weights_f_values[] = { -0.4937358, 0.5553266, 0.1960275, 0.1839888, 0.1733883, -0.2754271, 0.2482673, -0.5119551, -0.5303364, 0.0915996, 0.4851032, 0.329131, -0.4937358, 0.5553266, 0.1960275, 0.1839888, 0.1733883, -0.2754271, 0.2482673, -0.5119551, -0.5303364, 0.0915996, 0.4851032, 0.329131}; /* Visualization of i concatenation values in shape order [[[ 0.381342 0.4850937 -0.5389395] [-0.4317299 -0.44266 0.5706354] [ 0.4705055 -0.3875273 0.1228931] [ 0.3694199 0.2747256 0.0745605]] [[ 0.381342 0.4850937 -0.5389395] [-0.4317299 -0.44266 0.5706354] [ 0.4705055 -0.3875273 0.1228931] [ 0.3694199 0.2747256 0.0745605]]] */ float default_bidir_input_weights_i_values[] = { 0.381342, 0.4850937, -0.5389395, -0.4317299, -0.44266, 0.5706354, 0.4705055, -0.3875273, 0.1228931, 0.3694199, 0.2747256, 0.0745605, 0.381342, 0.4850937, -0.5389395, -0.4317299, -0.44266, 0.5706354, 0.4705055, -0.3875273, 0.1228931, 0.3694199, 0.2747256, 0.0745605}; /* Visualization of c concatenation values in shape order [[[ 0.548669 -0.2726471 -0.5263513] [-0.4730297 -0.1263285 -0.0133806] [ 0.0315526 -0.385514 0.3423259] [ 0.2071373 -0.2729528 0.2808076]] [[ 0.548669 -0.2726471 -0.5263513] [-0.4730297 -0.1263285 -0.0133806] [ 0.0315526 -0.385514 0.3423259] [ 0.2071373 -0.2729528 0.2808076]]] */ float default_bidir_input_weights_c_values[] = { 0.548669, -0.2726471, -0.5263513, -0.4730297, -0.1263285, -0.0133806, 0.0315526, -0.385514, 0.3423259, 0.2071373, -0.2729528, 0.2808076, 0.548669, -0.2726471, -0.5263513, -0.4730297, -0.1263285, -0.0133806, 0.0315526, -0.385514, 0.3423259, 0.2071373, -0.2729528, 0.2808076}; /* Visualization of o concatenation values in shape order [[[ 0.5423677 0.0945408 0.4383084] [-0.5070595 -0.1628114 0.4629621] [-0.0710383 -0.5199673 0.4833339] [ 0.5621256 0.2686667 0.113032 ]] [[ 0.5423677 0.0945408 0.4383084] [-0.5070595 -0.1628114 0.4629621] [-0.0710383 -0.5199673 0.4833339] [ 0.5621256 0.2686667 0.113032 ]]] */ float default_bidir_input_weights_o_values[] = { 0.5423677, 0.0945408, 0.4383084, -0.5070595, -0.1628114, 0.4629621, -0.0710383, -0.5199673, 0.4833339, 0.5621256, 0.2686667, 0.113032, 0.5423677, 0.0945408, 0.4383084, -0.5070595, -0.1628114, 0.4629621, -0.0710383, -0.5199673, 0.4833339, 0.5621256, 0.2686667, 0.113032}; /****************************************************************************** default_bidir_input_biases ******************************************************************************/ uint32_t default_bidir_input_biases_shape[] = {2, 3}; /* Visualization of f concatenation values in shape order [[-0.1775665 0.0771791 -0.2241169] [-0.1775665 0.0771791 -0.2241169]] */ float default_bidir_input_biases_f_values[] = { -0.1775665, 0.0771791, -0.2241169, -0.1775665, 0.0771791, -0.2241169}; ; /* Visualization of i concatenation values in shape order [[ 0.3968375 -0.4157575 -0.3188125] [ 0.3968375 -0.4157575 -0.3188125]] */ float default_bidir_input_biases_i_values[] = { 0.3968375, -0.4157575, -0.3188125, 0.3968375, -0.4157575, -0.3188125}; /* Visualization of c concatenation values in shape order [[-0.3590846 -0.1054496 -0.2817501] [-0.3590846 -0.1054496 -0.2817501]] */ float default_bidir_input_biases_c_values[] = { -0.3590846, -0.1054496, -0.2817501, -0.3590846, -0.1054496, -0.2817501}; /* Visualization of o concatenation values in shape order [[ 0.0158953 -0.4273889 -0.1443277] [ 0.0158953 -0.4273889 -0.1443277]] */ float default_bidir_input_biases_o_values[] = { 0.0158953, -0.4273889, -0.1443277, 0.0158953, -0.4273889, -0.1443277}; /****************************************************************************** default_uni_hidden_weights ******************************************************************************/ uint32_t default_bidir_hidden_weights_shape[] = {2, 3, 3}; /* Visualization of f concatenation values in shape order [[[-0.3689663 -0.3204532 -0.1866051] [-0.3069769 -0.3292732 -0.392639 ] [ 0.5463605 -0.1544762 0.4665768]] [[-0.3689663 -0.3204532 -0.1866051] [-0.3069769 -0.3292732 -0.392639 ] [ 0.5463605 -0.1544762 0.4665768]]] */ float default_bidir_hidden_weights_f_values[] = { -0.3689663, -0.3204532, -0.1866051, -0.3069769, -0.3292732, -0.392639, 0.5463605, -0.1544762, 0.4665768, -0.3689663, -0.3204532, -0.1866051, -0.3069769, -0.3292732, -0.392639, 0.5463605, -0.1544762, 0.4665768}; /* Visualization of i concatenation values in shape order [[[ 0.4114995 -0.049397 0.3073992] [-0.1453276 -0.1190602 0.233599 ] [ 0.4688771 -0.2869941 0.3672419]] [[ 0.4114995 -0.049397 0.3073992] [-0.1453276 -0.1190602 0.233599 ] [ 0.4688771 -0.2869941 0.3672419]]] */ float default_bidir_hidden_weights_i_values[] = { 0.4114995, -0.049397, 0.3073992, -0.1453276, -0.1190602, 0.233599, 0.4688771, -0.2869941, 0.3672419, 0.4114995, -0.049397, 0.3073992, -0.1453276, -0.1190602, 0.233599, 0.4688771, -0.2869941, 0.3672419}; /* Visualization of c concatenation values in shape order [[[ 0.0643551 -0.3741214 -0.0919193] [ 0.2632221 0.4407408 0.4369227] [ 0.4282453 -0.2892259 0.5323023]] [[ 0.0643551 -0.3741214 -0.0919193] [ 0.2632221 0.4407408 0.4369227] [ 0.4282453 -0.2892259 0.5323023]]] */ float default_bidir_hidden_weights_c_values[] = { 0.0643551, -0.3741214, -0.0919193, 0.2632221, 0.4407408, 0.4369227, 0.4282453, -0.2892259, 0.5323023, 0.0643551, -0.3741214, -0.0919193, 0.2632221, 0.4407408, 0.4369227, 0.4282453, -0.2892259, 0.5323023}; /* Visualization of o concatenation values in shape order [[[ 0.5068286 -0.2080224 -0.0424343] [ 0.3320496 -0.0367477 -0.0702022] [ 0.5366269 -0.1974721 0.3084639]] [[ 0.5068286 -0.2080224 -0.0424343] [ 0.3320496 -0.0367477 -0.0702022] [ 0.5366269 -0.1974721 0.3084639]]] */ float default_bidir_hidden_weights_o_values[] = { 0.5068286, -0.2080224, -0.0424343, 0.3320496, -0.0367477, -0.0702022, 0.5366269, -0.1974721, 0.3084639, 0.5068286, -0.2080224, -0.0424343, 0.3320496, -0.0367477, -0.0702022, 0.5366269, -0.1974721, 0.3084639}; /****************************************************************************** default_bidir_hidden_biases ******************************************************************************/ uint32_t default_bidir_hidden_biases_shape[] = {2, 3}; /* Visualization of f concatenation values in shape order [[ 0.3785818 -0.186314 -0.5293279] [ 0.3785818 -0.186314 -0.5293279]] */ float default_bidir_hidden_biases_f_values[] = { 0.3785818, -0.186314, -0.5293279, 0.3785818, -0.186314, -0.5293279}; /* Visualization of i concatenation values in shape order [[-0.2130262 -0.0797516 0.4536392] [-0.2130262 -0.0797516 0.4536392]] */ float default_bidir_hidden_biases_i_values[] = { -0.2130262, -0.0797516, 0.4536392, -0.2130262, -0.0797516, 0.4536392}; /* Visualization of c concatenation values in shape order [[-0.4129714 -0.4429338 -0.0547802] [-0.4129714 -0.4429338 -0.0547802]] */ float default_bidir_hidden_biases_c_values[] = { -0.4129714, -0.4429338, -0.0547802, -0.4129714, -0.4429338, -0.0547802}; /* Visualization of o concatenation values in shape order [[-0.2563944 -0.4034805 0.1280097] [-0.2563944 -0.4034805 0.1280097]] */ float default_bidir_hidden_biases_o_values[] = { -0.2563944, -0.4034805, 0.1280097, -0.2563944, -0.4034805, 0.1280097}; /****************************************************************************** default_fwd_exp_hn_out_all_ts ******************************************************************************/ uint32_t default_fwd_hn_out_all_ts_shape[] = {5, 1, 2, 3}; /* Visualization of values in shape order [[[-0.1496885 -0.0568049 -0.0847668] [-0.1502335 -0.057525 -0.0853017]] [[-0.212243 -0.0906312 -0.1264551] [-0.2129832 -0.0917483 -0.1272719]] [[-0.2460073 -0.1145757 -0.1504627] [-0.2468257 -0.115835 -0.1514198]] [[-0.2677511 -0.1334158 -0.1669724] [-0.2686036 -0.1346632 -0.1679834]] [[-0.2836966 -0.1488931 -0.180066 ] [-0.2845615 -0.1500451 -0.1810745]]] */ float default_fwd_exp_hn_out_all_ts_values[] = { -0.1496885, -0.0568049, -0.0847668, -0.1502335, -0.057525, -0.0853017, -0.212243, -0.0906312, -0.1264551, -0.2129832, -0.0917483, -0.1272719, -0.2460073, -0.1145757, -0.1504627, -0.2468257, -0.115835, -0.1514198, -0.2677511, -0.1334158, -0.1669724, -0.2686036, -0.1346632, -0.1679834, -0.2836966, -0.1488931, -0.180066, -0.2845615, -0.1500451, -0.1810745}; /****************************************************************************** default_fwd_exp_hn_out_final_ts ******************************************************************************/ uint32_t default_fwd_hn_out_final_ts_shape[] = {1, 1, 2, 3}; /* Visualization of values in shape order [[[-0.2836966 -0.1488931 -0.180066 ] [-0.2845615 -0.1500451 -0.1810745]]] */ float default_fwd_exp_hn_out_final_ts_values[] = { -0.2836966, -0.1488931, -0.180066, -0.2845615, -0.1500451, -0.1810745}; /****************************************************************************** default_fwd_cf_exp_out ******************************************************************************/ uint32_t default_fwd_cf_out_shape[] = {1, 1, 2, 3}; /* Visualization of values in shape order [[[-0.8036579 -0.552912 -0.2915583] [-0.8046424 -0.5594633 -0.2916239]]] */ float default_fwd_exp_cf_out_values[] = {-0.8036579, -0.552912, -0.2915583, -0.8046424, -0.5594633, -0.2916239}; /****************************************************************************** default_bwd_exp_hn_out_all_ts ******************************************************************************/ uint32_t default_bwd_hn_out_all_ts_shape[] = {5, 1, 2, 3}; /* Visualization of values in shape order [[[-0.2486852 -0.1223668 -0.1448121] [-0.2495632 -0.1242222 -0.1459369]] [[-0.2501265 -0.1314582 -0.1518588] [-0.2509633 -0.1329102 -0.1529005]] [[-0.2448045 -0.1305399 -0.1532898] [-0.2455692 -0.1315801 -0.1541975]] [[-0.2248478 -0.1148318 -0.1424497] [-0.2254719 -0.1154587 -0.14315 ]] [[-0.1676665 -0.0753414 -0.1037449] [-0.1679938 -0.0755724 -0.1041366]]] */ float default_bwd_exp_hn_out_all_ts_values[] = { -0.2486852, -0.1223668, -0.1448121, -0.2495632, -0.1242222, -0.1459369, -0.2501265, -0.1314582, -0.1518588, -0.2509633, -0.1329102, -0.1529005, -0.2448045, -0.1305399, -0.1532898, -0.2455692, -0.1315801, -0.1541975, -0.2248478, -0.1148318, -0.1424497, -0.2254719, -0.1154587, -0.14315, -0.1676665, -0.0753414, -0.1037449, -0.1679938, -0.0755724, -0.1041366}; /****************************************************************************** default_bwd_exp_hn_out_final_ts ******************************************************************************/ uint32_t default_bwd_hn_out_final_ts_shape[] = {1, 1, 2, 3}; /* Visualization of values in shape order [[[-0.2486852 -0.1223668 -0.1448121] [-0.2495632 -0.1242222 -0.1459369]]] */ float default_bwd_exp_hn_out_final_ts_values[] = { -0.2486852, -0.1223668, -0.1448121, -0.2495632, -0.1242222, -0.1459369}; /****************************************************************************** default_bwd_exp_cf_out ******************************************************************************/ uint32_t default_bwd_cf_out_shape[] = {1, 1, 2, 3}; /* Visualization of values in shape order [[[-0.7843156 -0.4000301 -0.3048753] [-0.7856599 -0.4076315 -0.3049449]]] */ float default_bwd_exp_cf_out_values[] = {-0.7843156, -0.4000301, -0.3048753, -0.7856599, -0.4076315, -0.3049449}; /****************************************************************************** default_bidir_exp_hn_out_all_ts ******************************************************************************/ uint32_t default_bidir_hn_out_all_ts_shape[] = {5, 2, 2, 3}; /* Visualization of values in shape order [[[-0.1496885 -0.0568049 -0.0847668 -0.1502335 -0.057525 -0.0853017] [-0.2486852 -0.1223668 -0.1448121 -0.2495632 -0.1242222 -0.1459369]] [[-0.212243 -0.0906312 -0.1264551 -0.2129832 -0.0917483 -0.1272719] [-0.2501265 -0.1314583 -0.1518588 -0.2509633 -0.1329102 -0.1529005]] [[-0.2460073 -0.1145757 -0.1504627 -0.2468257 -0.115835 -0.1514198] [-0.2448045 -0.1305399 -0.1532898 -0.2455692 -0.1315801 -0.1541975]] [[-0.2677511 -0.1334158 -0.1669723 -0.2686036 -0.1346633 -0.1679834] [-0.2248478 -0.1148318 -0.1424497 -0.2254719 -0.1154587 -0.14315 ]] [[-0.2836966 -0.1488931 -0.180066 -0.2845615 -0.1500451 -0.1810745] [-0.1676665 -0.0753414 -0.1037448 -0.1679938 -0.0755724 -0.1041366]]] */ float default_bidir_exp_hn_out_all_ts_values[] = { -0.1496885, -0.0568049, -0.0847668, -0.1502335, -0.057525, -0.0853017, -0.2486852, -0.1223668, -0.1448121, -0.2495632, -0.1242222, -0.1459369, -0.212243, -0.0906312, -0.1264551, -0.2129832, -0.0917483, -0.1272719, -0.2501265, -0.1314583, -0.1518588, -0.2509633, -0.1329102, -0.1529005, -0.2460073, -0.1145757, -0.1504627, -0.2468257, -0.115835, -0.1514198, -0.2448045, -0.1305399, -0.1532898, -0.2455692, -0.1315801, -0.1541975, -0.2677511, -0.1334158, -0.1669723, -0.2686036, -0.1346633, -0.1679834, -0.2248478, -0.1148318, -0.1424497, -0.2254719, -0.1154587, -0.14315, -0.2836966, -0.1488931, -0.180066, -0.2845615, -0.1500451, -0.1810745, -0.1676665, -0.0753414, -0.1037448, -0.1679938, -0.0755724, -0.1041366}; /****************************************************************************** default_bidir_exp_hn_out_final_ts ******************************************************************************/ uint32_t default_bidir_hn_out_final_ts_shape[] = {1, 2, 2, 3}; /* Visualization of values in shape order [[[-0.2836966 -0.1488931 -0.180066 -0.2845615 -0.1500451 -0.1810745] [-0.2486852 -0.1223668 -0.1448121 -0.2495632 -0.1242222 -0.1459369]]] */ float default_bidir_exp_hn_out_final_ts_values[] = { -0.2836966, -0.1488931, -0.180066, -0.2845615, -0.1500451, -0.1810745, -0.2486852, -0.1223668, -0.1448121, -0.2495632, -0.1242222, -0.1459369}; /****************************************************************************** default_bidir_cf_exp_out ******************************************************************************/ uint32_t default_bidir_cf_out_shape[] = {1, 2, 2, 3}; /* Visualization of values in shape order [[[-0.8036579 -0.552912 -0.2915582 -0.8046424 -0.5594633 -0.2916239] [-0.7843156 -0.4000301 -0.3048753 -0.7856599 -0.4076315 -0.3049449]]] */ float default_bidir_exp_cf_out_values[] = { -0.8036579, -0.552912, -0.2915582, -0.8046424, -0.5594633, -0.2916239, -0.7843156, -0.4000301, -0.3048753, -0.7856599, -0.4076315, -0.3049449}; /****************************************************************************** Unity Methods ******************************************************************************/ void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } /****************************************************************************** Tests ******************************************************************************/ // Confirm that lstm returns OK and expected values when set to return hn // results from all timesteps void lstm_basic_fwd_hn_all() { test_zdnn_api_lstm_gru( NNPA_LSTMACT, default_input_shape, ZDNN_3DS, default_input_values, default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, default_uni_c0_shape, ZDNN_3DS, default_uni_c0_values, default_uni_input_weights_shape, ZDNN_3DS, default_uni_input_weights_f_values, default_uni_input_weights_i_values, default_uni_input_weights_c_values, default_uni_input_weights_o_values, default_uni_input_biases_shape, ZDNN_2DS, default_uni_input_biases_f_values, default_uni_input_biases_i_values, default_uni_input_biases_c_values, default_uni_input_biases_o_values, default_uni_hidden_weights_shape, ZDNN_3DS, default_uni_hidden_weights_f_values, default_uni_hidden_weights_i_values, default_uni_hidden_weights_c_values, default_uni_hidden_weights_o_values, default_uni_hidden_biases_shape, ZDNN_2DS, default_uni_hidden_biases_f_values, default_uni_hidden_biases_i_values, default_uni_hidden_biases_c_values, default_uni_hidden_biases_o_values, default_fwd_hn_out_all_ts_shape, ZDNN_4DS, default_fwd_exp_hn_out_all_ts_values, default_fwd_cf_out_shape, ZDNN_4DS, default_fwd_exp_cf_out_values, FWD, ZDNN_OK); } // Confirm that lstm returns OK and expected values when set to return only the // final hn result void lstm_basic_fwd_hn_final() { test_zdnn_api_lstm_gru( NNPA_LSTMACT, default_input_shape, ZDNN_3DS, default_input_values, default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, default_uni_c0_shape, ZDNN_3DS, default_uni_c0_values, default_uni_input_weights_shape, ZDNN_3DS, default_uni_input_weights_f_values, default_uni_input_weights_i_values, default_uni_input_weights_c_values, default_uni_input_weights_o_values, default_uni_input_biases_shape, ZDNN_2DS, default_uni_input_biases_f_values, default_uni_input_biases_i_values, default_uni_input_biases_c_values, default_uni_input_biases_o_values, default_uni_hidden_weights_shape, ZDNN_3DS, default_uni_hidden_weights_f_values, default_uni_hidden_weights_i_values, default_uni_hidden_weights_c_values, default_uni_hidden_weights_o_values, default_uni_hidden_biases_shape, ZDNN_2DS, default_uni_hidden_biases_f_values, default_uni_hidden_biases_i_values, default_uni_hidden_biases_c_values, default_uni_hidden_biases_o_values, default_fwd_hn_out_final_ts_shape, ZDNN_4DS, default_fwd_exp_hn_out_final_ts_values, default_fwd_cf_out_shape, ZDNN_4DS, default_fwd_exp_cf_out_values, FWD, ZDNN_OK); } // Confirm that lstm returns OK and expected values when set to return hn // results from all timesteps void lstm_basic_bwd_hn_all() { test_zdnn_api_lstm_gru( NNPA_LSTMACT, default_input_shape, ZDNN_3DS, default_input_values, default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, default_uni_c0_shape, ZDNN_3DS, default_uni_c0_values, default_uni_input_weights_shape, ZDNN_3DS, default_uni_input_weights_f_values, default_uni_input_weights_i_values, default_uni_input_weights_c_values, default_uni_input_weights_o_values, default_uni_input_biases_shape, ZDNN_2DS, default_uni_input_biases_f_values, default_uni_input_biases_i_values, default_uni_input_biases_c_values, default_uni_input_biases_o_values, default_uni_hidden_weights_shape, ZDNN_3DS, default_uni_hidden_weights_f_values, default_uni_hidden_weights_i_values, default_uni_hidden_weights_c_values, default_uni_hidden_weights_o_values, default_uni_hidden_biases_shape, ZDNN_2DS, default_uni_hidden_biases_f_values, default_uni_hidden_biases_i_values, default_uni_hidden_biases_c_values, default_uni_hidden_biases_o_values, default_bwd_hn_out_all_ts_shape, ZDNN_4DS, default_bwd_exp_hn_out_all_ts_values, default_bwd_cf_out_shape, ZDNN_4DS, default_bwd_exp_cf_out_values, BWD, ZDNN_OK); } // Confirm that lstm returns OK and expected values when set to return only the // final hn result void lstm_basic_bwd_hn_final() { test_zdnn_api_lstm_gru( NNPA_LSTMACT, default_input_shape, ZDNN_3DS, default_input_values, default_uni_h0_shape, ZDNN_3DS, default_uni_h0_values, default_uni_c0_shape, ZDNN_3DS, default_uni_c0_values, default_uni_input_weights_shape, ZDNN_3DS, default_uni_input_weights_f_values, default_uni_input_weights_i_values, default_uni_input_weights_c_values, default_uni_input_weights_o_values, default_uni_input_biases_shape, ZDNN_2DS, default_uni_input_biases_f_values, default_uni_input_biases_i_values, default_uni_input_biases_c_values, default_uni_input_biases_o_values, default_uni_hidden_weights_shape, ZDNN_3DS, default_uni_hidden_weights_f_values, default_uni_hidden_weights_i_values, default_uni_hidden_weights_c_values, default_uni_hidden_weights_o_values, default_uni_hidden_biases_shape, ZDNN_2DS, default_uni_hidden_biases_f_values, default_uni_hidden_biases_i_values, default_uni_hidden_biases_c_values, default_uni_hidden_biases_o_values, default_bwd_hn_out_final_ts_shape, ZDNN_4DS, default_bwd_exp_hn_out_final_ts_values, default_bwd_cf_out_shape, ZDNN_4DS, default_bwd_exp_cf_out_values, BWD, ZDNN_OK); } // Confirm that lstm returns OK and expected values when set to return hn // results from all timesteps void lstm_basic_bidir_hn_all() { test_zdnn_api_lstm_gru( NNPA_LSTMACT, default_input_shape, ZDNN_3DS, default_input_values, default_bidir_h0_shape, ZDNN_3DS, default_bidir_h0_values, default_bidir_c0_shape, ZDNN_3DS, default_bidir_c0_values, default_bidir_input_weights_shape, ZDNN_3DS, default_bidir_input_weights_f_values, default_bidir_input_weights_i_values, default_bidir_input_weights_c_values, default_bidir_input_weights_o_values, default_bidir_input_biases_shape, ZDNN_2DS, default_bidir_input_biases_f_values, default_bidir_input_biases_i_values, default_bidir_input_biases_c_values, default_bidir_input_biases_o_values, default_bidir_hidden_weights_shape, ZDNN_3DS, default_bidir_hidden_weights_f_values, default_bidir_hidden_weights_i_values, default_bidir_hidden_weights_c_values, default_bidir_hidden_weights_o_values, default_bidir_hidden_biases_shape, ZDNN_2DS, default_bidir_hidden_biases_f_values, default_bidir_hidden_biases_i_values, default_bidir_hidden_biases_c_values, default_bidir_hidden_biases_o_values, default_bidir_hn_out_all_ts_shape, ZDNN_4DS, default_bidir_exp_hn_out_all_ts_values, default_bidir_cf_out_shape, ZDNN_4DS, default_bidir_exp_cf_out_values, BIDIR, ZDNN_OK); } // Confirm that lstm returns OK and expected values when set to return only the // final hn result void lstm_basic_bidir_hn_final() { test_zdnn_api_lstm_gru( NNPA_LSTMACT, default_input_shape, ZDNN_3DS, default_input_values, default_bidir_h0_shape, ZDNN_3DS, default_bidir_h0_values, default_bidir_c0_shape, ZDNN_3DS, default_bidir_c0_values, default_bidir_input_weights_shape, ZDNN_3DS, default_bidir_input_weights_f_values, default_bidir_input_weights_i_values, default_bidir_input_weights_c_values, default_bidir_input_weights_o_values, default_bidir_input_biases_shape, ZDNN_2DS, default_bidir_input_biases_f_values, default_bidir_input_biases_i_values, default_bidir_input_biases_c_values, default_bidir_input_biases_o_values, default_bidir_hidden_weights_shape, ZDNN_3DS, default_bidir_hidden_weights_f_values, default_bidir_hidden_weights_i_values, default_bidir_hidden_weights_c_values, default_bidir_hidden_weights_o_values, default_bidir_hidden_biases_shape, ZDNN_2DS, default_bidir_hidden_biases_f_values, default_bidir_hidden_biases_i_values, default_bidir_hidden_biases_c_values, default_bidir_hidden_biases_o_values, default_bidir_hn_out_final_ts_shape, ZDNN_4DS, default_bidir_exp_hn_out_final_ts_values, default_bidir_cf_out_shape, ZDNN_4DS, default_bidir_exp_cf_out_values, BIDIR, ZDNN_OK); } int main() { UNITY_BEGIN(); // LSTM tests with good input requires AIU to get results and // validate values. #ifdef TEST_AIU // FWD direction tests RUN_TEST_ALL_DATATYPES(lstm_basic_fwd_hn_all); RUN_TEST_ALL_DATATYPES(lstm_basic_fwd_hn_final); // BWD direction tests RUN_TEST_ALL_DATATYPES(lstm_basic_bwd_hn_all); RUN_TEST_ALL_DATATYPES(lstm_basic_bwd_hn_final); // BIDIR direction tests RUN_TEST_ALL_DATATYPES(lstm_basic_bidir_hn_all); RUN_TEST_ALL_DATATYPES(lstm_basic_bidir_hn_final); #endif return UNITY_END(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_matmul_op.c��������������������������������������������������������0000664�0000000�0000000�00000061746�14364043643�0021116�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "testsupport.h" #include <stdio.h> #include <stdlib.h> #include <string.h> void setUp(void) { /* This is run before EACH TEST */ tol_bfloat.ulps = 64; tol_bfloat.epsilon_mult = (0.1 / EPSILON_BFLOAT) + 1; tol_fp16.ulps = 64; tol_fp16.epsilon_mult = (0.1 / EPSILON_FP16) + 1; tol_fp32.ulps = 64 * 16384; tol_fp32.epsilon_mult = (0.1 / EPSILON_FLOAT) + 1; VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } /** * Helper macro that given the indices and sizes of a multidimensional array * returns equivalent index to a flat representation of the same array. The * result is cast to uint64_t as that's the largest number of total elements a * ztensor supports as opposed to the single dimension maximum of unint32_t * * Note: Default usage is for 3D arrays. For 2D arrays, use 0 for the * undefined dimension's index and 1 its size. */ #define GET_FLAT_IDX(stack, row, col, row_size, col_size) \ (uint64_t)(stack) * (row_size) * (col_size) + (row) * (col_size) + (col) /** * Helper function to print matmul arrays. 3D arrays are printed as separate * stacks of 2D arrays. */ void print_matmul_array(uint32_t s, uint32_t r, uint32_t c, char *name, float *arr) { printf("Printing \"%s\" as %u stack(s) of array[%u][%u]\n", name, s, r, c); for (uint32_t i = 0; i < s; i++) { printf("\"%s\" stack %u\n", name, i); for (uint32_t j = 0; j < r; j++) { for (uint32_t k = 0; k < c; k++) { printf("%f ", arr[GET_FLAT_IDX(i, j, k, r, c)]); } printf("\n"); } } printf("end \"%s\"\n\n", name); } /** * Helper function to compute expected output tensor from randomly generated * test input arrays. * * | first | second | bias | result | * | (s, m, n) | (s, n, p) | (s, p) | (s, m, p) | * */ void gen_test_expected_fp32_array(uint32_t s, uint32_t m, uint32_t n, uint32_t p, zdnn_data_types type, float *first, float *second, float *bias, float *result) { for (uint32_t i = 0; i < s; i++) { // MATRIX from stack for (uint32_t j = 0; j < m; j++) { // ROW of Mat 1 for (uint32_t k = 0; k < p; k++) { // COL of Mat 2 uint64_t result_idx = GET_FLAT_IDX(i, j, k, m, p); uint64_t bias_idx = GET_FLAT_IDX(i, 0, k, 1, p); float cleansed_bias = 0; switch (type) { case (BFLOAT): cleansed_bias = CLEANSE_BFLOAT(bias[bias_idx]); break; case (FP16): cleansed_bias = CLEANSE_FP16(bias[bias_idx]); break; case (FP32): cleansed_bias = CLEANSE_FP32(bias[bias_idx]); break; default: break; } result[result_idx] = cleansed_bias; // bias add BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("result[%u][%u][%u] = ", i, j, k); } for (uint32_t l = 0; l < n; l++) { // COL of Mat 1 uint64_t first_idx = GET_FLAT_IDX(i, j, l, m, n); uint64_t second_idx = GET_FLAT_IDX(i, l, k, n, p); float cleansed_first = 0; float cleansed_second = 0; switch (type) { case (BFLOAT): cleansed_first = CLEANSE_BFLOAT(first[first_idx]); cleansed_second = CLEANSE_BFLOAT(second[second_idx]); break; case (FP16): cleansed_first = CLEANSE_FP16(first[first_idx]); cleansed_second = CLEANSE_FP16(second[second_idx]); break; case (FP32): cleansed_first = CLEANSE_FP32(first[first_idx]); cleansed_second = CLEANSE_FP32(second[second_idx]); break; default: break; } result[result_idx] += cnvt_1_dlf16_to_fp32(cnvt_1_fp32_to_dlf16( cleansed_first * cleansed_second)); // dot product // Prints the math that generates each cell of the output. BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("(%f * %f) + ", cleansed_first, cleansed_second); } } BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("%f = %f\n", cleansed_bias, result[result_idx]); } } } } } /** * do_test * * Handles all the logic to run custom tests. * * when is_stacked is true, shapes are interpreted as: * - input_a = s x m x n ZDNN_3DS * - input_b = s x n x p ZDNN_3DS * - bias = s x p ZDNN_2DS * - output = s x m x p ZDNN_3DS * * when is_stacked is not true, shapes are interpreted as: * - input_a = m x n ZDNN_2D * - input_b = n x p ZDNN_2D * - bias = p ZDNN_1D * - output = m x p ZDNN_2D * * when is_bcast is true (regardless of is_stacked), shapes are in interpreted * as: * - input_a = s x m x n ZDNN_3DS * - input_b = n x p ZDNN_2D * - bias = p ZDNN_1D * - output = s x m x p ZDNN_3DS * */ void do_test(uint32_t *input_a_shape, uint32_t *input_b_shape, uint32_t *input_bias_shape, uint32_t *output_shape, bool is_stacked, bool is_bcast, float *input_a, float *input_b, float *bias, zdnn_matmul_ops op_type, zdnn_status expected_status, float *expected_values) { /* * Input A Tensor */ zdnn_ztensor *input_a_ztensor = alloc_ztensor_with_values( input_a_shape, (!is_stacked && !is_bcast) ? ZDNN_2D : ZDNN_3DS, test_datatype, NO_CONCAT, false, input_a); /* * Input B Tensor */ zdnn_ztensor *input_b_ztensor = alloc_ztensor_with_values( input_b_shape, (is_stacked && !is_bcast) ? ZDNN_3DS : ZDNN_2D, test_datatype, NO_CONCAT, false, input_b); /* * Bias Tensor */ zdnn_ztensor *input_bias_ztensor = alloc_ztensor_with_values( input_bias_shape, (is_stacked && !is_bcast) ? ZDNN_2DS : ZDNN_1D, test_datatype, NO_CONCAT, false, bias); /* * Output Tensor */ zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_shape, (!is_stacked && !is_bcast) ? ZDNN_2D : ZDNN_3DS, test_datatype, NO_CONCAT, true, ZERO_ARRAY); /* * Get back zDNN test status */ zdnn_status test_status = GENERAL_TESTCASE_FAILURE; if (!is_bcast) { test_status = zdnn_matmul_op(input_a_ztensor, input_b_ztensor, input_bias_ztensor, op_type, output_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( expected_status == test_status, "Expected status %08x from zdnn_matmul_op() with %d Op but %08x was " "returned.", expected_status, op_type, test_status); } else { test_status = zdnn_matmul_bcast_op(input_a_ztensor, input_b_ztensor, input_bias_ztensor, op_type, output_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( expected_status == test_status, "Expected status %08x from zdnn_matmul_bcast_op() with %d Op but %08x " "was returned.", expected_status, op_type, test_status); } BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { int s = input_a_ztensor->transformed_desc->dim4; int m = input_a_ztensor->transformed_desc->dim2; int n = input_a_ztensor->transformed_desc->dim1; int p = input_b_ztensor->transformed_desc->dim1; print_matmul_array(s, m, n, "input_a", input_a); print_matmul_array(s, n, p, "input_b", input_b); print_matmul_array(s, 1, p, "bias", bias); print_matmul_array(s, m, p, "expected_values", expected_values); } #ifdef TEST_AIU fp_tolerance *tol = NULL; switch (output_ztensor->pre_transformed_desc->type) { case BFLOAT: tol = &tol_bfloat; break; case FP16: tol = &tol_fp16; break; case FP32: tol = &tol_fp32; break; default: break; // should never get here } // Only check expected values if we expected the NNPA call to be successful if (expected_status == ZDNN_OK) { assert_ztensor_values_adv(output_ztensor, false, expected_values, *tol); } #endif // All done--clean up the tensor buffers free_ztensor_buffers(4, input_a_ztensor, input_b_ztensor, input_bias_ztensor, output_ztensor); } void zdnn_matmul_op_test(uint32_t *input_a_shape, uint32_t *input_b_shape, uint32_t *input_bias_shape, uint32_t *output_shape, bool is_stacked, float *input_a, float *input_b, float *bias, zdnn_matmul_ops op_type, zdnn_status expected_status, float *expected_values) { do_test(input_a_shape, input_b_shape, input_bias_shape, output_shape, is_stacked, false, input_a, input_b, bias, op_type, expected_status, expected_values); } void zdnn_matmul_bcast_op_test(uint32_t *input_a_shape, uint32_t *input_b_shape, uint32_t *input_bias_shape, uint32_t *output_shape, float *input_a, float *input_b, float *bias, zdnn_matmul_bcast_ops op_type, zdnn_status expected_status, float *expected_values) { do_test(input_a_shape, input_b_shape, input_bias_shape, output_shape, false, true, input_a, input_b, bias, op_type, expected_status, expected_values); } /** * - MatMulBiasAdd (non-stacked) * * - Matrix input_a = 3x3 -- Manually Coded Input * - Matrix input_b = 3x3 -- Manually Coded Input * - Matrix bias = 3 -- Manually Coded Input * - Matrix output = 3x3 */ void zdnn_matmul_biasadd_3x3_by_3x3() { // Setup Input A uint32_t input_a_shape[] = {3, 3}; float input_a_values[] = {0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90}; // Setup Input B uint32_t input_b_shape[] = {3, 3}; float input_b_values[] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; // Setup Input bias uint32_t input_bias_shape[] = {3}; float input_bias_values[] = {10, 10, 10}; // Output tensor and expected values uint32_t output_shape[] = {input_a_shape[0], input_b_shape[1]}; float expected_values[] = {40, 46, 52, 76, 91, 106, 112, 136, 160}; zdnn_matmul_op_test(input_a_shape, input_b_shape, input_bias_shape, output_shape, false, input_a_values, input_b_values, input_bias_values, MATMUL_OP_ADDITION, ZDNN_OK, expected_values); } /** * - MatMulBiasAdd (non-stacked, bigger values) * * - Matrix input_a = 3x3 -- Manually Coded Input * - Matrix input_b = 3x3 -- Manually Coded Input * - Matrix bias = 3 -- Manually Coded Input * - Matrix output = 3x3 */ void zdnn_matmul_biasadd_3x3_by_3x3_bigger_vals() { // Setup Input A uint32_t input_a_shape[] = {3, 3}; float input_a_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // Setup Input B uint32_t input_b_shape[] = {3, 3}; float input_b_values[] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; // Setup Input bias uint32_t input_bias_shape[] = {3}; float input_bias_values[] = {10, 10, 10}; // Output tensor and expected values uint32_t output_shape[] = {input_a_shape[0], input_b_shape[1]}; float expected_values[] = {310, 370, 430, 670, 820, 970, 1030, 1270, 1510}; zdnn_matmul_op_test(input_a_shape, input_b_shape, input_bias_shape, output_shape, false, input_a_values, input_b_values, input_bias_values, MATMUL_OP_ADDITION, ZDNN_OK, expected_values); } /** * - MatMulBiasAdd (non-stacked) * * - Matrix input_a = 4x3 -- Manually Coded Input * - Matrix input_b = 3x2 -- Manually Coded Input * - Matrix bias = 2 -- Manually Coded Input * - Matrix output = 4x2 */ void zdnn_matmul_biasadd_4x3_by_3x2() { // Setup Input A uint32_t input_a_shape[] = {4, 3}; float input_a_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Setup Input B uint32_t input_b_shape[] = {3, 2}; float input_b_values[] = {1, 2, 3, 4, 5, 6}; // Setup Input bias uint32_t input_bias_shape[] = {2}; float input_bias_values[] = {3, 3}; // Output tensor and expected values uint32_t output_shape[] = {input_a_shape[0], input_b_shape[1]}; float expected_values[] = {25, 31, 52, 67, 79, 103, 106, 139}; zdnn_matmul_op_test(input_a_shape, input_b_shape, input_bias_shape, output_shape, false, input_a_values, input_b_values, input_bias_values, MATMUL_OP_ADDITION, ZDNN_OK, expected_values); } /** * - MatMulBiasAdd (stacked) * * - Matrix input_a = s x m x n --Randomly Generated Positive/Negative Array * - Matrix input_b = s x n x p --Randomly Generated Positive/Negative Array * - Matrix bias = s x p --Randomly Generated Positive Array * - Matrix output = s x m x p */ void zdnn_matmul_biasadd_smn_by_snp(uint64_t s, uint64_t m, uint64_t n, uint64_t p) { uint64_t num_values = 0; // Setup Input A using random values uint32_t input_a_shape[] = {s, m, n}; num_values = s * m * n; float input_a_values[num_values]; gen_random_float_array_pos_neg(num_values, input_a_values); // Setup Input B using random values uint32_t input_b_shape[] = {s, n, p}; num_values = s * n * p; float input_b_values[num_values]; gen_random_float_array_pos_neg(num_values, input_b_values); // Setup Input bias using random values uint32_t input_bias_shape[] = {s, p}; num_values = s * p; float input_bias_values[num_values]; gen_random_float_array(num_values, input_bias_values); // Setup Output and expected values uint32_t output_shape[] = {s, m, p}; num_values = s * m * p; float expected_values[num_values]; gen_test_expected_fp32_array(s, m, n, p, test_datatype, input_a_values, input_b_values, input_bias_values, expected_values); zdnn_matmul_op_test(input_a_shape, input_b_shape, input_bias_shape, output_shape, true, input_a_values, input_b_values, input_bias_values, MATMUL_OP_ADDITION, ZDNN_OK, expected_values); } /** * - MatMulCompare (non-stacked) * * - Matrix input_a = 3x3 -- Manually Coded Input * - Matrix input_b = 3x3 -- Manually Coded Input * - Matrix bias = 3 -- Manually Coded Input * - Matrix output = 3x3 */ void test_compare_3x3_by_3x3(zdnn_matmul_ops op, float *exp_vals) { // // input values are derivatives of power-of-2 numbers to minimum // precision loss due to conversion, as that affects comparsions // Setup Input A uint32_t input_a_shape[] = {3, 3}; float input_a_values[] = { 1.0 / 2, 1.0 / 4, 1.0 / 8, 1.0 / 16, 1.0 / 32, 1.0 / 64, 1.0 / 32, 1.0 / 16, 1.0 / 8, }; // Setup Input B uint32_t input_b_shape[] = {3, 3}; float input_b_values[] = {2, 4, 8, 16, 2, 4, 8, 16, 2}; // Setup Input bias uint32_t input_c_shape[] = {3}; float input_c_values[] = {0.65, 4.5, 0.7}; // Output tensor and expected values uint32_t output_shape[] = {input_a_shape[0], input_b_shape[1]}; zdnn_matmul_op_test(input_a_shape, input_b_shape, input_c_shape, output_shape, false, input_a_values, input_b_values, input_c_values, op, ZDNN_OK, exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_greater() { float is_greater_exp_vals[] = {1., 0., 1., 1., 0., 0., 1., 0., 1.}; test_compare_3x3_by_3x3(MATMUL_OP_GREATER, is_greater_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_greater_equal() { float is_greater_equal_exp_vals[] = {1., 1., 1., 1., 0., 0., 1., 0., 1.}; test_compare_3x3_by_3x3(MATMUL_OP_GREATER_EQUAL, is_greater_equal_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_equal() { float is_equal_exp_vals[] = {0., 1., 0., 0., 0., 0., 0., 0., 0.}; test_compare_3x3_by_3x3(MATMUL_OP_EQUAL, is_equal_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_not_equal() { float is_not_equal_exp_vals[] = {1., 0., 1., 1., 1., 1., 1., 1., 1.}; test_compare_3x3_by_3x3(MATMUL_OP_NOT_EQUAL, is_not_equal_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_lesser_equal() { float is_lesser_equal_exp_vals[] = {0., 1., 0., 0., 1., 1., 0., 1., 0.}; test_compare_3x3_by_3x3(MATMUL_OP_LESSER_EQUAL, is_lesser_equal_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_lesser() { float is_lesser_exp_vals[] = {0., 0., 0., 0., 1., 1., 0., 1., 0.}; test_compare_3x3_by_3x3(MATMUL_OP_LESSER, is_lesser_exp_vals); } /** * - MatMulCompare (non-stacked, bigger values) * * - Matrix input_a = 3x3 -- Manually Coded Input * - Matrix input_b = 3x3 -- Manually Coded Input * - Matrix bias = 3 -- Manually Coded Input * - Matrix output = 3x3 */ void test_compare_3x3_by_3x3_bigger_vals(zdnn_matmul_ops op, float *exp_vals) { // Setup Input A uint32_t input_a_shape[] = {3, 3}; float input_a_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // Setup Input B uint32_t input_b_shape[] = {3, 3}; float input_b_values[] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; // Setup Input bias uint32_t input_c_shape[] = {3}; float input_c_values[] = {650, 360, 1000}; // Output tensor and expected values uint32_t output_shape[] = {input_a_shape[0], input_b_shape[1]}; zdnn_matmul_op_test(input_a_shape, input_b_shape, input_c_shape, output_shape, false, input_a_values, input_b_values, input_c_values, op, ZDNN_OK, exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_bigger_vals_greater() { float is_greater_exp_vals[] = {0, 0, 0, 1, 1, 0, 1, 1, 1}; test_compare_3x3_by_3x3_bigger_vals(MATMUL_OP_GREATER, is_greater_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_bigger_vals_greater_equal() { float is_greater_equal_exp_vals[] = {0, 1, 0, 1, 1, 0, 1, 1, 1}; test_compare_3x3_by_3x3_bigger_vals(MATMUL_OP_GREATER_EQUAL, is_greater_equal_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_bigger_vals_equal() { float is_equal_exp_vals[] = {0, 1, 0, 0, 0, 0, 0, 0, 0}; test_compare_3x3_by_3x3_bigger_vals(MATMUL_OP_EQUAL, is_equal_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_bigger_vals_not_equal() { float is_not_equal_exp_vals[] = {1, 0, 1, 1, 1, 1, 1, 1, 1}; test_compare_3x3_by_3x3_bigger_vals(MATMUL_OP_NOT_EQUAL, is_not_equal_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_bigger_vals_lesser_equal() { float is_lesser_equal_exp_vals[] = {1, 1, 1, 0, 0, 1, 0, 0, 0}; test_compare_3x3_by_3x3_bigger_vals(MATMUL_OP_LESSER_EQUAL, is_lesser_equal_exp_vals); } void zdnn_matmul_compare_3x3_by_3x3_bigger_vals_lesser() { float is_lesser_exp_vals[] = {1, 0, 1, 0, 0, 1, 0, 0, 0}; test_compare_3x3_by_3x3_bigger_vals(MATMUL_OP_LESSER, is_lesser_exp_vals); } /** * - MatMulCompare (non-stacked) * * - Matrix input_a = 4x3 -- Manually Coded Input * - Matrix input_b = 3x2 -- Manually Coded Input * - Matrix bias = 2 -- Manually Coded Input * - Matrix output = 4x2 */ void test_compare_4x3_by_3x2(zdnn_matmul_ops op, float *exp_vals) { // Setup Input A uint32_t input_a_shape[] = {4, 3}; float input_a_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Setup Input B uint32_t input_b_shape[] = {3, 2}; float input_b_values[] = {1, 2, 3, 4, 5, 6}; // Setup Input bias uint32_t input_c_shape[] = {2}; float input_c_values[] = {50, 100}; // Output tensor and expected values uint32_t output_shape[] = {input_a_shape[0], input_b_shape[1]}; zdnn_matmul_op_test(input_a_shape, input_b_shape, input_c_shape, output_shape, false, input_a_values, input_b_values, input_c_values, op, ZDNN_OK, exp_vals); } void zdnn_matmul_compare_4x3_by_3x2_greater() { float is_greater_exp_vals[] = {0, 0, 0, 0, 1, 0, 1, 1}; test_compare_4x3_by_3x2(MATMUL_OP_GREATER, is_greater_exp_vals); } void zdnn_matmul_compare_4x3_by_3x2_greater_equal() { float is_greater_equal_exp_vals[] = {0, 0, 0, 0, 1, 1, 1, 1}; test_compare_4x3_by_3x2(MATMUL_OP_GREATER_EQUAL, is_greater_equal_exp_vals); } void zdnn_matmul_compare_4x3_by_3x2_equal() { float is_equal_exp_vals[] = {0, 0, 0, 0, 0, 1, 0, 0}; test_compare_4x3_by_3x2(MATMUL_OP_EQUAL, is_equal_exp_vals); } void zdnn_matmul_compare_4x3_by_3x2_not_equal() { float is_not_equal_exp_vals[] = {1, 1, 1, 1, 1, 0, 1, 1}; test_compare_4x3_by_3x2(MATMUL_OP_NOT_EQUAL, is_not_equal_exp_vals); } void zdnn_matmul_compare_4x3_by_3x2_lesser_equal() { float is_lesser_equal_exp_vals[] = {1, 1, 1, 1, 0, 1, 0, 0}; test_compare_4x3_by_3x2(MATMUL_OP_LESSER_EQUAL, is_lesser_equal_exp_vals); } void zdnn_matmul_compare_4x3_by_3x2_lesser() { float is_lesser_exp_vals[] = {1, 1, 1, 1, 0, 0, 0, 0}; test_compare_4x3_by_3x2(MATMUL_OP_LESSER, is_lesser_exp_vals); } /** * - MatMulBiasAdd Boardcast * * - Matrix input_a = s x m x n --Randomly Generated Positive/Negative Array * - Matrix input_b = 1 x n x p --Randomly Generated Positive/Negative Array * - Matrix bias = 1 x p --Randomly Generated Positive Array * - Matrix output = s x m x p */ void zdnn_matmul_bcast_op_smn_by_np(uint64_t s, uint64_t m, uint64_t n, uint64_t p) { uint64_t num_values = 0; // Setup Input A using random values uint32_t input_a_shape[] = {s, m, n}; num_values = s * m * n; float input_a_values[num_values]; gen_random_float_array_pos_neg(num_values, input_a_values); // Setup Input B using random values uint32_t input_b_shape[] = {n, p}; num_values = n * p; float input_b_values[s * num_values]; gen_random_float_array_pos_neg(num_values, input_b_values); // manually "broadcast" those n*p entries s times across input_b_values[] // because gen_test_expected_fp32_array2() doesn't handle broadcast natively uint64_t size = n * p * sizeof(float); uint8_t *tmp_ptr = (uint8_t *)((uintptr_t)input_b_values + size); for (uint64_t i = 1; i < s; i++) { memcpy((void *)tmp_ptr, (void *)input_b_values, size); tmp_ptr += size; } // Setup Input bias using random values uint32_t input_bias_shape[] = {p}; num_values = p; float input_bias_values[s * num_values]; gen_random_float_array(num_values, input_bias_values); size = p * sizeof(float); tmp_ptr = (uint8_t *)((uintptr_t)input_bias_values + size); for (uint64_t i = 1; i < s; i++) { memcpy((void *)tmp_ptr, (void *)input_bias_values, size); tmp_ptr += size; } // Setup Output and expected values uint32_t output_shape[] = {s, m, p}; num_values = s * m * p; float expected_values[num_values]; gen_test_expected_fp32_array(s, m, n, p, test_datatype, input_a_values, input_b_values, input_bias_values, expected_values); zdnn_matmul_bcast_op_test(input_a_shape, input_b_shape, input_bias_shape, output_shape, input_a_values, input_b_values, input_bias_values, MATMUL_BCAST_OP_ADDITION, ZDNN_OK, expected_values); } void zdnn_matmul_biasadd_3x10x11_by_3x11x2() { zdnn_matmul_biasadd_smn_by_snp(3, 10, 11, 2); } void zdnn_matmul_bcast_op_3x10x11_by_11x2() { zdnn_matmul_bcast_op_smn_by_np(3, 10, 11, 2); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(zdnn_matmul_biasadd_3x3_by_3x3); RUN_TEST_ALL_DATATYPES(zdnn_matmul_biasadd_3x3_by_3x3_bigger_vals); RUN_TEST_ALL_DATATYPES(zdnn_matmul_biasadd_4x3_by_3x2); RUN_TEST_ALL_DATATYPES(zdnn_matmul_biasadd_3x10x11_by_3x11x2); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_greater); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_greater_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_not_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_lesser_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_lesser); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_bigger_vals_greater); RUN_TEST_ALL_DATATYPES( zdnn_matmul_compare_3x3_by_3x3_bigger_vals_greater_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_bigger_vals_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_bigger_vals_not_equal); RUN_TEST_ALL_DATATYPES( zdnn_matmul_compare_3x3_by_3x3_bigger_vals_lesser_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_3x3_by_3x3_bigger_vals_lesser); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_4x3_by_3x2_greater); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_4x3_by_3x2_greater_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_4x3_by_3x2_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_4x3_by_3x2_not_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_4x3_by_3x2_lesser_equal); RUN_TEST_ALL_DATATYPES(zdnn_matmul_compare_4x3_by_3x2_lesser); RUN_TEST_ALL_DATATYPES(zdnn_matmul_bcast_op_3x10x11_by_11x2); return UNITY_END(); } ��������������������������zDNN-1.0.1/tests/testDriver_zdnn_max_elwise.c�������������������������������������������������������0000664�0000000�0000000�00000012034�14364043643�0021240�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_elwise.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} /* * Simple test to drive a full max api. Input tensor 1 has values greater than * those in input tensor 2. */ void api_max_basic() { /* Input 1 values as true NHWC [[ [[3, 30], [6, 60]], [[8, 80], [3, 10]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {1, 2, 2, 2}; float input1_values[] = {3, 30, 6, 60, 8, 80, 3, 10}; /* Input 2 values as true NHWC [[ [[1, 15], [3, 12]], [[4, 40], [4.5, 45]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 15, 3, 12, 4, 40, 4.5, 15}; /* Expected output values as true NHWC [[ [[3, 30], [6, 60]], [[8, 80], [4.5, 45]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_MAX, ZDNN_OK); } // test to drive input tensors with 280 values in their buffer. All randomly // generated numbers in first input tensor will be greater than or equal to // those in the second input tensor to avoid negatives in the output tensor void api_max_med_dims() { uint32_t shape[] = {1, 7, 10, 4}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_MAX, ZDNN_OK); } // test to drive input tensors with 6825 values in their buffer void api_max_high_dims() { uint32_t shape[] = {1, 3, 33, 65}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_MAX, ZDNN_OK); } /* * Simple test to drive a full max api using the Data type and * the 3D layout */ void api_max_3D() { /* Input 1 values as true NHWC [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2, 2}; float input1_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Input 2 values as true NHWC [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 5, 2, 20, 4, 40, 5, 50}; /* Expected values as true NHWC [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_3D, input1_values, input2_values, NNPA_MAX, ZDNN_OK); } /* * Simple test to drive a full max api using the data type * and 2 dimensional tensors */ void api_max_2D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2}; /* Input 1 values as true NHWC [[ [[1, 10], [2, 20]] ]] */ float input1_values[] = {1, 10, 2, 20}; /* Input 2 values as true NHWC [[ [[3, 20], [2, 5]] ]] */ float input2_values[] = {3, 20, 2, 5}; /* Expected values as true NHWC [[ [[3, 20], [2, 20]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_2D, input1_values, input2_values, NNPA_MAX, ZDNN_OK); } /* * Simple test to drive a full max api using the data type * and 1 dimensional tensors */ void api_max_1D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2}; /* Input 1 values as true NHWC [[ [[10000, 12000]] ]] */ float input1_values[] = {10000, 12000}; /* Input 2 values as true NHWC [[ [[2.5, 4000]] ]] */ float input2_values[] = {2.5, 4000}; /* Expected values as true NHWC [[ [[10000, 12000]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_1D, input1_values, input2_values, NNPA_MAX, ZDNN_OK); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(api_max_basic); RUN_TEST_ALL_DATATYPES(api_max_med_dims); RUN_TEST_ALL_DATATYPES(api_max_high_dims); RUN_TEST_ALL_DATATYPES(api_max_3D); RUN_TEST_ALL_DATATYPES(api_max_2D); RUN_TEST_ALL_DATATYPES(api_max_1D); return UNITY_END(); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_meanreduce2d_pool.c������������������������������������������������0000664�0000000�0000000�00000014574�14364043643�0022505�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_pool.h" void setUp(void) { /* This is run before EACH TEST */ tol_bfloat.ulps = 64; tol_bfloat.epsilon_mult = (0.1 / EPSILON_BFLOAT) + 1; tol_fp16.ulps = 64; tol_fp16.epsilon_mult = (0.1 / EPSILON_FP16) + 1; tol_fp32.ulps = 64 * 16384; tol_fp32.epsilon_mult = (0.1 / EPSILON_FLOAT) + 1; VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } void test_meanreduce2d(uint32_t *input_shape, zdnn_data_layouts input_layout, bool repeat_first_input_value, float *input_values, uint32_t *output_shape, zdnn_data_layouts output_layout, zdnn_status expected_status, bool repeat_first_expected_value, float *expected_values) { // Create input and output ztensors zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( input_shape, input_layout, test_datatype, NO_CONCAT, repeat_first_input_value, input_values); zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( output_shape, output_layout, test_datatype, NO_CONCAT, true, ZERO_ARRAY); // Test requires AIU #ifdef TEST_AIU // Call public NNPA method zdnn_status status = zdnn_meanreduce2d(input_ztensor, output_ztensor); // Assert returned status matches expected TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to zdnn_meanreduce2d to returned status %08x but expected " "%08x\n", status, expected_status); fp_tolerance *tol = NULL; switch (output_ztensor->pre_transformed_desc->type) { case BFLOAT: tol = &tol_bfloat; break; case FP16: tol = &tol_fp16; break; case FP32: tol = &tol_fp32; break; default: break; // should never get here } // If expected status is ZDNN_OK, assert output values matches expected if (expected_status == ZDNN_OK) { assert_ztensor_values_adv(output_ztensor, repeat_first_expected_value, expected_values, *tol); } #endif // Cleanup test ztensors free_ztensor_buffers(2, input_ztensor, output_ztensor); } /* * Simple test of basic mean reduce */ void zdnn_meanreduce2d_basic() { zdnn_data_layouts layout = ZDNN_NHWC; /* Visualization of input values [[ [[1, 10], [2, 20], [3, 30]], [[4, 40], [5, 50], [6, 60]], [[7, 70], [8, 80], [9, 90]] ]] */ uint32_t input_shape[] = {1, 3, 3, 2}; float input_values[] = {1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60, 7, 70, 8, 80, 9, 90}; /* Visualization of expected values [[ [[5, 50]] ]] */ uint32_t output_shape[] = {1, 1, 1, 2}; float expected_values[] = {5, 50}; test_meanreduce2d(input_shape, layout, false, input_values, output_shape, layout, ZDNN_OK, false, expected_values); } /* * Check that we don't hit a condition code when Height and Width dimensions are * at the largest size allowed. */ void zdnn_meanreduce2d_max_height_width_dims_pass() { zdnn_data_layouts layout = ZDNN_NHWC; uint32_t input_shape[] = {1, MAXIMUM_POOL_ZERO_STRIDES_KERNEL_SIZE, MAXIMUM_POOL_ZERO_STRIDES_KERNEL_SIZE, 2}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; uint32_t output_shape[] = {1, 1, 1, 2}; // Since all input values are the same, they should average to the same. float *expected_values = input_values; test_meanreduce2d(input_shape, layout, true, input_values, output_shape, layout, ZDNN_OK, true, expected_values); } /* * Check that we hit the expected condition code when height is over the * largest size. */ void zdnn_meanreduce2d_over_max_height_fail() { zdnn_data_layouts layout = ZDNN_NHWC; // over_max_dim is a valid tensor dimension size but is too large for a // meanreduce dimension. This should lead to a condition code from the NNPA. // If not, update the test constant and the API documentation. uint32_t over_max_dim = MAXIMUM_POOL_ZERO_STRIDES_KERNEL_SIZE + 1; uint32_t input_shape[] = {1, over_max_dim, 3, 2}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; uint32_t output_shape[] = {1, 1, 1, 2}; // Output values don't really matter as we expect failure status. float *expected_values = input_values; test_meanreduce2d(input_shape, layout, true, input_values, output_shape, layout, ZDNN_FUNC_RC_F001, true, expected_values); } /* * Check that we hit the expected condition code when width is over the * largest size. */ void zdnn_meanreduce2d_over_max_width_fail() { zdnn_data_layouts layout = ZDNN_NHWC; // over_max_dim is a valid tensor dimension size but is too large for a // meanreduce dimension. This should lead to a condition code from the NNPA. // If not, update the test constant and the API documentation. uint32_t over_max_dim = MAXIMUM_POOL_ZERO_STRIDES_KERNEL_SIZE + 1; uint32_t input_shape[] = {1, 3, over_max_dim, 2}; // Just repeat the same value rather than try and genarate a unique array of // values for this test. float input_values[] = {42}; uint32_t output_shape[] = {1, 1, 1, 2}; // Output values don't really matter as we expect failure status. float *expected_values = input_values; test_meanreduce2d(input_shape, layout, true, input_values, output_shape, layout, ZDNN_FUNC_RC_F001, true, expected_values); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(zdnn_meanreduce2d_basic); RUN_TEST_ALL_DATATYPES(zdnn_meanreduce2d_max_height_width_dims_pass); RUN_TEST_ALL_DATATYPES(zdnn_meanreduce2d_over_max_height_fail); RUN_TEST_ALL_DATATYPES(zdnn_meanreduce2d_over_max_width_fail); return UNITY_END(); } ������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_min_elwise.c�������������������������������������������������������0000664�0000000�0000000�00000012157�14364043643�0021244�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_elwise.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} /* * Simple test to drive a full min api. Input tensor 1 has values greater than * those in input tensor 2. */ void api_min_basic() { /* Input 1 values as true NHWC sized (1,2,2,2) [[ [[3, 30], [6, 60]], [[8, 80], [3, 10]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {1, 2, 2, 2}; float input1_values[] = {3, 30, 6, 60, 8, 80, 3, 10}; /* Input 2 values as true NHWC sized (1,2,2,2) [[ [[1, 15], [3, 12]], [[4, 40], [4.5, 45]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 15, 3, 12, 4, 40, 4.5, 15}; /* Expected values as true NHWC sized (1,2,2,2) [[ [[1, 15], [3, 12]], [[4, 40], [3, 10]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_MIN, ZDNN_OK); } // test to drive input tensors with 280 values in their buffer. All randomly // generated numbers in first input tensor will be greater than or equal to // those in the second input tensor to avoid negatives in the output tensor void api_min_med_dims() { uint32_t shape[] = {1, 7, 10, 4}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_MIN, ZDNN_OK); } // test to drive input tensors with 6825 values in their buffer void api_min_high_dims() { uint32_t shape[] = {1, 3, 33, 65}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_MIN, ZDNN_OK); } /* * Simple test to drive a full min api. */ void api_min_3D() { /* Input 1 values as true NHWC sized (1,2,2,2) [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC uint32_t shape[] = {2, 2, 2}; float input1_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Input 2 values as true NHWC sized (1,2,2,2) [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ // Values in ZDNN_NHWC float input2_values[] = {1, 5, 2, 20, 4, 40, 5, 50}; /* Expected values as true NHWC sized (1,2,2,2) [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_3D, input1_values, input2_values, NNPA_MIN, ZDNN_OK); } /* * Simple test to drive a full min api using the data type * and 2 dimensional tensors */ void api_min_2D() { // Values in ZDNN_NHWC uint32_t shape[] = {2, 2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[1, 10], [2, 20]] ]] */ float input1_values[] = {1, 10, 2, 20}; /* Input 2 values as true NHWC sized (1,1,2,2) [[ [[3, 20], [2, 5]] ]] */ float input2_values[] = {3, 20, 2, 5}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[1, 10], [2, 5]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_2D, input1_values, input2_values, NNPA_MIN, ZDNN_OK); } /* * Simple test to drive a full min api using the data type * and 1 dimensional tensors */ void api_min_1D() { // Values in ZDNN_NHWC uint32_t shape[] = {2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[10000, 12000]] ]] */ float input1_values[] = {10000, 12000}; /* Input 2 values as true NHWC sized (1,1,2,2) [[ [[2.5, 4000]] ]] */ float input2_values[] = {2.5, 4000}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[2.5, 4000]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_1D, input1_values, input2_values, NNPA_MIN, ZDNN_OK); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(api_min_basic); RUN_TEST_ALL_DATATYPES(api_min_med_dims); RUN_TEST_ALL_DATATYPES(api_min_high_dims); RUN_TEST_ALL_DATATYPES(api_min_3D); RUN_TEST_ALL_DATATYPES(api_min_2D); RUN_TEST_ALL_DATATYPES(api_min_1D); return UNITY_END(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_mul_elwise.c�������������������������������������������������������0000664�0000000�0000000�00000011620�14364043643�0021250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_elwise.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} /* * Simple test to drive a full mul api. */ void api_mul_basic() { /* Input 1 values as true NHWC [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {1, 2, 2, 2}; float input1_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Input 2 values as true NHWC [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 10, 2, 20, 4, 40, 5, 50}; /* Expected values as true NHWC [[ [[3, 300], [12, 1200]], [[32, 3200], [45, 4500]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_MUL, ZDNN_OK); } // test to drive input tensors with 280 values in their buffer. void api_mul_med_dims() { uint32_t shape[] = {1, 7, 10, 4}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_MUL, ZDNN_OK); } // test to drive input tensors with 6825 values in their buffer void api_mul_high_dims() { uint32_t shape[] = {1, 3, 33, 65}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_MUL, ZDNN_OK); } /* * Simple test to drive a full mul api. */ void api_mul_3D() { /* Input 1 values as true NHWC [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2, 2}; float input1_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Input 2 values as true NHWC [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 5, 2, 20, 4, 40, 5, 50}; // Create ztensor with input1_values /* Expected values as true NHWC [[ [[3, 300], [12, 1200]], [[32, 3200], [45, 1400]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_3D, input1_values, input2_values, NNPA_MUL, ZDNN_OK); } /* * Simple test to drive a full mul api using the data type * and 2 dimensional tensors */ void api_mul_2D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[1, 10], [2, 20]] ]] */ float input1_values[] = {1, 10, 2, 20}; /* Input 2 values as true NHWC sized (1,1,2,2) [[ [[3, 20], [2, 5]] ]] */ float input2_values[] = {3, 20, 2, 5}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[3, 200], [4, 100]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_2D, input1_values, input2_values, NNPA_MUL, ZDNN_OK); } /* * Simple test to drive a full mul api using the data type * and 1 dimensional tensors */ void api_mul_1D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2}; /* Input 1 values as true NHWC sized (1,1,2,2) [[ [[8, 12]] ]] */ float input1_values[] = {8, 12}; /* Input 2 values as true NHWC sized (1,1,2,2) [[ [[2.5, 4000]] ]] */ float input2_values[] = {2.5, 4000}; /* Expected values as true NHWC sized (1,1,2,2) [[ [[20, 48000]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_1D, input1_values, input2_values, NNPA_MUL, ZDNN_OK); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(api_mul_basic); RUN_TEST_ALL_DATATYPES(api_mul_med_dims); RUN_TEST_ALL_DATATYPES(api_mul_high_dims); RUN_TEST_ALL_DATATYPES(api_mul_3D); RUN_TEST_ALL_DATATYPES(api_mul_2D); RUN_TEST_ALL_DATATYPES(api_mul_1D); return UNITY_END(); } ����������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_relu.c�������������������������������������������������������������0000664�0000000�0000000�00000027461�14364043643�0020064�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_act.h" // ----------------------------------------------------------------------------- // ReLU Unit Testing, for convenience, recall the following: // relu(x) -> if (x>0) {return x; else return 0;} // ----------------------------------------------------------------------------- void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } /** * zdnn_relu_test * * Handles all the logic to run custom tests. */ void zdnn_relu_test(uint32_t *io_dims, zdnn_data_layouts layout, float *input, float *clipping_value, zdnn_status expected_status, float *expected_values) { /* * Input Tensor */ zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( io_dims, layout, test_datatype, NO_CONCAT, false, input); /* * Output Tensor */ zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( io_dims, layout, test_datatype, NO_CONCAT, true, ZERO_ARRAY); /* * Begin Testing! */ zdnn_status status = zdnn_relu(input_ztensor, clipping_value, output_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to zdnn_relu() to returned status %08x but expected %08x\n", status, expected_status); #ifdef TEST_AIU if (expected_status == ZDNN_OK) { assert_ztensor_values(output_ztensor, false, expected_values); } #endif // All done--clean up the tensor buffers free_ztensor_buffers(2, input_ztensor, output_ztensor); } /* ------------------------------------------------------------------------------- ReLU Basic Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_relu_basic_nhwc_basic * * Simple test of all positive input values * Expect a mirror of the Input values as the Output values * * Input values as NHWC * [[ * [[1], [2], [3]], * [[4], [5], [6]], * [[7], [8], [9]] * ]] * * Expected Output values as NHWC * [[ * [[1], [2], [3]], * [[4], [5], [6]], * [[7], [8], [9]] * ]] */ void zdnn_relu_basic_nhwc_basic() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 1}; // Will be same for in and out dim. float input_expected_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; float clip_value = 0; zdnn_relu_test(shape, ZDNN_NHWC, input_expected_values, &clip_value, ZDNN_OK, input_expected_values); } /** * zdnn_relu_basic_nhwc_basic_clip6 * * Simple test of all positive input values * Expect a mirror of the Input values as the Output values * * Input values as NHWC * [[ * [[1], [2], [3]], * [[4], [5], [6]], * [[7], [8], [9]] * ]] * * Expected Output values as NHWC * [[ * [[1], [2], [3]], * [[4], [5], [6]], * [[6], [6], [6]] * ]] */ void zdnn_relu_basic_nhwc_basic_clip6() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 1}; // Will be same for in and out dim. float input_expected_values[] = {1, 2, 3, 4, 5, 6, 6, 6, 6}; float clip_value = 6; zdnn_relu_test(shape, ZDNN_NHWC, input_expected_values, &clip_value, ZDNN_OK, input_expected_values); } /* ------------------------------------------------------------------------------- ReLU Basic Layout: ZDNN_3D ------------------------------------------------------------------------------- */ /** * zdnn_relu_deadneuron_3d_basic * * Simple test of all negative input values * Expect a dead neuron * * Input values as NWC sized (3,3,2): * [[ * [[-1, -10], [-2, -20], [-3, -30]], * [[-4, -40], [-5, -50], [-6, -60]], * [[-7, -70], [-8, -80], [-9, -90]] * ]] * * Expected Output values as NWC sized (3,3,2): * [[ * [[0, 0], [0, 0], [0, 0]], * [[0, 0], [0, 0], [0, 0]], * [[0, 0], [0, 0], [0, 0]] * ]] */ void zdnn_relu_deadneuron_3d_basic() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {3, 3, 2}; // Will be same for in and out dim. float input_values[] = {-1, -10, -2, -20, -3, -30, -4, -40, -5, -50, -6, -60, -7, -70, -8, -80, -9, -90}; float expected_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; zdnn_relu_test(shape, ZDNN_3D, input_values, NULL, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- ReLU Basic Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_relu_balance_nhwc_basic * * Simple test of half positive and half negative input values * Expect 50% zeroed 50% valued * * Input values as NHWC * [[ * [[10, -10], [20, -20], [30, -30]], * [[40, -40], [50, -50], [60, -60]], * [[70, -70], [80, -80], [90, -90]], * ]] * * Expected Output values as NHWC * [[ * [[10, 0], [20, 0], [30, 0]], * [[40, 0], [50, 0], [60, 0]], * [[70, 0], [80, 0], [90, 0]], * ]] */ void zdnn_relu_balance_nhwc_basic() { // Initialize the dimensions for our input tensor uint32_t shape[] = {1, 3, 3, 2}; // Will be same for in and out dim. float input_values[] = {10, -10, 20, -20, 30, -30, 40, -40, 50, -50, 60, -60, 70, -70, 80, -80, 90, -90}; float expected_values[] = {10, 0, 20, 0, 30, 0, 40, 0, 50, 0, 60, 0, 70, 0, 80, 0, 90, 0}; zdnn_relu_test(shape, ZDNN_NHWC, input_values, NULL, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- ReLU Basic Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_relu_balance_nhwc_basic_clip50 * * Simple test of half positive and half negative input values * Expect 50% zeroed 50% valued * * Input values as NHWC * [[ * [[10, -10], [20, -20], [30, -30]], * [[40, -40], [50, -50], [60, -60]], * [[70, -70], [80, -80], [90, -90]], * ]] * * Expected Output values as NHWC * [[ * [[10, 0], [20, 0], [30, 0]], * [[40, 0], [50, 0], [50, 0]], * [[50, 0], [50, 0], [50, 0]], * ]] */ void zdnn_relu_balance_nhwc_basic_clip50() { // Initialize the dimensions for our input tensor uint32_t shape[] = {1, 3, 3, 2}; // Will be same for in and out dim. float input_values[] = {10, -10, 20, -20, 30, -30, 40, -40, 50, -50, 60, -60, 70, -70, 80, -80, 90, -90}; float expected_values[] = {10, 0, 20, 0, 30, 0, 40, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0}; float clip_value = 50; zdnn_relu_test(shape, ZDNN_NHWC, input_values, &clip_value, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- ReLU Large Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_relu_basic_nhwc_large * * Simple test of all positive input values * Expect a mirror of the Input values as the Output values * * Input values as NHWC * [[ * [[65000, 65100, 65200], [64000, 64100, 64200], [63000, 63100, 63200]], * [[62000, 62100, 62200], [61000, 61100, 61200], [60000, 60100, 60200]], * [[59000, 59100, 59200], [58000, 58100, 58200], [57000, 57100, 57200]] * ]] * * Expected Output values as NHWC * [[ * [[65000, 65100, 65200], [64000, 64100, 64200], [63000, 63100, 63200]], * [[62000, 62100, 62200], [61000, 61100, 61200], [60000, 60100, 60200]], * [[59000, 59100, 59200], [58000, 58100, 58200], [57000, 57100, 57200]] * ]] * */ void zdnn_relu_basic_nhwc_large() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 3}; // Will be same for in and out dim. float input_expected_values[] = { 65000, 65100, 65200, 64000, 64100, 64200, 63000, 63100, 63200, 62000, 62100, 62200, 61000, 61100, 61200, 60000, 60100, 60200, 59000, 59100, 59200, 58000, 58100, 58200, 57000, 57100, 57200}; zdnn_relu_test(shape, ZDNN_NHWC, input_expected_values, NULL, ZDNN_OK, input_expected_values); } /* ------------------------------------------------------------------------------- ReLU Large Layout: ZDNN_3D ------------------------------------------------------------------------------- */ /** * zdnn_relu_deadneuron_3d_large * * Simple test of all negative input values * Expect a dead neuron * * Generate a test that is of size 8x8x8 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 8x8x8 * with all 0 zeros. */ void zdnn_relu_deadneuron_3d_large() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {8, 8, 8}; // Will be same for in and out dim. int num_io_buffer_values = shape[0] * shape[1] * shape[2]; float input_values[num_io_buffer_values]; gen_random_float_array_neg(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; gen_float_array_zeros(num_io_buffer_values, expected_values); zdnn_relu_test(shape, ZDNN_3D, input_values, NULL, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- ReLU Large Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_relu_balance_nhwc_large * * Simple test of half positive and half negative input values * Expect 50% zeroed 50% valued * * Generate a test that is of size 50x25x10x1 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 50x25x10x1 * with 50% zeros 50% valued. * * */ void zdnn_relu_balance_nhwc_large() { // Initialize the dimensions for our input tensor uint32_t shape[] = {1, 10, 25, 50}; // Will be same for in and out dim. int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; float input_values[num_io_buffer_values]; gen_random_float_array_pos_neg(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; copy_to_array(num_io_buffer_values, input_values, expected_values); fill_everyother_with_zero_float_array(num_io_buffer_values, expected_values); zdnn_relu_test(shape, ZDNN_NHWC, input_values, NULL, ZDNN_OK, expected_values); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(zdnn_relu_basic_nhwc_basic); RUN_TEST_ALL_DATATYPES(zdnn_relu_basic_nhwc_large); RUN_TEST_ALL_DATATYPES(zdnn_relu_deadneuron_3d_basic); RUN_TEST_ALL_DATATYPES(zdnn_relu_balance_nhwc_basic); RUN_TEST_ALL_DATATYPES(zdnn_relu_deadneuron_3d_large); RUN_TEST_ALL_DATATYPES(zdnn_relu_balance_nhwc_large); RUN_TEST_ALL_DATATYPES(zdnn_relu_basic_nhwc_basic_clip6); RUN_TEST_ALL_DATATYPES(zdnn_relu_balance_nhwc_basic_clip50); return UNITY_END(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_sigmoid.c����������������������������������������������������������0000664�0000000�0000000�00000024336�14364043643�0020546�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_act.h" #include <math.h> // ----------------------------------------------------------------------------- // Sigmoid Unit Testing, for convenience, recall the following: // sigmoid(x) -> [0,1] // For some value x, we squash that value to some real-valued number within // range [0,1]. // For the behind the scenes: // sigmoid(x) -> ( 1 / (1 + e(-x)) ) // https://mathworld.wolfram.com/SigmoidFunction.html // ----------------------------------------------------------------------------- void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } /** * Helper function to compute output tensor values using activation * sigmoid */ void act_sigmoid(float input[], float output[], int num_elems) { for (long i = 0; i < num_elems; i++) { output[i] = 1 / (1 + exp(-input[i])); } } /** * zdnn_sigmoid_test * * Handles all the logic to run custom tests. */ void zdnn_sigmoid_test(uint32_t *shape, zdnn_data_layouts layout, float *input_values, zdnn_status expected_status, float *expected_values) { /* * Input Tensor */ zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( shape, layout, test_datatype, NO_CONCAT, false, input_values); /* * Output Tensor */ zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( shape, layout, test_datatype, NO_CONCAT, true, ZERO_ARRAY); /* * Begin Testing! */ zdnn_status status = zdnn_sigmoid(input_ztensor, output_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to zdnn_sigmoid() to returned status %08x but expected %08x\n", status, expected_status); #ifdef TEST_AIU if (expected_status == ZDNN_OK) { assert_ztensor_values(output_ztensor, false, expected_values); } #endif // All done--clean up the tensor buffers free_ztensor_buffers(2, input_ztensor, output_ztensor); } /* ------------------------------------------------------------------------------- Sigmoid Basic Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_sigmoid_basic_nhwc * * Simple test to demonstrate tanh * * Input values as NHWC sized (1,3,3,1): * [[ * [[0], [1], [2]], * [[3], [4], [5]], * [[6], [7], [8]] * ]] * * Expected Output values as NHWC sized (1,3,3,1): * [[ * [[0.5], [0.7310585786], [0.880797078]], * [[0.9525741268], [0.98201379], [0.9933071491]], * [[0.9975273768], [0.9990889488], [0.9996646499] * ]] * */ void zdnn_sigmoid_basic_nhwc() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 1}; // Will be same for in and out dim. float input_values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; float expected_values[] = { 0.5, 0.7310585786, 0.880797078, 0.9525741268, 0.98201379, 0.9933071491, 0.9975273768, 0.9990889488, 0.9996646499, }; zdnn_sigmoid_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- Sigmoid Basic Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_sigmoid_balanced_nhwc * * Balanced (pos and neg inputs) test to demonstrate sigmoid * * * Input values as NHWC sized (1,3,3,2): * [[ * [[-1, 1], [-2, 2], [-3, 3]], * [[-4, 4], [-5, 5], [-6, 6]], * [[-7, 7], [-8, 8], [-9, 9]], * ]] * * Expected Output values as NHWC sized 1,3,3,2: * [[ * [[0.2689414214, 0.7310585786], [0.119202922 , 0.880797078], [0.0474258732, * 0.9525741268]], * [[0.01798621, 0.98201379], [0.0066928509, 0.9933071491],[0.0024726232, * 0.9975273768]], * [[0.0009110512, 0.9990889488], [0.0003353501, 0.9996646499],[0.0001233946, * 0.9998766054]], * ]] */ void zdnn_sigmoid_balanced_nhwc() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 2}; // Will be same for in and out dim. float input_values[] = {-1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7, -8, 8, -9, 9}; float expected_values[] = { 0.2689414214, 0.7310585786, 0.119202922, 0.880797078, 0.0474258732, 0.9525741268, 0.01798621, 0.98201379, 0.0066928509, 0.9933071491, 0.0024726232, 0.9975273768, 0.0009110512, 0.9990889488, 0.0003353501, 0.9996646499, 0.0001233946, 0.9998766054, }; zdnn_sigmoid_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- Sigmoid Basic Layout: ZDNN_3D ------------------------------------------------------------------------------- */ /** * zdnn_sigmoid_negative_3d * * Simple test to demonstrate tanh * * Input values as NWC sized (1,2,4): * [[ * [[-1, -2, -3, -4], [-5, -6, -7, -8]], * ]] * * Expected Output values as NWC sized (1,2,4): * [[ * [[0.2689414214, 0.119202922, 0.0474258732, 0.01798621], * [0.0066928509, 0.0024726232, 0.0009110512 , 0.0003353501]], * ]] */ void zdnn_sigmoid_negative_3d() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {1, 2, 4}; // Will be same for in and out dim. float input_values[] = {-1, -2, -3, -4, -5, -6, -7, -8}; float expected_values[] = { 0.2689414214, 0.119202922, 0.0474258732, 0.01798621, 0.0066928509, 0.0024726232, 0.0009110512, 0.0003353501, }; zdnn_sigmoid_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- Sigmoid Large Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_sigmoid_basic_nhwc_large * * Simple test of all positive input values * * Input values as NHWC sized (3,3,3,1): * [[ * [[65000, 65100, 65200], [64000, 64100, 64200], [63000, 63100, 63200]], * [[62000, 62100, 62200], [61000, 61100, 61200], [60000, 60100, 60200]], * [[59000, 59100, 59200], [58000, 58100, 58200], [57000, 57100, 57200]] * ]] * * Expected Output values as NHWC sized (3,3,3,1): * */ void zdnn_sigmoid_basic_nhwc_large() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 3}; // Will be same for in and out dim. int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; float input_values[] = {65000, 65100, 65200, 64000, 64100, 64200, 63000, 63100, 63200, 62000, 62100, 62200, 61000, 61100, 61200, 60000, 60100, 60200, 59000, 59100, 59200, 58000, 58100, 58200, 57000, 57100, 57200}; float expected_values[num_io_buffer_values]; act_sigmoid(input_values, expected_values, num_io_buffer_values); zdnn_sigmoid_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- Sigmoid Large Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_sigmoid_balanced_nhwc_large * * Simple test of half positive and half negative input values * * Generate a test that is of size 53x30x11x1 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 53x30x11x1 */ void zdnn_sigmoid_balanced_nhwc_large() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 4, 20, 12}; // Will be same for in and out dim. int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; float input_values[num_io_buffer_values]; gen_random_float_array_pos_neg(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_sigmoid(input_values, expected_values, num_io_buffer_values); zdnn_sigmoid_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- Sigmoid Large Layout: ZDNN_3D ------------------------------------------------------------------------------- */ /** * zdnn_sigmoid_negative_3d_large * * Simple test of all negative input values * * Generate a test that is of size 78x45x30 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 78x45x30 */ void zdnn_sigmoid_negative_3d_large() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {10, 6, 22}; // Will be same for in and out dim. int num_io_buffer_values = shape[0] * shape[1] * shape[2]; float input_values[num_io_buffer_values]; gen_random_float_array_neg(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_sigmoid(input_values, expected_values, num_io_buffer_values); zdnn_sigmoid_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(zdnn_sigmoid_basic_nhwc); RUN_TEST_ALL_DATATYPES(zdnn_sigmoid_basic_nhwc_large); RUN_TEST_ALL_DATATYPES(zdnn_sigmoid_balanced_nhwc); RUN_TEST_ALL_DATATYPES(zdnn_sigmoid_negative_3d); RUN_TEST_ALL_DATATYPES(zdnn_sigmoid_balanced_nhwc_large); RUN_TEST_ALL_DATATYPES(zdnn_sigmoid_negative_3d_large); return UNITY_END(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_softmax.c����������������������������������������������������������0000664�0000000�0000000�00000043042�14364043643�0020567�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_act.h" // ------------------------------------------w----------------------------------- // Softmax Unit Testing, for convenience, recall the following: // softmax(x) -> [0,1] // For some value x, we squash that value to some real-valued number within // range [0,1] -- all components will indeed add up to one, this is mainly // so thar they can be interpreted as probabilities. // For the behind the scenes: // softmax(x) -> ( e(x) / e(x) +e(x) +...+e(x) +e(x) ) // sub 1 sub 2 sub n-1 sub n // https://en.wikipedia.org/wiki/Softmax_function // ----------------------------------------------------------------------------- void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } /** * zdnn_softmax_test * * Handles all the logic to run custom tests. */ void zdnn_softmax_test(uint32_t *shape, zdnn_data_layouts layout, float *input, zdnn_softmax_act act_func, zdnn_status expected_status, float *expected_values) { /* * Input Tensor */ zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( shape, layout, test_datatype, NO_CONCAT, false, input); /* * Output Tensor */ zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( shape, layout, test_datatype, NO_CONCAT, true, ZERO_ARRAY); zdnn_status status; /* * Begin Testing! */ /* once with NULL workarea, once with self-allocated */ status = zdnn_softmax(input_ztensor, NULL, act_func, output_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to zdnn_softmax() with activation function %d returned status %08x " "but expected %08x\n", act_func, status, expected_status); #ifdef TEST_AIU if (expected_status == ZDNN_OK) { assert_ztensor_values(output_ztensor, false, expected_values); } #endif zdnn_reset_ztensor(output_ztensor); void *self_workarea = malloc_aligned_4k(ZDNN_SOFTMAX_SAVEAREA_SIZE); TEST_ASSERT_MESSAGE_FORMATTED( self_workarea, "%s() - can't allocate SOFTMAX workarea\n", __func__); status = zdnn_softmax(input_ztensor, self_workarea, act_func, output_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to zdnn_softmax() with activation function %d and provided " "work_area returned status %08x but expected %08x\n", act_func, status, expected_status); #ifdef TEST_AIU if (expected_status == ZDNN_OK) { assert_ztensor_values(output_ztensor, false, expected_values); } #endif free_aligned_4k(self_workarea); free_ztensor_buffers(2, input_ztensor, output_ztensor); } /* ------------------------------------------------------------------------------- Softmax Basic Layout: 3DS ------------------------------------------------------------------------------- */ /** * zdnn_softmax_basic_3ds_ * * Simple test of all positive input values * Expect a mirror of the Input values as the Output values * * Input values as 3DS * [[ * [[0.5], [1.0], [1.5]], * [[2.0], [2.5], [3.0]], * [[3.5], [4.0], [4.5]] * ]] * * Expected Output values as 3DS with no activation * [[ * [[1.0], [1.0], [1.0]], * [[1.0], [1.0], [1.0]], * [[1.0], [1.0], [1.0]] * ]] * * Expected Output values as 3DS with log activation * [[ * [[0.0], [0.0], [0.0]], * [[0.0], [0.0], [0.0]], * [[0.0], [0.0], [0.0]] * ]] */ void zdnn_softmax_basic_3ds() { // Initialize the dimensions for our input tensor ZDNN_3DS uint32_t shape[] = {3, 3, 1}; // Will be same for in and out dim. float input_values[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5}; float expected_values[] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_NONE, ZDNN_OK, expected_values); float log_expected_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_LOG, ZDNN_OK, log_expected_values); } /* ------------------------------------------------------------------------------- Softmax Basic Layout: 3DS ------------------------------------------------------------------------------- */ /** * zdnn_softmax_balanced_3ds_ * * Balanced (pos and neg inputs) test to demonstrate softmax * * Input values as 3DS * [[ * [[-2, -1.5], [-1, -0.5]], * [[0.5, 1.0], [1.5, 2.0]], * ]] * * Expected Output values as 3DS with no activation * [[ * [[0.37754068, 0.62245935], [0.37754068, 0.62245935]], * [[0.37754068, 0.62245935], [0.37754068, 0.62245935]], * ]] * * Expected Output values as 3DS with log activation * [[ * [[-0.974077 -0.47407693], [-0.974077 -0.47407693]] * [[-0.974077 -0.47407693], [-0.974077 -0.47407693]] * ]] */ void zdnn_softmax_balanced_3ds() { // Initialize the dimensions for our input tensor ZDNN_3DS uint32_t shape[] = {2, 2, 2}; // Will be same for in and out dim. float input_values[] = {-2, -1.5, -1, -0.5, 0.5, 1, 1.5, 2}; float expected_values[] = {0.37754068, 0.62245935, 0.37754068, 0.62245935, 0.37754068, 0.62245935, 0.37754068, 0.62245935}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_NONE, ZDNN_OK, expected_values); float log_expected_values[] = {-0.974077, -0.47407693, -0.974077, -0.47407693, -0.974077, -0.47407693, -0.974077, -0.47407693}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_LOG, ZDNN_OK, log_expected_values); } /* ------------------------------------------------------------------------------- Softmax Basic Layout: ZDNN_3D ------------------------------------------------------------------------------- */ /** * zdnn_softmax_negative_3ds_ * * Negative test to demonstrate tanh * * Input values as NWC sized (1,1,8): * [[ * [[-1.4, -2.8, -3.12, -4.16, -5.20, -6.24, -7.28, -8.32]], * ]] * * Expected Output values as NWC sized (1,1,8) with no activation: * [[ * [[0.656592, 0.161914, 0.117573, * 0.041557, 0.014688, 0.005192, * 0.001835 , 0.000649]], * ]] * * Expected Output values as NWC sized (1,1,8) with log activation: * [[ * [[-0.42069218, -1.8206921, -2.140692, * -3.180692, -4.2206917, -5.260692, * -6.300692, -7.3406916]], * ]] * */ void zdnn_softmax_negative_3ds() { // Initialize the dimensions for our input tensor--ZDNN_3DS [C,W,N] uint32_t shape[] = {1, 1, 8}; // Will be same for in and out dim. float input_values[] = {-1.4, -2.8, -3.12, -4.16, -5.20, -6.24, -7.28, -8.32}; float expected_values[] = {0.656592, 0.161914, 0.117573, 0.041557, 0.014688, 0.005192, 0.001835, 0.000649}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_NONE, ZDNN_OK, expected_values); float log_expected_values[] = {-0.42069218, -1.8206921, -2.140692, -3.180692, -4.2206917, -5.260692, -6.300692, -7.3406916}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_LOG, ZDNN_OK, log_expected_values); } /* ------------------------------------------------------------------------------- Softmax Large Layout: 3DS ------------------------------------------------------------------------------- */ /** * zdnn_softmax_basic_3ds_large * * Simple test of all positive input values * Expect a mirror of the Input values as the Output values * * Input values as 3DS * [[ * [[0.65536, 0.65100, 0.65200], * [0.64000, 0.64100, 0.64200], * [0.63000, 0.63100, 0.63200]], * [[0.62000, 0.62100, 0.62200], * [0.61000, 0.61100, 0.61200], * [0.60000, 0.60100, 0.60200]], * [[0.59000, 0.59100, 0.59200], * [0.58000, 0.58100, 0.58200], * [0.57000, 0.57100, 0.57200]] * ]] * * Expected Output values as 3DS with no activation * [[ * [[0.33419162, 0.3327377, 0.33307064] * [0.33300006, 0.33333322, 0.33366674] * [0.33300006, 0.33333322, 0.33366674]] * [[0.33300006, 0.3333332, 0.3336667] * [0.33300006, 0.3333332, 0.3336667] * [0.33300006, 0.3333332, 0.3336667]] * [[0.33300003, 0.3333332, 0.3336667] * [0.33300006, 0.33333322, 0.33366674] * [0.33300006, 0.33333322, 0.33366674]] * ]] * * Expected Output values as 3DS with log activation * [[ * [[-1.0960407 -1.1004007 -1.0994008] * [-1.0996126 -1.0986125 -1.0976126] * [-1.0996126 -1.0986125 -1.0976126]] * [[-1.0996126 -1.0986127 -1.0976126] * [-1.0996126 -1.0986127 -1.0976126] * [-1.0996126 -1.0986127 -1.0976126]] * [[-1.0996127 -1.0986127 -1.0976126] * [-1.0996126 -1.0986125 -1.0976126] * [-1.0996126 -1.0986127 -1.0976126]] * ]] */ void zdnn_softmax_basic_3ds_large() { // Initialize the dimensions for our input tensor ZDNN_3DS uint32_t shape[] = {3, 3, 3}; float input_values[] = {0.65536, 0.65100, 0.65200, 0.64000, 0.64100, 0.64200, 0.63000, 0.63100, 0.63200, 0.62000, 0.62100, 0.62200, 0.61000, 0.61100, 0.61200, 0.60000, 0.60100, 0.60200, 0.59000, 0.59100, 0.59200, 0.58000, 0.58100, 0.58200, 0.57000, 0.57100, 0.57200}; float expected_values[] = { 0.33419162, 0.3327377, 0.33307064, 0.33300006, 0.33333322, 0.33366674, 0.33300006, 0.33333322, 0.33366674, 0.33300006, 0.3333332, 0.3336667, 0.33300006, 0.3333332, 0.3336667, 0.33300006, 0.3333332, 0.3336667, 0.33300003, 0.3333332, 0.3336667, 0.33300006, 0.33333322, 0.33366674, 0.33300006, 0.33333322, 0.33366674}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_NONE, ZDNN_OK, expected_values); float log_expected_values[] = { -1.0960407, -1.1004007, -1.0994008, -1.0996126, -1.0986125, -1.0976126, -1.0996126, -1.0986125, -1.0976126, -1.0996126, -1.0986127, -1.0976126, -1.0996126, -1.0986127, -1.0976126, -1.0996126, -1.0986127, -1.0976126, -1.0996127, -1.0986127, -1.0976126, -1.0996126, -1.0986125, -1.0976126, -1.0996126, -1.0986127, -1.0976126}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_LOG, ZDNN_OK, log_expected_values); } /* ------------------------------------------------------------------------------- Softmax Large Layout: 3DS ------------------------------------------------------------------------------- */ /** * zdnn_softmax_balanced_3ds_large * * Input values as 3DS * [[[ 0.9356609 , 1.0854305 , -0.93788373], * [-0.5061547 , 1.3169702 , 0.7137579 ]], * [[-0.4126717 , -0.40257987, 2.0713255 ], * [-0.35911667, 0.3861619 , 1.9897066 ]], * [[-0.2823396 , -0.5135972 , -0.8962833 ], * [-0.0901652 , -0.73964226, -0.46269894]], * [[ 0.42379895, 1.1180195 , 1.4442351 ], * [-1.0771092 , 0.9014347 , -0.14529487]], * [[ 1.173365 , 1.510687 , -0.46714714], * [ 1.3281798 , 1.7365712 , -1.5435543 ]], * [[ 0.35064182, 0.5708492 , -1.8452454 ], * [ 0.9243176 , 0.57233644, -1.0959795 ]], * [[-0.62557054, 0.686686 , 0.4222773 ], * [-0.2146352 , -0.81243026, -1.1678637 ]], * [[ 1.6384528 , 1.187959 , -2.5538385 ], * [-0.39338952, 0.233341 , -1.6181145 ]], * [[-0.8736809 , 0.05150718, 2.2328985 ], * [ 2.8749912 , 0.08306922, -0.9871888 ]], * [[ 0.47143334, -1.7806206 , -0.27681163], * [-0.9240901 , 1.3088665 , 0.7826533 ]]] * * Expected Output values as 3DS with no activation * [[ * [[0.43193838, 0.5017252, 0.06633637], * [0.09453523, 0.5852842, 0.32018057]], * [[0.07143247, 0.07215702, 0.85641056], * [0.07363626, 0.15515368, 0.7712101 ]], * [[0.42831188, 0.3398805, 0.23180765], * [0.45222163, 0.23620388, 0.31157458]], * [[0.17311363, 0.3465991, 0.48028725], * [0.09283915, 0.67143184, 0.23572904]], * [[0.38534594, 0.5399429, 0.07471115], * [0.390473, 0.58742595, 0.02210104]], * [[0.42416108, 0.5286468, 0.04719208], * [0.5446892, 0.38307628, 0.07223454]], * [[0.13216929, 0.49094895, 0.37688172], * [0.51665765, 0.28417364, 0.19916865]], * [[0.6051712, 0.3856837, 0.00914512], * [0.31592378, 0.5912456, 0.09283058]], * [[0.03865956, 0.09751265, 0.86382776], * [0.9239366, 0.05664035, 0.01942311]], * [[0.6335613, 0.06663986, 0.29979888], * [0.06313774, 0.5889111, 0.34795114]] * ]] * * Expected Output values as 3DS with log activation * [[ * [[-0.83947235 -0.68970275 -2.713017 ] * [-2.3587828 -0.53565776 -1.1388701 ]] * [[-2.6390028 -2.6289108 -0.1550054 ] * [-2.6086178 -1.8633392 -0.25979444]] * [[-0.84790367 -1.0791612 -1.4618473 ] * [-0.79358286 -1.4430599 -1.1661166 ]] * [[-1.7538071 -1.0595865 -0.7333709 ] * [-2.3768868 -0.39834276 -1.4450723 ]] * [[-0.9536138 -0.6162919 -2.594126 ] * [-0.9403964 -0.5320051 -3.8121307 ]] * [[-0.857642 -0.6374347 -3.0535293 ] * [-0.60753995 -0.9595212 -2.627837 ]] * [[-2.0236716 -0.7114151 -0.9758239 ] * [-0.6603748 -1.2581699 -1.6136034 ]] * [[-0.5022439 -0.9527377 -4.6945353 ] * [-1.1522543 -0.5255238 -2.376979 ]] * [[-3.2529612 -2.327773 -0.14638188] * [-0.07911182 -2.8710337 -3.9412918 ]] * [[-0.4563985 -2.7084525 -1.2046435 ] * [-2.7624366 -0.52948 -1.0556931 ]]] * ]] */ void zdnn_softmax_balanced_3ds_large() { // Initialize the dimensions for our input tensor ZDNN_3DS uint32_t shape[] = {10, 2, 3}; // Will be same for in and out dim. float input_values[] = { 0.9356609, 1.0854305, -0.93788373, -0.5061547, 1.3169702, 0.7137579, -0.4126717, -0.40257987, 2.0713255, -0.35911667, 0.3861619, 1.9897066, -0.2823396, -0.5135972, -0.8962833, -0.0901652, -0.73964226, -0.46269894, 0.42379895, 1.1180195, 1.4442351, -1.0771092, 0.9014347, -0.14529487, 1.173365, 1.510687, -0.46714714, 1.3281798, 1.7365712, -1.5435543, 0.35064182, 0.5708492, -1.8452454, 0.9243176, 0.57233644, -1.0959795, -0.62557054, 0.686686, 0.4222773, -0.2146352, -0.81243026, -1.1678637, 1.6384528, 1.187959, -2.5538385, -0.39338952, 0.233341, -1.6181145, -0.8736809, 0.05150718, 2.2328985, 2.8749912, 0.08306922, -0.9871888, 0.47143334, -1.7806206, -0.27681163, -0.9240901, 1.3088665, 0.7826533}; float expected_values[] = { 0.43193838, 0.5017252, 0.06633637, 0.09453523, 0.5852842, 0.32018057, 0.07143247, 0.07215702, 0.85641056, 0.07363626, 0.15515368, 0.7712101, 0.42831188, 0.3398805, 0.23180765, 0.45222163, 0.23620388, 0.31157458, 0.17311363, 0.3465991, 0.48028725, 0.09283915, 0.67143184, 0.23572904, 0.38534594, 0.5399429, 0.07471115, 0.390473, 0.58742595, 0.02210104, 0.42416108, 0.5286468, 0.04719208, 0.5446892, 0.38307628, 0.07223454, 0.13216929, 0.49094895, 0.37688172, 0.51665765, 0.28417364, 0.19916865, 0.6051712, 0.3856837, 0.00914512, 0.31592378, 0.5912456, 0.09283058, 0.03865956, 0.09751265, 0.86382776, 0.9239366, 0.05664035, 0.01942311, 0.6335613, 0.06663986, 0.29979888, 0.06313774, 0.5889111, 0.34795114}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_NONE, ZDNN_OK, expected_values); float log_expected_values[] = { -0.83947235, -0.68970275, -2.713017, -2.3587828, -0.53565776, -1.1388701, -2.6390028, -2.6289108, -0.1550054, -2.6086178, -1.8633392, -0.25979444, -0.84790367, -1.0791612, -1.4618473, -0.79358286, -1.4430599, -1.1661166, -1.7538071, -1.0595865, -0.7333709, -2.3768868, -0.39834276, -1.4450723, -0.9536138, -0.6162919, -2.594126, -0.9403964, -0.5320051, -3.8121307, -0.857642, -0.6374347, -3.0535293, -0.60753995, -0.9595212, -2.627837, -2.0236716, -0.7114151, -0.9758239, -0.6603748, -1.2581699, -1.6136034, -0.5022439, -0.9527377, -4.6945353, -1.1522543, -0.5255238, -2.376979, -3.2529612, -2.327773, -0.14638188, -0.07911182, -2.8710337, -3.9412918, -0.4563985, -2.7084525, -1.2046435, -2.7624366, -0.52948, -1.0556931}; zdnn_softmax_test(shape, ZDNN_3DS, input_values, SOFTMAX_ACT_LOG, ZDNN_OK, log_expected_values); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(zdnn_softmax_basic_3ds); RUN_TEST_ALL_DATATYPES(zdnn_softmax_basic_3ds_large); RUN_TEST_ALL_DATATYPES(zdnn_softmax_balanced_3ds); RUN_TEST_ALL_DATATYPES(zdnn_softmax_negative_3ds); RUN_TEST_ALL_DATATYPES(zdnn_softmax_balanced_3ds_large); return UNITY_END(); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testDriver_zdnn_sub_elwise.c�������������������������������������������������������0000664�0000000�0000000�00000014744�14364043643�0021256�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_elwise.h" void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) {} /* * Simple test to drive a full sub api. Input tensor 1 has values greater than * those in input tensor 2, so the result values will not be negative. */ void api_sub_basic() { /* Input 1 values as true NHWC [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {1, 2, 2, 2}; float input1_values[] = {3, 8, 6, 9, 30, 80, 60, 90}; /* Input 2 values as true NHWC [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 4, 2, 5, 10, 40, 20, 50}; /* Expected values as true NHWC [[ [[2, 20], [4, 40]], [[4, 40], [4, 40]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_SUB, ZDNN_OK); } // test to drive input tensors with 280 values in their buffer. All randomly // generated numbers in first input tensor will be greater than or equal to // those in the second input tensor to avoid negatives in the output tensor void api_sub_med_dims() { uint32_t shape[] = {1, 7, 10, 4}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_SUB, ZDNN_OK); } // test to drive input tensors with 6825 values in their buffer void api_sub_high_dims() { uint32_t shape[] = {1, 3, 33, 65}; int num_io_buffer_values = shape[0] * shape[1] * shape[2] * shape[3]; // Values in ZDNN_NHWC order float input1_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input1_values); // Values in ZDNN_NHWC order float input2_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input2_values); test_elwise_api_2_inputs(shape, ZDNN_NHWC, input1_values, input2_values, NNPA_SUB, ZDNN_OK); } /* * Simple test to drive a full sub api. */ void api_sub_3D() { /* Input 1 values as true NHWC [[ [[3, 30], [6, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2, 2}; float input1_values[] = {3, 30, 6, 60, 8, 80, 9, 90}; /* Input 2 values as true NHWC [[ [[1, 10], [2, 20]], [[4, 40], [5, 50]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 10, 2, 20, 4, 40, 5, 50}; /* Expected values as true NHWC [[ [[2, 20], [4, 40]], [[4, 40], [4, 40]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_3D, input1_values, input2_values, NNPA_SUB, ZDNN_OK); } /* * Simple test to drive a full sub api using the data type * and 2 dimensional tensors */ void api_sub_2D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2, 2}; /* Input 1 values as true NHWC [[ [[3, 20], [2, 20]] ]] */ float input1_values[] = {3, 20, 2, 20}; /* Input 2 values as true NHWC [[ [[1, 10], [2, 5]] ]] */ float input2_values[] = {1, 10, 2, 5}; /* Expected values as true NHWC [[ [[2, 10], [0, 15]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_2D, input1_values, input2_values, NNPA_SUB, ZDNN_OK); } /* * Simple test to drive a full sub api using the data type * and 1 dimensional tensors */ void api_sub_1D() { // Values in ZDNN_NHWC order uint32_t shape[] = {2}; /* Input 1 values as true NHWC [[ [[8, 4000]] ]] */ float input1_values[] = {8, 4000}; /* Input 2 values as true NHWC [[ [[2.5, 12]] ]] */ float input2_values[] = {2.5, 12}; /* Expected values as true NHWC [[ [[5.5, 3988]] ]] */ test_elwise_api_2_inputs(shape, ZDNN_1D, input1_values, input2_values, NNPA_SUB, ZDNN_OK); } /* * Simple test to drive a full sub api, resulting in underflow. * Input tensors 1 and 2 have negative values, such that when tensor 2 * is subtracted from tensor 1, the result values will be negative, and * one value will be exceed the DLFloat16 capability. */ void api_sub_underflow() { /* Input 1 values as true NHWC [[ [[3, 30], [-MAX_DLF16 * 0.75, 60]], [[8, 80], [9, 90]] ]] */ // Values in ZDNN_NHWC order uint32_t shape[] = {1, 2, 2, 2}; float input1_values[] = {3, 8, -MAX_DLF16 * 0.75, 9, 30, 80, 60, 90}; /* Input 2 values as true NHWC [[ [[1, 10], [-MAX_DLF16 * 0.75, 20]], [[4, 40], [5, 50]] ]] */ // Values in ZDNN_NHWC order float input2_values[] = {1, 4, MAX_DLF16 * 0.75, 5, 10, 40, 20, 50}; /* Expected values as true NHWC [[ [[2, 20], [UNDERFLOW, 40]], [[4, 40], [4, 40]] ]] */ // when overflow/underflow happens, AIU sets range violation flag test_elwise_api_2_inputs_adv(shape, ZDNN_NHWC, FP32, input1_values, input2_values, NNPA_SUB, ZDNN_ELEMENT_RANGE_VIOLATION); test_elwise_api_2_inputs_adv(shape, ZDNN_NHWC, BFLOAT, input1_values, input2_values, NNPA_SUB, ZDNN_ELEMENT_RANGE_VIOLATION); // Note: We can't create an add/sub overflow/underflow with values that // originate as FP16s, since FP16's max is way below the DLFloat max. } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(api_sub_basic); RUN_TEST_ALL_DATATYPES(api_sub_med_dims); RUN_TEST_ALL_DATATYPES(api_sub_high_dims); RUN_TEST_ALL_DATATYPES(api_sub_3D); RUN_TEST_ALL_DATATYPES(api_sub_2D); RUN_TEST_ALL_DATATYPES(api_sub_1D); RUN_TEST(api_sub_underflow); return UNITY_END(); } ����������������������������zDNN-1.0.1/tests/testDriver_zdnn_tanh.c�������������������������������������������������������������0000664�0000000�0000000�00000076760�14364043643�0020055�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common_act.h" // ----------------------------------------------------------------------------- // TanH Unit Testing, for convenience, recall the following: // tanh(x) -> [-1,1] // For some value x, we squash that value to some real-valued number within // range [-1,1]. Negative inputs are mapped strongly negative and zero // inputs are mapped near zero. // For the behind the scenes: // tanh(x) -> ( 1 - e(-2(x)) ) / ( 1 + e(-2(x)) ) // https://functions.wolfram.com/ElementaryFunctions/Tanh/ // introductions/Tanh/ShowAll.html // ----------------------------------------------------------------------------- void setUp(void) { /* This is run before EACH TEST */ VERIFY_HW_ENV; } void tearDown(void) { /* This is run after EACH TEST */ } /** * Helper function to compute output tensor values using activation * tanh */ void act_tanh(float input[], float output[], int num_elems) { for (long i = 0; i < num_elems; i++) { output[i] = (2 / (1 + exp(-2 * input[i]))) - 1; } } /** * zdnn_tanh_test * * Handles all the logic to run custom tests. */ void zdnn_tanh_test(uint32_t *shape, zdnn_data_layouts layout, float *input, zdnn_status expected_status, float *expected_values) { /* * Input Tensor */ zdnn_ztensor *input_ztensor = alloc_ztensor_with_values( shape, layout, test_datatype, NO_CONCAT, false, input); /* * Output Tensor */ zdnn_ztensor *output_ztensor = alloc_ztensor_with_values( shape, layout, test_datatype, NO_CONCAT, true, ZERO_ARRAY); /* * Begin Testing! */ zdnn_status status = zdnn_tanh(input_ztensor, output_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == expected_status, "call to zdnn_tanh() to returned status %08x but expected " "%08x\n", status, expected_status); #ifdef TEST_AIU // Only check expected values if we expected the NNPA call to be successful if (expected_status == ZDNN_OK) { assert_ztensor_values(output_ztensor, false, expected_values); } #endif // All done--clean up the tensor buffers free_ztensor_buffers(2, input_ztensor, output_ztensor); } /* ------------------------------------------------------------------------------- TanH Basic Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_tanh_basic_nhwc * * Simple test to demonstrate tanh * * Input values as NHWC sized (1,3,3,1): * [[ * [[0.01], [0.02], [0.03]], * [[0.04], [0.05], [0.06]], * [[0.07], [0.08], [0.09]] * ]] * * Expected Output values as NHWC sized (1,3,3,1): * [[ * [[0.00999966667999946], [0.019997333759930933], [0.029991003238820143]], * [[0.03997868031116357], [0.04995837495787998], [0.059928103529143496]], * [[0.06988589031642899], [0.07982976911113136], [0.0897577847471601] * ]] */ void zdnn_tanh_basic_nhwc_1() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 1}; // Will be same for in and out dim. float input_values[] = {0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09}; float expected_values[] = { 0.00999966667999946, 0.019997333759930933, 0.029991003238820143, 0.03997868031116357, 0.04995837495787998, 0.059928103529143496, 0.06988589031642899, 0.07982976911113136, 0.0897577847471601}; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_zeros_nhwc * * Zero test to demonstrate tanh * * Input values as NHWC sized (1, 3, 3, 3): * [[ * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]] * ]] * * Expected Output values as NHWC sized (1, 3, 3, 3): * [[ * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]] * ]] */ void zdnn_tanh_zeros_nhwc_1() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 3}; // Will be same for in and out dim. float input_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; float expected_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_negative_nhwc * * Negative test to demonstrate tanh * * Input values as NHWC sized (1,3,3,1): * [[ * [[-0.01], [-0.02], [-0.03]], * [[-0.04], [-0.05], [-0.06]], * [[-0.07], [-0.08], [-0.09]] * ]] * * Expected Output values as NHWC sized (1,3,3,1): * [[ * [[-0.00999966667999946], [-0.019997333759930933], * [-0.029991003238820143]], * [[-0.03997868031116357], [-0.04995837495787998], [-0.059928103529143496]], * [[-0.06988589031642899], [-0.07982976911113136], [-0.0897577847471601] * ]] */ void zdnn_tanh_negative_nhwc_1() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 1}; // Will be same for in and out dim. float input_values[] = {-0.01, -0.02, -0.03, -0.04, -0.05, -0.06, -0.07, -0.08, -0.09}; float expected_values[] = { -0.00999966667999946, -0.019997333759930933, -0.029991003238820143, -0.03997868031116357, -0.04995837495787998, -0.059928103529143496, -0.06988589031642899, -0.07982976911113136, -0.0897577847471601}; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_positive_nhwc * * Positive test to demonstrate tanh * * Input values as NHWC sized (4, 1, 1, 1) * [[ * [[0.01]], * [[0.02]], * [[0.03]], * [[0.04]], * ]] * * Expected Output values as NHWC sized (4, 1, 1, 1): * [[ * [[0.00999966667999946]], * [[0.019997333759930933]], * [[0.029991003238820143]], * [[0.03997868031116357]], * ]] */ void zdnn_tanh_positive_nhwc_1() { uint32_t shape[] = {4, 1, 1, 1}; // Will be same for in and out dim. float input_values[] = {0.01, 0.02, 0.03, 0.04}; float expected_values[] = {0.00999966667999946, 0.019997333759930933, 0.029991003238820143, 0.03997868031116357}; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_balanced_nhwc * * Balanced (pos and neg inputs) test to demonstrate tanh * * Input values as NHWC sized (1, 1, 2, 6) * [[ * [[-0.05, -0.04, -0.03, -0.02, -0.01, -0.00], * [0.01, 0.02, 0.03, 0.04, 0.05, 0.06]] * ]] * * Expected Output values as NHWC sized (1, 1, 2, 6): * [[ * [[-0.04995837495787998, -0.03997868031116357, -0.029991003238820143, * -0.019997333759930933, -0.00999966667999946, 0.0], * [0.00999966667999946, 0.019997333759930933, 0.029991003238820143, * 0.03997868031116357, 0.04995837495787998, 0.059928103529143496]] * ]] */ void zdnn_tanh_balanced_nhwc_1() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 1, 2, 6}; // Will be same for in and out dim. float input_values[] = {-0.05, -0.04, -0.03, -0.02, -0.01, 0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06}; float expected_values[] = { -0.04995837495787998, -0.03997868031116357, -0.029991003238820143, -0.019997333759930933, -0.00999966667999946, 0.0, 0.00999966667999946, 0.019997333759930933, 0.029991003238820143, 0.03997868031116357, 0.04995837495787998, 0.059928103529143496}; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- TanH Basic Layout: ZDNN_3D ------------------------------------------------------------------------------- */ /** * zdnn_tanh_basic_3d * * Simple test to demonstrate tanh * * Input values as NWC sized (1,3,1): * [[ * [[0.01], [0.02], [0.03]], * [[0.04], [0.05], [0.06]], * [[0.07], [0.08], [0.09]] * ]] * * Expected Output values as NWC sized (1,3,1): * [[ * [[0.00999966667999946], [0.019997333759930933], [0.029991003238820143]], * [[0.03997868031116357], [0.04995837495787998], [0.059928103529143496]], * [[0.06988589031642899], [0.07982976911113136], [0.0897577847471601] * ]] */ void zdnn_tanh_basic_3d_1() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {1, 3, 1}; // Will be same for in and out dim. float input_values[] = {0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09}; float expected_values[] = { 0.00999966667999946, 0.019997333759930933, 0.029991003238820143, 0.03997868031116357, 0.04995837495787998, 0.059928103529143496, 0.06988589031642899, 0.07982976911113136, 0.0897577847471601}; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_zeros_3d * * Zero test to demonstrate tanh * * Input values as NWC sized (1,3,3): * [[ * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]] * ]] * * Expected Output values as NWC sized (1,3,3): * [[ * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]] * ]] */ void zdnn_tanh_zeros_3d_1() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {1, 3, 3}; // Will be same for in and out dim. float input_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; float expected_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_negative_3d * * Negative test to demonstrate tanh * * Input values as NWC sized (1,3,3): * [[ * [[-0.01], [-0.02], [-0.03]], * [[-0.04], [-0.05], [-0.06]], * [[-0.07], [-0.08], [-0.09]] * ]] * * Expected Output values as NWC sized (1,3,3): * [[ * [[-0.00999966667999946], [-0.019997333759930933], * [-0.029991003238820143]], * [[-0.03997868031116357], [-0.04995837495787998], [-0.059928103529143496]], * [[-0.06988589031642899], [-0.07982976911113136], [-0.0897577847471601] * ]] */ void zdnn_tanh_negative_3d_1() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {1, 3, 3}; // Will be same for in and out dim. float input_values[] = {-0.01, -0.02, -0.03, -0.04, -0.05, -0.06, -0.07, -0.08, -0.09}; float expected_values[] = { -0.00999966667999946, -0.019997333759930933, -0.029991003238820143, -0.03997868031116357, -0.04995837495787998, -0.059928103529143496, -0.06988589031642899, -0.07982976911113136, -0.0897577847471601}; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_positive_3d * * Positive test to demonstrate tanh * * * Input values as NWC sized (4, 1, 1) * [[ * [[0.01]], * [[0.02]], * [[0.03]], * [[0.04]], * ]] * * Expected Output values as NWC sized (4, 1, 1): * [[ * [[0.00999966667999946]], * [[0.019997333759930933]], * [[0.029991003238820143]], * [[0.03997868031116357]], * ]] */ void zdnn_tanh_positive_3d_1() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {4, 1, 1}; // Will be same for in and out dim. float input_values[] = {0.01, 0.02, 0.03, 0.04}; float expected_values[] = {0.00999966667999946, 0.019997333759930933, 0.029991003238820143, 0.03997868031116357}; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_balanced_3d * * Balanced (pos and neg inputs) test to demonstrate tanh * * Input values as NWC sized (1, 2, 6) * [[ * [[-0.05, -0.04, -0.03, -0.02, -0.01, -0.00], * [0.01, 0.02, 0.03, 0.04, 0.05, 0.06]] * ]] * * Expected Output values as NWC sized (1, 2, 6): * [[ * [[-0.04995837495787998, -0.03997868031116357, -0.029991003238820143, * -0.019997333759930933, -0.00999966667999946, 0.0], * [0.00999966667999946, 0.019997333759930933, 0.029991003238820143, * 0.03997868031116357, 0.04995837495787998, 0.059928103529143496]] * ]] * */ void zdnn_tanh_balanced_3d_1() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {1, 2, 6}; // Will be same for in and out dim. float input_values[] = {-0.05, -0.04, -0.03, -0.02, -0.01, 0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06}; float expected_values[] = { -0.04995837495787998, -0.03997868031116357, -0.029991003238820143, -0.019997333759930933, -0.00999966667999946, 0.0, 0.00999966667999946, 0.019997333759930933, 0.029991003238820143, 0.03997868031116357, 0.04995837495787998, 0.059928103529143496}; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- TanH Basic Layout: NHWC ------------------------------------------------------------------------------- */ /** * zdnn_tanh_basic_nhwc * * Simple test to demonstrate tanh * * Input values as NHWC sized (1,3,3,1): * [[ * [[1], [2], [3]], * [[4], [5], [6]], * [[7], [8], [9]] * ]] * * Expected Output values as NHWC sized (1,3,3,1): * [[ * [[0.761594156], [0.9640275801], [0.9950547537]], * [[0.9993292997], [0.9999092043], [0.9999877117]], * [[0.9999983369], [0.9999997749], [0.9999999695] * ]] */ void zdnn_tanh_basic_nhwc_2() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 1}; // Will be same for in and out dim. float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; float expected_values[] = { 0.761594156, 0.9640275801, 0.9950547537, 0.9993292997, 0.9999092043, 0.9999877117, 0.9999983369, 0.9999997749, 0.9999999695, }; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_zeros_nhwc * * Zero test to demonstrate tanh * * Input values as NHWC sized (1, 3, 3, 3): * [[ * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]] * ]] * * Expected Output values as NHWC sized (1, 3, 3, 3): * [[ * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]] * ]] */ void zdnn_tanh_zeros_nhwc_2() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 3}; // Will be same for in and out dim. float input_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; float expected_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_negative_nhwc * * Negative test to demonstrate tanh * * Input values as NHWC sized (1, 3, 3, 1): * [[ * [[-1], [-2], [-3]], * [[-4], [-5], [-6]], * [[-7], [-8], [-9]] * ]] * * Expected Output values as NHWC sized (1, 3, 3, 1): * [[ * [[-0.761594156], [-0.9640275801], [-0.9950547537]], * [[-0.9993292997], [-0.9999092043], [-0.9999877117]], * [[-0.9999983369], [-0.9999997749], [-0.9999999695]] * ]] */ void zdnn_tanh_negative_nhwc_2() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 3, 3, 1}; // Will be same for in and out dim. float input_values[] = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; float expected_values[] = { -0.761594156, -0.9640275801, -0.9950547537, -0.9993292997, -0.9999092043, -0.9999877117, -0.9999983369, -0.9999997749, -0.9999999695, }; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_positive_nhwc * * Positive test to demonstrate tanh * * Input values as NHWC sized (9, 1, 1, 1) * [[ * [[1]], * [[2]], * [[3]], * [[4]], * [[5]], * [[6]], * [[7]], * [[8]], * [[9]], * ]] * * Expected Output values as NHWC sized (9, 1, 1, 1): * [[ * [[0.761594156]], * [[0.9640275801]], * [[0.9950547537]], * [[0.9993292997]], * [[0.9999092043]], * [[0.9999877117]], * [[0.9999983369]], * [[0.9999997749]], * [[0.9999999695]], * ]] */ void zdnn_tanh_positive_nhwc_2() { uint32_t shape[] = {9, 1, 1, 1}; // Will be same for in and out dim. float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; float expected_values[] = { 0.761594156, 0.9640275801, 0.9950547537, 0.9993292997, 0.9999092043, 0.9999877117, 0.9999983369, 0.9999997749, 0.9999999695, }; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_balanced_nhwc * * Balanced (pos and neg inputs) test to demonstrate tanh * * Input values as NHWC sized (1, 1, 3, 5) * [[ * [[-4, -2, 0, 2, 4], [-3, -1, 0, 1, 3], [-8, -6, 0, 6, 8]] * ]] * * Expected Output values as NHWC sized (1, 1, 3, 5): * [[ * [[ -0.9993292997, -0.9640275801, 0.0, 0.9640275801, 0.9993292997], * [-0.9950547537, -0.761594156, 0.0, 0.761594156, 0.9950547537], * [-0.9999997749, -0.9999877117, 0.0, 0.9999877117, 0.9999997749]] * ]] */ void zdnn_tanh_balanced_nhwc_2() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 1, 3, 5}; // Will be same for in and out dim. float input_values[] = {-4, -2, 0, 2, 4, -3, -1, 0, 1, 3, -8, -6, 0, 6, 8}; float expected_values[] = { -0.9993292997, -0.9640275801, 0.0, 0.9640275801, 0.9993292997, -0.9950547537, -0.761594156, 0.0, 0.761594156, 0.9950547537, -0.9999997749, -0.9999877117, 0.0, 0.9999877117, 0.9999997749, }; zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- TanH Basic Layout: ZDNN_3D ------------------------------------------------------------------------------- */ /** * zdnn_tanh_basic_3d * * Simple test to demonstrate tanh * * Input values as NWC sized (1,3,1): * [[ * [[1], [2], [3]], * [[4], [5], [6]], * [[7], [8], [9]] * ]] * * Expected Output values as NWC sized (1,3,1): * [[ * [[0.761594156], [0.9640275801], [0.9950547537]], * [[0.9993292997], [0.9999092043], [0.9999877117]], * [[0.9999983369], [0.9999997749], [0.9999999695] * ]] */ void zdnn_tanh_basic_3d_2() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {1, 3, 1}; // Will be same for in and out dim. float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; float expected_values[] = { 0.761594156, 0.9640275801, 0.9950547537, 0.9993292997, 0.9999092043, 0.9999877117, 0.9999983369, 0.9999997749, 0.9999999695, }; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_zeros_3d * * Zero test to demonstrate tanh * * Input values as NWC sized (1,3,3): * [[ * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]] * ]] * * Expected Output values as NWC sized (1,3,3): * [[ * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]], * [[0,0,0], [0,0,0], [0,0,0]] * ]] */ void zdnn_tanh_zeros_3d_2() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {1, 3, 3}; // Will be same for in and out dim. float input_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; float expected_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_negative_3d * * Negative test to demonstrate tanh * * Input values as NWC sized (1,3,3): * [[ * [[-1.0], [-2.1], [-3.2]], * [[-4.3], [-5.4], [-6.5]], * [[-7.6], [-8.7], [-9.8]] * ]] * * Expected Output values as NWC sized (1,3,3): * [[ * [[-0.761594156], [-0.9704519366], [-0.9966823978]], * [[-0.9996318562], [-0.9999592018], [-0.9999954794]], * [[-0.9999994991], [-0.9999999445], [-0.9999999939]] * ]] */ void zdnn_tanh_negative_3d_2() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {1, 3, 3}; // Will be same for in and out dim. float input_values[] = {-1.0, -2.1, -3.2, -4.3, -5.4, -6.5, -7.6, -8.7, -9.8}; float expected_values[] = { -0.761594156, -0.9704519366, -0.9966823978, -0.9996318562, -0.9999592018, -0.9999954794, -0.9999994991, -0.9999999445, -0.9999999939, }; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_positive_3d * * Positive test to demonstrate tanh * * * * Input values as NWC sized (8, 1, 1) * [[ * [[1.0]], * [[2.1]], * [[3.2]], * [[4.3]], * [[5.4]], * [[6.5]], * [[7.6]], * [[8.7]] * ]] * * Expected Output values as NWC sized (8, 1, 1): * [[ * [[0.761594156]], * [[0.9704519366]], * [[0.9966823978]], * [[0.9996318562]], * [[0.9999592018]], * [[0.9999954794]], * [[0.9999994991]], * [[0.9999999445]] * ]] */ void zdnn_tanh_positive_3d_2() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {8, 1, 1}; // Will be same for in and out dim. float input_values[] = {1.0, 2.1, 3.2, 4.3, 5.4, 6.5, 7.6, 8.7}; float expected_values[] = {0.761594156, 0.9704519366, 0.9966823978, 0.9996318562, 0.9999592018, 0.9999954794, 0.9999994991, 0.9999999445}; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_balanced_3d * * Balanced (pos and neg inputs) test to demonstrate tanh * * Input values as NWC sized (1, 3, 5) * [[ * [[-4, -2, 0, 2, 4], [-3, -1, 0, 1, 3], [-8, -6, 0, 6, 8]] * ]] * * Expected Output values as NWC sized (1 3, 5): * [[ * [[ -0.9993292997, -0.9640275801, 0.0, 0.9640275801, 0.9993292997], * [-0.9950547537, -0.761594156, 0.0, 0.761594156, 0.9950547537], * [-0.9999997749, -0.9999877117, 0.0, 0.9999877117, 0.9999997749]] * ]] * */ void zdnn_tanh_balanced_3d_2() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {1, 3, 5}; // Will be same for in and out dim. float input_values[] = {-4, -2, 0, 2, 4, -3, -1, 0, 1, 3, -8, -6, 0, 6, 8}; float expected_values[] = { -0.9993292997, -0.9640275801, 0.0, 0.9640275801, 0.9993292997, -0.9950547537, -0.761594156, 0.0, 0.761594156, 0.9950547537, -0.9999997749, -0.9999877117, 0.0, 0.9999877117, 0.9999997749, }; zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- TANH Large Layout: NCHW ------------------------------------------------------------------------------- */ /** * zdnn_tanh_basic_nhwc_large * * - ZDNN_3D * Simple test of positive input. * * Generate a test that is of size 40x30x15x1 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 40x30x15x1. */ void zdnn_tanh_basic_nhwc_large() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 15, 30, 43}; // Will be same for in and out dim. int num_io_buffer_values = shape[3] * shape[2] * shape[1] * shape[0]; float input_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_tanh(input_values, expected_values, num_io_buffer_values); zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_zeros_nhwc_large * * Simple test of all zero input. * * Generate a test that is of size 80x40x20x1 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 80x40x20x1 */ void zdnn_tanh_zeros_nhwc_large() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 20, 40, 80}; // Will be same for in and out dim. int num_io_buffer_values = shape[3] * shape[2] * shape[1] * shape[0]; float input_values[num_io_buffer_values]; fill_all_with_zero_float_array(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_tanh(input_values, expected_values, num_io_buffer_values); zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_negative_nhwc_large * * Simple test of all negative input values. * * Generate a test that is of size 80x23x10x1 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 80x23x10x1 */ void zdnn_tanh_negative_nhwc_large() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 10, 28, 83}; // Will be same for in and out dim. int num_io_buffer_values = shape[3] * shape[2] * shape[1] * shape[0]; float input_values[num_io_buffer_values]; gen_random_float_array_neg(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_tanh(input_values, expected_values, num_io_buffer_values); zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_balanced_nhwc_large * * Simple test of half negative and positive inputs. * * Generate a test that is of size 56x12x10x1 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 56x12x10x1 */ void zdnn_tanh_balanced_nhwc_large() { // Initialize the dimensions for our input tensor ZDNN_NHWC uint32_t shape[] = {1, 10, 12, 56}; // Will be same for in and out dim. int num_io_buffer_values = shape[3] * shape[2] * shape[1] * shape[0]; float input_values[num_io_buffer_values]; gen_random_float_array_pos_neg(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_tanh(input_values, expected_values, num_io_buffer_values); zdnn_tanh_test(shape, ZDNN_NHWC, input_values, ZDNN_OK, expected_values); } /* ------------------------------------------------------------------------------- TANH Large Layout: ZDNN_3D ------------------------------------------------------------------------------- */ /** * zdnn_tanh_basic_3d_large * * Simple test of positive input. * * Generate a test that is of size 10x10x10. * and use automatic float generator to create * input values. * * Output will contain tensor of size size 10x10x10. */ void zdnn_tanh_basic_3d_large() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {10, 10, 10}; // Will be same for in and out dim. int num_io_buffer_values = shape[2] * shape[1] * shape[0]; float input_values[num_io_buffer_values]; gen_random_float_array(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_tanh(input_values, expected_values, num_io_buffer_values); zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_zeros_3d_large * * Simple test of all zero input. * * Generate a test that is of size 15x5x3 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 15x5x3 */ void zdnn_tanh_zeros_3d_large() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {3, 5, 13}; // Will be same for in and out dim. int num_io_buffer_values = shape[2] * shape[1] * shape[0]; float input_values[num_io_buffer_values]; fill_all_with_zero_float_array(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_tanh(input_values, expected_values, num_io_buffer_values); zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_negative_3d_large * * Simple test of all negative input values. * * Generate a test that is of size 20x15x10 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 20x15x10 */ void zdnn_tanh_negative_3d_large() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {20, 15, 10}; // Will be same for in and out dim. int num_io_buffer_values = shape[2] * shape[1] * shape[0]; float input_values[num_io_buffer_values]; gen_random_float_array_neg(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_tanh(input_values, expected_values, num_io_buffer_values); zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } /** * zdnn_tanh_balanced_3d_large * * Simple test of half negative and positive inputs. * * Generate a test that is of size 30x3x3 * and use automatic float generator to create * input values. * * Output will contain tensor of size size 30x3x3 */ void zdnn_tanh_balanced_3d_large() { // Initialize the dimensions for our input tensor ZDNN_3D uint32_t shape[] = {3, 3, 30}; // Will be same for in and out dim. int num_io_buffer_values = shape[2] * shape[1] * shape[0]; float input_values[num_io_buffer_values]; gen_random_float_array_neg(num_io_buffer_values, input_values); float expected_values[num_io_buffer_values]; act_tanh(input_values, expected_values, num_io_buffer_values); zdnn_tanh_test(shape, ZDNN_3D, input_values, ZDNN_OK, expected_values); } int main() { UNITY_BEGIN(); RUN_TEST_ALL_DATATYPES(zdnn_tanh_basic_nhwc_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_zeros_nhwc_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_negative_nhwc_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_positive_nhwc_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_balanced_nhwc_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_basic_3d_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_zeros_3d_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_negative_3d_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_positive_3d_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_balanced_3d_1); RUN_TEST_ALL_DATATYPES(zdnn_tanh_basic_nhwc_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_zeros_nhwc_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_negative_nhwc_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_positive_nhwc_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_balanced_nhwc_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_basic_nhwc_large); RUN_TEST_ALL_DATATYPES(zdnn_tanh_zeros_nhwc_large); RUN_TEST_ALL_DATATYPES(zdnn_tanh_negative_nhwc_large); RUN_TEST_ALL_DATATYPES(zdnn_tanh_balanced_nhwc_large); RUN_TEST_ALL_DATATYPES(zdnn_tanh_basic_3d_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_zeros_3d_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_negative_3d_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_positive_3d_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_balanced_3d_2); RUN_TEST_ALL_DATATYPES(zdnn_tanh_basic_3d_large); RUN_TEST_ALL_DATATYPES(zdnn_tanh_zeros_3d_large); RUN_TEST_ALL_DATATYPES(zdnn_tanh_negative_3d_large); RUN_TEST_ALL_DATATYPES(zdnn_tanh_balanced_3d_large); return UNITY_END(); } ����������������zDNN-1.0.1/tests/testsupport.c����������������������������������������������������������������������0000664�0000000�0000000�00000122011�14364043643�0016250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Allows struct timeval to work on z/OS. Must be before <sys/time.h> include #ifdef __MVS__ #define _XOPEN_SOURCE_EXTENDED 1 #undef _ALL_SOURCE #endif #include "testsupport.h" #include "zdnn.h" #include "zdnn_private.h" #include <assert.h> #include <float.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/time.h> #include <time.h> #include <unistd.h> char error_message[ERROR_MESSAGE_STR_LENGTH]; float ZERO_ARRAY[1] = {0}; // Custom FP tolerance for tests to set and use, if needed fp_tolerance tol_bfloat = {0, 0}, tol_fp16 = {0, 0}, tol_fp32 = {0, 0}; zdnn_concat_info prev_layers[NUM_PREV_LAYERS] = {PREV_LAYER_UNI, PREV_LAYER_BIDIR}; zdnn_concat_info biases_usages[NUM_BIASES_USAGES] = {USAGE_BIASES, USAGE_HIDDEN_BIASES}; zdnn_concat_info no_vconcat_infos[NUM_NO_VCONCAT_INFOS] = { PREV_LAYER_UNI | USAGE_HIDDEN_WEIGHTS, PREV_LAYER_BIDIR | USAGE_HIDDEN_WEIGHTS, PREV_LAYER_UNI | USAGE_WEIGHTS, }; // Generate size_t offset array based on dimensions of ztensor. // // NOTE: when transformed dim1 is > 64, dim3 can not be > 1 void quick_generate_offsets(zdnn_ztensor *ztensor, size_t *offsets) { uint64_t total_elements; // fail the testcase right now if dim1 > 64 && dim3 > 1 // the e1_offset_template[i] = <...> loop doesn't handle that case TEST_ASSERT_MESSAGE_FORMATTED(!(ztensor->transformed_desc->dim3 > 1 && ztensor->transformed_desc->dim1 > 64), "incorrect quick_generate_offsets() usage: " "dim3 (%u) > 1 and dim1 (%u) > 64", ztensor->transformed_desc->dim3, ztensor->transformed_desc->dim1); if ((ztensor->transformed_desc->layout == ZDNN_ZRH) || (ztensor->transformed_desc->layout == ZDNN_FICO) || (ztensor->transformed_desc->layout == ZDNN_BIDIR_ZRH) || (ztensor->transformed_desc->layout == ZDNN_BIDIR_FICO)) { total_elements = get_num_elements(ztensor, ELEMENTS_PRE_ALL_GATES); } else { total_elements = get_num_elements(ztensor, ELEMENTS_PRE); } // Concatenated trfmd->dim1/dim2 includes padding so get the pre-padded ones. // Non-concatenated this will be equal to pre-trfmd's. uint32_t unpadded_dim1 = ztensor->pre_transformed_desc->dim1; uint32_t unpadded_dim2; // Offset template for e1 elements. These offsets will be added to the e1 loop // when determining correct offsets for test cases. size_t e1_offset_template[unpadded_dim1]; if (ztensor->transformed_desc->layout != ZDNN_BIDIR_FICO && ztensor->transformed_desc->layout != ZDNN_BIDIR_ZRH) { // transformed_desc->dim2 has the correct value we need unpadded_dim2 = ztensor->transformed_desc->dim2; for (uint32_t i = 0; i < unpadded_dim1; i++) { // build an offset template for the unpadded_dim1 number of elements. all // eventual offsets are going to follow that pattern e1_offset_template[i] = ((i / AIU_2BYTE_CELLS_PER_STICK) * CEIL(unpadded_dim2, AIU_STICKS_PER_PAGE) * AIU_PAGESIZE_IN_BYTES) + (i % AIU_2BYTE_CELLS_PER_STICK) * get_data_type_size(ZDNN_DLFLOAT16); LOG_TRACE("e1_offset_template[%d] = %d", i, e1_offset_template[i]); } uint64_t offset_i = 0; size_t e1_offset_start = 0; // Generate an offset for each element. Note: For concatenated ztensors, // padding elements will not be included in the offsets. while (unpadded_dim1 && offset_i < total_elements) { // Add relative e1 template to current stick start to get target offset. for (uint32_t dim1_i = 0; dim1_i < unpadded_dim1; dim1_i++) { offsets[offset_i] = e1_offset_start + e1_offset_template[dim1_i]; LOG_TRACE("offsets[%d] = %+08x", offset_i, offsets[offset_i]); offset_i++; } // Jump e1_offset_start to the start of the next unused page as soon as // all dim1 elements for each dim2 are processed if (offset_i % (unpadded_dim2 * unpadded_dim1) == 0) { // We already incremented offset_i so use previous offset_i to determine // current page number. uint32_t curr_page_num = offsets[offset_i - 1] / AIU_PAGESIZE_IN_BYTES; // Reset the e1 offset start to start of next page. e1_offset_start = (curr_page_num + 1) * AIU_PAGESIZE_IN_BYTES; LOG_TRACE("Jumped to start of next page location = %+08x", e1_offset_start); } else { // The e1 templates can skip over whole sticks if the number of elements // is larger than a single stick. Once the current dim1 row is fully // processed, reset e1_offset_start to jump back to the start of the // first empty stick. e1_offset_start += AIU_2BYTE_CELLS_PER_STICK * AIU_2BYTE_CELL_SIZE; LOG_TRACE("Jumped to start of first empty stick = %+08x", e1_offset_start); } } } else { // transformed_desc->dim2 is vertically concatenated, so instead grab the // actual dim2 from pre_transformed_desc unpadded_dim2 = ztensor->pre_transformed_desc->dim2; // number of pages needed to store a single c-stick (max: // AIU_2BYTE_CELLS_PER_STICK) worth of elements uint32_t num_pages_vertical = PADDED(unpadded_dim2 / 2) / AIU_STICKS_PER_PAGE * 2; for (uint32_t i = 0; i < unpadded_dim1; i++) { e1_offset_template[i] = ((i / AIU_2BYTE_CELLS_PER_STICK) * num_pages_vertical * AIU_PAGESIZE_IN_BYTES) + (i % AIU_2BYTE_CELLS_PER_STICK) * get_data_type_size(ZDNN_DLFLOAT16); LOG_TRACE("e1_offset_template[%d] = %d", i, e1_offset_template[i]); } uint64_t offset_i = 0; size_t e1_offset_start = 0; size_t e1_offset_start_slice = 0; while (unpadded_dim1 && offset_i < total_elements) { // build an offset template like the other case for (uint32_t dim1_i = 0; dim1_i < unpadded_dim1; dim1_i++) { offsets[offset_i] = e1_offset_start + e1_offset_template[dim1_i]; LOG_TRACE("offsets[%d] = %+08x", offset_i, offsets[offset_i]); offset_i++; } uint32_t curr_page_num = offsets[offset_i - 1] / AIU_PAGESIZE_IN_BYTES; if (offset_i % (unpadded_dim2 * unpadded_dim1) == 0) { // when we're done with this slice, reset the e1 offset start. the new // page number is always in multiples of 2 due to vertical concatenation e1_offset_start = CEIL(curr_page_num + 1, 2) * 2 * AIU_PAGESIZE_IN_BYTES; // save the offset start of this new slice to jump back to later e1_offset_start_slice = e1_offset_start; LOG_TRACE("Jumped to start of new page location = %+08x", e1_offset_start); } else if (offset_i % (unpadded_dim2 / 2 * unpadded_dim1) == 0) { // when we're done with 1st half of dim2, reset e1_offset_start to // beginning of this slice + half num_pages_vertical worth of bytes e1_offset_start = e1_offset_start_slice + num_pages_vertical / 2 * AIU_PAGESIZE_IN_BYTES; LOG_TRACE("Jumped back to start of 2nd half = %+08x", e1_offset_start); } else { // go to the next c-stick e1_offset_start += AIU_2BYTE_CELLS_PER_STICK * AIU_2BYTE_CELL_SIZE; LOG_TRACE("Jumped to start of first empty stick = %+08x", e1_offset_start); } } } } // Get integer values from a txt file and put them in the size_t array. // used by the stickify/unstickify test routines. Returns number of values // read. uint64_t get_offsets_from_file(const char *file_name, size_t *array) { if (file_name == NULL) { TEST_FAIL_MESSAGE("file_name required for get_offsets_from_file"); } FILE *file = fopen(file_name, "r"); uint64_t i = 0; if (file) { while (!feof(file)) { // Read integers from file, stopping at the first non-integer // (ie final newline) if (fscanf(file, "%" PRIu64 "", &array[i]) != 1) { break; } i++; } fclose(file); } return i; } size_t *alloc_offsets(zdnn_ztensor *ztensor, offset_mode mode, const char *path) { if (path != NULL && mode != FILE_OFFSETS) { TEST_FAIL_MESSAGE("path only valid for file mode"); } uint64_t total_elements; if ((ztensor->transformed_desc->layout == ZDNN_ZRH) || (ztensor->transformed_desc->layout == ZDNN_FICO) || (ztensor->transformed_desc->layout == ZDNN_BIDIR_ZRH) || (ztensor->transformed_desc->layout == ZDNN_BIDIR_FICO)) { total_elements = get_num_elements(ztensor, ELEMENTS_PRE_ALL_GATES); } else { total_elements = get_num_elements(ztensor, ELEMENTS_PRE); } LOG_TRACE("ztensor->transformed_desc->layout = %s, total_elements = %ld", get_data_layout_str(ztensor->transformed_desc->layout), total_elements); size_t *offsets = malloc(total_elements * sizeof(size_t)); switch (mode) { case QUICK_OFFSETS: { quick_generate_offsets(ztensor, offsets); break; } case FILE_OFFSETS: { uint64_t num_offsets = get_offsets_from_file(path, offsets); TEST_ASSERT_MESSAGE_FORMATTED( get_offsets_from_file(path, offsets) == total_elements, "for %" PRIu64 " elements get_offsets_from_file() on file \"%s\" returned %" PRIu64 " offsets", total_elements, path, num_offsets); break; } default: { TEST_FAIL_MESSAGE_FORMATTED("unknown mode: %d", mode); break; } } return offsets; } size_t *alloc_rnn_output_offsets(const zdnn_ztensor *ztensor) { // basically the result is like (dim4 * dim3) pieces of ZDNN_2D (dim2, dim1) // offsets stitched together, and everytime we replicate a piece we add some // offset to it zdnn_tensor_desc tmp_p_desc, tmp_t_desc; zdnn_ztensor tmp_ztensor; // create a ZDNN_2D (dim2, dim1) tensor and get the offsets of that via // alloc_offsets() zdnn_init_pre_transformed_desc(ZDNN_2D, test_datatype, &tmp_p_desc, ztensor->pre_transformed_desc->dim2, ztensor->pre_transformed_desc->dim1); zdnn_generate_transformed_desc(&tmp_p_desc, &tmp_t_desc); zdnn_status status = zdnn_init_ztensor_with_malloc(&tmp_p_desc, &tmp_t_desc, &tmp_ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc() failed status = %08x", status); size_t *piece_offsets = alloc_offsets(&tmp_ztensor, QUICK_OFFSETS, NULL); // each replication is seperated by this many bytes uint64_t piece_size = zdnn_getsize_ztensor(&tmp_t_desc); size_t *offsets = malloc(get_num_elements(ztensor, ELEMENTS_PRE_SINGLE_GATE) * sizeof(size_t)); // replicate the offsets dim4*dim3 times uint64_t c = 0; for (uint32_t i = 0; i < ztensor->pre_transformed_desc->dim4 * ztensor->pre_transformed_desc->dim3; i++) { for (uint32_t j = 0; j < ztensor->pre_transformed_desc->dim2 * ztensor->pre_transformed_desc->dim1; j++) { offsets[c] = piece_size * i + piece_offsets[j]; c++; } } return offsets; } /// Creates a data buffer with the provided float values converted to the /// specified type /// /// \note This method does not check that the size of values matches expected /// number of elements. /// /// Example usage: /// Setup input tensor /// \code /// void *data = alloc_and_convert_float_values(num_values, type, values); /// \endcode /// /// \param[in] type data type to convert the values into /// \param[in] num_values number of values in the float array /// \param[in] repeat_first_value if true, data will be poplulated with /// values[0] /// \param[in] values float array of values to convert and store in /// data /// /// \return a pointer with alloced memory containing the converted values /// void *alloc_and_convert_float_values(zdnn_data_types type, uint64_t num_values, bool repeat_first_value, float *values) { // Malloc the data buffer size_t data_size = num_values * get_data_type_size(type); void *data = malloc(data_size); memset(data, 0, data_size); // Convert values into desired type and store in data buffer for (uint64_t i = 0; i < num_values; i++) { float value; if (repeat_first_value) { value = values[0]; } else { value = values[i]; } switch (type) { case BFLOAT: ((uint16_t *)data)[i] = cnvt_1_fp32_to_bfloat(value); break; case FP16: ((uint16_t *)data)[i] = cnvt_1_fp32_to_fp16(value); break; case FP32: ((float *)data)[i] = value; break; default: // NOTE: Along with undefined types, DLFLOAT types will also come down // this path. zdnn_transform_ztensor() would fail with them as // DLFLOATs are a stickified type and transform() expects unstickified // data. TEST_FAIL_MESSAGE_FORMATTED("unsupported type: %d", type); } } return data; } /// Creates a ztensor with the provided values. Values are converted to the /// specified type. The resulting ztensor is transformed and ready for use in /// zDNN operations. /// /// \note This method does not check that the size of values matches expected /// number of elements. /// /// Example usage: /// Setup input tensor /// \code /// ztensor *zt = alloc_ztensor_with_values(shape, pre_tfrmd_layout, /// type, NO_CONCAT, false, values); /// \endcode /// Setup Output tensor /// \code /// ztensor *zt = alloc_ztensor_with_values(shape, pre_tfrmd_layout, /// type, NO_CONCAT, true, /// ZERO_ARRAY); /// \endcode /// /// \param[in] shape array of dimensions /// \param[in] pre_tfrmd_layout pre-transformed data layout /// \param[in] type data type /// \param[in] zdnn_concat_info /// indicates the type of concatenation to use /// This indirectly sets the transformed ztensor layout /// and the number of values arrays to expect. /// \param[in] repeat_first_value if true, ztensor will be poplulated with /// values[0] /// \param[in] ... float array(s) to tensor data or gates data. /// 1 array for NO_CONCAT, 3 arrays for GRU, 4 arrays for LSTM /// /// \return zdnn_ztensor* Pointer to a malloc'd ztensor with transformed data /// zdnn_ztensor *alloc_ztensor_with_values(uint32_t *shape, zdnn_data_layouts pre_tfrmd_layout, zdnn_data_types type, zdnn_concat_info info, int repeat_first_value, ...) { zdnn_status status = GENERAL_TESTCASE_FAILURE; // Create the pretransformed description zdnn_tensor_desc *pre_tfrmd_desc = (zdnn_tensor_desc *)malloc(sizeof(zdnn_tensor_desc)); switch (pre_tfrmd_layout) { case (ZDNN_1D): zdnn_init_pre_transformed_desc(pre_tfrmd_layout, type, pre_tfrmd_desc, shape[0]); break; case (ZDNN_2D): case (ZDNN_2DS): zdnn_init_pre_transformed_desc(pre_tfrmd_layout, type, pre_tfrmd_desc, shape[0], shape[1]); break; case (ZDNN_3D): case (ZDNN_3DS): zdnn_init_pre_transformed_desc(pre_tfrmd_layout, type, pre_tfrmd_desc, shape[0], shape[1], shape[2]); break; case (ZDNN_4D): case (ZDNN_4DS): case (ZDNN_NHWC): case (ZDNN_NCHW): case (ZDNN_HWCK): zdnn_init_pre_transformed_desc(pre_tfrmd_layout, type, pre_tfrmd_desc, shape[0], shape[1], shape[2], shape[3]); break; default: TEST_FAIL_MESSAGE_FORMATTED( "I'm dreadfully sorry but I don't seem to know how to deal with a %s " "pre_tfrmd_layout. Could you teach me?", get_data_layout_str(pre_tfrmd_layout)); break; } // Create the transformed description zdnn_tensor_desc *tfrmd_desc = (zdnn_tensor_desc *)malloc(sizeof(zdnn_tensor_desc)); if (info == NO_CONCAT) { status = zdnn_generate_transformed_desc(pre_tfrmd_desc, tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_generate_transformed_desc failed (status = %08x)", status); } else { status = zdnn_generate_transformed_desc_concatenated(pre_tfrmd_desc, info, tfrmd_desc); TEST_ASSERT_MESSAGE_FORMATTED(status == ZDNN_OK, "zdnn_generate_transformed_desc_concatenated " "with info %08x failed (status = %08x)", info, status); } // Create the ztensor with malloc'd buffer pointer zdnn_ztensor *ztensor = (zdnn_ztensor *)malloc(sizeof(zdnn_ztensor)); status = zdnn_init_ztensor_with_malloc(pre_tfrmd_desc, tfrmd_desc, ztensor); TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_init_ztensor_with_malloc failed (status = %08x)", status); // Prepare to iterate over the passed in values arrays va_list values_list; va_start(values_list, repeat_first_value); uint64_t num_elements = get_num_elements(ztensor, ELEMENTS_PRE_SINGLE_GATE); if (pre_tfrmd_layout == ZDNN_4DS) { // For testing outputs, we want to be able initialize rnn output ztensors to // zeros but we don't need to support setting arbitrary values memset(ztensor->buffer, 0, ztensor->buffer_size); } else { uint32_t num_things; // Find out how many things to stickify if (CONCAT_RNN_TYPE(info) == RNN_TYPE_LSTM) { num_things = get_func_code_num_gates(NNPA_LSTMACT); } else if (CONCAT_RNN_TYPE(info) == RNN_TYPE_GRU) { num_things = get_func_code_num_gates(NNPA_GRUACT); } else { num_things = 1; // the NO_CONCAT case, so we have 1 thing } void *values_data[num_things]; // Convert that many things for (uint32_t i = 0; i < num_things; i++) { values_data[i] = alloc_and_convert_float_values( type, num_elements, repeat_first_value, va_arg(values_list, float *)); } // Stickify ztensor using data that we type converted above if (CONCAT_RNN_TYPE(info) == RNN_TYPE_LSTM) { status = zdnn_transform_ztensor(ztensor, values_data[0], values_data[1], values_data[2], values_data[3]); } else if (CONCAT_RNN_TYPE(info) == RNN_TYPE_GRU) { status = zdnn_transform_ztensor(ztensor, values_data[0], values_data[1], values_data[2]); } else { status = zdnn_transform_ztensor(ztensor, values_data[0]); } TEST_ASSERT_MESSAGE_FORMATTED( status == ZDNN_OK, "zdnn_transform_ztensor failed with status %08x \"%s\"", status, zdnn_get_status_message(status)); for (uint32_t i = 0; i < num_things; i++) { free(values_data[i]); } } va_end(values_list); return ztensor; } // ----------------------------------------------------------------------------- // ULP-based Floating Point Comparsino Functions // ----------------------------------------------------------------------------- // used to get around "breaking strict-aliasing rules" typedef union float_int_u { // cppcheck-suppress unusedStructMember float f; int i; } float_int_u; int ulps_diff_float(float a, float b) { float_int_u au = {a}; float_int_u bu = {b}; // Make au.i lexicographically ordered as a twos-complement int if (au.i < 0) au.i = 0x80000000 - au.i; // Make bu.i lexicographically ordered as a twos-complement int if (bu.i < 0) bu.i = 0x80000000 - bu.i; return abs(au.i - bu.i); } int ulps_diff_16(uint16_t a, uint16_t b) { int16_t a_int = *(int16_t *)&a; int16_t b_int = *(int16_t *)&b; // Make a_int lexicographically ordered as a twos-complement int if (a_int < 0) a_int = 0x8000 - a_int; // Make b_int lexicographically ordered as a twos-complement int if (b_int < 0) b_int = 0x8000 - b_int; return abs(a_int - b_int); } // ----------------------------------------------------------------------------- // Floating Point Verify Functions // // - basic version (uses default fp_tolerance defined in testsupport.h) // - advanced version, suppply custom fp_tolerance // // Use ULPs comparsion first, then epsilon as fallback // ----------------------------------------------------------------------------- // advanced versions bool almost_equal_bfloat_adv(uint16_t actual, uint16_t expected, fp_tolerance tol) { // try ulps verification first, so we don't need to convert things to float int ulps_diff = ulps_diff_16(actual, expected); if (ulps_diff > tol.ulps) { LOG_DEBUG("actual = %f, expected = %f: ulps diff = %d (max = %d)", cnvt_1_bfloat_to_fp32(actual), cnvt_1_bfloat_to_fp32(expected), ulps_diff, tol.ulps); // epsilon verification float diff = fabs(cnvt_1_bfloat_to_fp32(actual) - cnvt_1_bfloat_to_fp32(expected)); float max_diff = EPSILON_BFLOAT * tol.epsilon_mult; LOG_DEBUG(" diff = %f (max = %f)", diff, max_diff); return !(diff > max_diff); } return true; } bool almost_equal_fp16_adv(uint16_t actual, uint16_t expected, fp_tolerance tol) { // try ulps verification first, so we don't need to convert things to float int ulps_diff = ulps_diff_16(actual, expected); if (ulps_diff > tol.ulps) { LOG_DEBUG("actual = %f, expected = %f: ulps diff = %d (max = %d)", cnvt_1_fp16_to_fp32(actual), cnvt_1_fp16_to_fp32(expected), ulps_diff, tol.ulps); // epsilon verification float diff = fabs(cnvt_1_fp16_to_fp32(actual) - cnvt_1_fp16_to_fp32(expected)); float max_diff = EPSILON_FP16 * tol.epsilon_mult; LOG_DEBUG(" diff = %f (max = %f)", diff, max_diff); return !(diff > max_diff); } return true; } bool almost_equal_float_adv(float actual, float expected, fp_tolerance tol) { // ulps-based verification int ulps_diff = ulps_diff_float(actual, expected); if (ulps_diff > tol.ulps) { LOG_DEBUG("actual = %f, expected = %f: ulps diff = %d (max = %d)", actual, expected, ulps_diff, tol.ulps); // epsilon verification float diff = fabs(actual - expected); float max_diff = EPSILON_FLOAT * tol.epsilon_mult; LOG_DEBUG(" diff = %f (max = %f)", diff, max_diff); return !(diff > max_diff); } return true; } bool almost_equal_dlf16_adv(uint16_t actual, uint16_t expected, fp_tolerance tol) { // try ulps verification first, so we don't need to convert things to float int ulps_diff = ulps_diff_16(actual, expected); if (ulps_diff > tol.ulps) { LOG_DEBUG("actual = %f, expected = %f: ulps diff = %d (max = %d)", cnvt_1_dlf16_to_fp32(actual), cnvt_1_dlf16_to_fp32(expected), ulps_diff, tol.ulps); // epsilon verification float diff = fabs(cnvt_1_dlf16_to_fp32(actual) - cnvt_1_dlf16_to_fp32(expected)); float max_diff = EPSILON_DLFLOAT16 * tol.epsilon_mult; LOG_DEBUG(" diff = %f (max = %f)", diff, max_diff); return !(diff > max_diff); } return true; } // basic versions, use default fp_tolerance. bool almost_equal_bfloat(uint16_t actual, uint16_t expected) { fp_tolerance tol = {MAX_ULPS_BFLOAT, MAX_EPSILON_MULT_BFLOAT}; return almost_equal_bfloat_adv(actual, expected, tol); } bool almost_equal_fp16(uint16_t actual, uint16_t expected) { fp_tolerance tol = {MAX_ULPS_FP16, MAX_EPSILON_MULT_FP16}; return almost_equal_fp16_adv(actual, expected, tol); } bool almost_equal_float(float actual, float expected) { fp_tolerance tol = {MAX_ULPS_FLOAT, MAX_EPSILON_MULT_FLOAT}; return almost_equal_float_adv(actual, expected, tol); } bool almost_equal_dlf16(uint16_t actual, uint16_t expected) { fp_tolerance tol = {MAX_ULPS_DLFLOAT16, MAX_EPSILON_MULT_DLFLOAT16}; return almost_equal_dlf16_adv(actual, expected, tol); } /// Asserts each value in the stickified ztensor are within a specified /// tolerance from the given expected float values. /// /// \note This method does not check that the size of values array matches the /// number of elements. If there's not enough expected values, the test will /// likely fail when garbage data is pulled in as the expected value. /// /// Example usage: /// \code /// assert_ztensor_values_adv(&ztensor, false, values, true, tol); /// \endcode /// /// \param[in] ztensor pointer to zdnn_ztensor with actual values /// \param[in] repeat_first_expected_value if true, all ztensor values will be /// compared to values[0] /// \param[in] values array of expected values /// \param[in] tol floating point tolerance information /// /// \return None (assert fails if any actual value not within expected range) /// void assert_ztensor_values_adv(zdnn_ztensor *ztensor, bool repeat_first_expected_value, void *values, fp_tolerance tol) { zdnn_status status; zdnn_tensor_desc *pre_tfrmd_desc = ztensor->pre_transformed_desc; uint64_t num_elements = 0; switch (ztensor->transformed_desc->layout) { case ZDNN_1D: case ZDNN_2D: case ZDNN_2DS: case ZDNN_3D: case ZDNN_3DS: case ZDNN_4D: case ZDNN_4DS: case ZDNN_NHWC: num_elements = get_num_elements(ztensor, ELEMENTS_PRE); break; case ZDNN_FICO: case ZDNN_ZRH: TEST_FAIL_MESSAGE_FORMATTED( "does not support %s layout as we don't support unstickifying " "concatenated ztensors.", get_data_layout_str(ztensor->transformed_desc->layout)); break; default: TEST_FAIL_MESSAGE_FORMATTED( "I'm dreadfully sorry but I don't seem to know how to deal with a %s " "layout. Could you teach me?", get_data_layout_str(ztensor->transformed_desc->layout)); break; } // Malloc error_message as it will be large if num_elements is large. uint64_t big_error_message_size = (uint64_t)sizeof(char) * ERROR_MESSAGE_STR_LENGTH * num_elements; char *error_msg = malloc(big_error_message_size); void *actual_vals, *expected_vals; // Get unstickified data from ztensor to actual_vals[] actual_vals = malloc(num_elements * get_data_type_size(pre_tfrmd_desc->type)); status = zdnn_transform_origtensor(ztensor, actual_vals); snprintf(error_msg, big_error_message_size, "zdnn_transform_origtensor failed (status = %08x)", status); TEST_ASSERT_MESSAGE(status == ZDNN_OK, error_msg); // expected_vals[] will contains the expected values (values[]) but in the // same data type as actual_vals[], i.e., (pre_tfrmd_desc->type) expected_vals = malloc(num_elements * get_data_type_size(pre_tfrmd_desc->type)); // Instead of directly converting from C float to (pre_tfrmd_desc->type), we // convert it to DLFLOAT16 first then (pre_tfrmd_desc->type) in order to // simulate the precision loss the values have gone through. The same // process applies for FP32. for (uint64_t i = 0; i < num_elements; i++) { uint16_t tmp_dlf16; if (!repeat_first_expected_value) { tmp_dlf16 = cnvt_1_fp32_to_dlf16(((float *)values)[i]); } else { tmp_dlf16 = cnvt_1_fp32_to_dlf16(((float *)values)[0]); } switch (pre_tfrmd_desc->type) { case BFLOAT: ((uint16_t *)expected_vals)[i] = cnvt_1_fp32_to_bfloat(cnvt_1_dlf16_to_fp32(tmp_dlf16)); break; case FP16: ((uint16_t *)expected_vals)[i] = cnvt_1_fp32_to_fp16(cnvt_1_dlf16_to_fp32(tmp_dlf16)); break; case FP32: ((float *)expected_vals)[i] = cnvt_1_dlf16_to_fp32(tmp_dlf16); break; default: // NOTE: Along with undefined types, DLFLOAT types will also come down // this path. DLFLOATS are a stickified types which are not valid types // for the pre_tfrmd_desc (ie prestickifed description). snprintf(error_msg, big_error_message_size, "unsupported type: %d\n", pre_tfrmd_desc->type); TEST_FAIL_MESSAGE(error_msg); break; } } // Assert ztentor's values (converted back to floats) match does not exceed // max ULPs and epsilon bool all_pass = true; // Loop appends to error_msg so reset it first error_msg[0] = '\0'; char *error_fmt = "Element %" PRIu64 " == %f expecting %f"; char *error_fmt2 = " <==== FAILED (diff beyond ULPs %u, epsilon multiplier %u)"; // Compared the actual and expected values for (uint64_t i = 0; i < num_elements; i++) { bool is_almost_equal = false; switch (pre_tfrmd_desc->type) { case BFLOAT: { // Record all actual vs expected values (only printed if one fails) // For printf-ing error_msg we'll need to convert "actual" to float uint16_t actual = ((uint16_t *)actual_vals)[i]; uint16_t expected = ((uint16_t *)expected_vals)[i]; snprintf(error_msg + strlen(error_msg), big_error_message_size - strlen(error_msg), error_fmt, i, cnvt_1_bfloat_to_fp32(actual), cnvt_1_bfloat_to_fp32(expected)); LOG_DEBUG(error_fmt, i, cnvt_1_bfloat_to_fp32(actual), cnvt_1_bfloat_to_fp32(expected)); is_almost_equal = almost_equal_bfloat_adv(actual, expected, tol); break; } case FP16: { uint16_t actual = ((uint16_t *)actual_vals)[i]; uint16_t expected = ((uint16_t *)expected_vals)[i]; snprintf(error_msg + strlen(error_msg), big_error_message_size - strlen(error_msg), error_fmt, i, cnvt_1_fp16_to_fp32(actual), cnvt_1_fp16_to_fp32(expected)); LOG_DEBUG(error_fmt, i, cnvt_1_fp16_to_fp32(actual), cnvt_1_fp16_to_fp32(expected)); is_almost_equal = almost_equal_fp16_adv(actual, expected, tol); break; } case FP32: { float actual = ((float *)actual_vals)[i]; float expected = ((float *)expected_vals)[i]; snprintf(error_msg + strlen(error_msg), big_error_message_size - strlen(error_msg), error_fmt, i, actual, expected); LOG_DEBUG(error_fmt, i, actual, expected); is_almost_equal = almost_equal_float_adv(actual, expected, tol); break; } default: // would have died earlier break; } if (!is_almost_equal) { snprintf(error_msg + strlen(error_msg), big_error_message_size - strlen(error_msg), error_fmt2, tol.ulps, tol.epsilon_mult); all_pass = false; } snprintf(error_msg + strlen(error_msg), big_error_message_size - strlen(error_msg), "\n"); } // Assert that all passed and clean up temp data TEST_ASSERT_MESSAGE(all_pass, error_msg); free(expected_vals); free(actual_vals); free(error_msg); } void assert_ztensor_values(zdnn_ztensor *ztensor, bool repeat_first_expected_value, void *values) { fp_tolerance tol = {0, 0}; // zero tolerance ==> testcase will likely fail. switch (ztensor->pre_transformed_desc->type) { case BFLOAT: tol.ulps = MAX_ULPS_BFLOAT; tol.epsilon_mult = MAX_EPSILON_MULT_BFLOAT; break; case FP16: tol.ulps = MAX_ULPS_FP16; tol.epsilon_mult = MAX_EPSILON_MULT_FP16; break; case FP32: tol.ulps = MAX_ULPS_FLOAT; tol.epsilon_mult = MAX_EPSILON_MULT_FLOAT; break; default: // let assert_ztensor_values_adv() deal with it break; } assert_ztensor_values_adv(ztensor, repeat_first_expected_value, values, tol); } /// Free buffers, descriptions, and ztensors structs for all provided ztensors /// /// \param[in] num_of_ztensors number of ztensors pointers passed into this /// method /// \param[in] ... variable number of ztensor pointers /// /// \return None (assert fails if freeing any buffer fails /// void free_ztensor_buffers(uint32_t num_ztensors, ...) { zdnn_status status; // Create ztensor_list to handle the multple input ztensors passed in. va_list ztensor_list; va_start(ztensor_list, num_ztensors); // Free data buffer for each provided ztensor for (uint32_t i = 0; i < num_ztensors; i++) { zdnn_ztensor *ztensor = va_arg(ztensor_list, zdnn_ztensor *); if ((status = zdnn_free_ztensor_buffer(ztensor)) != ZDNN_OK) { free(ztensor->transformed_desc); free(ztensor->pre_transformed_desc); free(ztensor); TEST_FAIL_MESSAGE_FORMATTED( "zdnn_free_ztensor_buffer() failed on tensor %u with status %08x", i, status); } } va_end(ztensor_list); } /// Allocates a data buffer then fills it with random float values (between /// SMALLEST_RANDOM_FP to 1) /// /// \param[out] ztensor A zdnn tensor /// /// \return pointer to filled data buffer /// unsigned char *create_and_fill_random_fp_data(zdnn_ztensor *ztensor) { // The single concat looks at just the pre_tfrmd shape which matches tfrmd // size for everything but concat cases. For concat tests that use this, we // want the single concat size specifically because we generate the data for // each concat (RNN gate) separately. uint64_t num_elements = get_num_elements(ztensor, ELEMENTS_PRE_SINGLE_GATE); zdnn_data_types dtype = ztensor->pre_transformed_desc->type; void *data = malloc(num_elements * get_data_type_size(dtype)); struct timeval t1; gettimeofday(&t1, NULL); srand(t1.tv_usec * t1.tv_sec); for (int i = 0; i < num_elements; i++) { float filling = 0; // https://stackoverflow.com/questions/13408990/how-to-generate-random-float-number-in-c while (filling < SMALLEST_RANDOM_FP) { filling = (float)rand() / (float)(RAND_MAX); } switch (dtype) { case BFLOAT: ((uint16_t *)data)[i] = cnvt_1_fp32_to_bfloat(filling); break; case FP16: ((uint16_t *)data)[i] = cnvt_1_fp32_to_fp16(filling); break; case FP32: ((float *)data)[i] = filling; break; case ZDNN_DLFLOAT16: ((uint16_t *)data)[i] = cnvt_1_fp32_to_dlf16(filling); } } return data; } /** * Helper that generates random floats and populate the given array. This will * be used for populating tensor buffers in the end-to-end unit tests. * * https://stackoverflow.com/questions/13408990/how-to-generate-random-float-number-in-c */ void gen_random_float_array(int size, float arr[]) { struct timeval t1; gettimeofday(&t1, NULL); srand(t1.tv_usec * t1.tv_sec); // The raw output value will be [0, a]. To make sure we're always at least // SMALLEST_RANDOM_FP from zero, add it to the result. Also subtract it // from the max so when we add it to the result, we'll still be within max. float desired_max = LARGEST_RANDOM_FP - SMALLEST_RANDOM_FP; for (int i = 0; i < size; i++) { arr[i] = ((float)rand() / (float)(RAND_MAX)) * desired_max + SMALLEST_RANDOM_FP; } } /** * Helper that generates random negative floats and populate the given array. * This will be used for populating tensor buffers in the end-to-end unit * tests. */ void gen_random_float_array_neg(int size, float arr[]) { struct timeval t1; gettimeofday(&t1, NULL); srand(t1.tv_usec * t1.tv_sec); // The raw output value will be [0, a]. To make sure we're always at least // SMALLEST_RANDOM_FP from zero, add it to the result. Also subtract it // from the max so when we add it to the result, we'll still be within max. float desired_max = LARGEST_RANDOM_FP - SMALLEST_RANDOM_FP; for (int i = 0; i < size; i++) { arr[i] = -((float)rand() / (float)(RAND_MAX)) * desired_max + SMALLEST_RANDOM_FP; } } /** * Helper that generates random negative and positive float values for a given * size and for a given array, meant for populating tensor buffers in * end-to-end unit tests. * * Every other array index will be negative: * * Example: [-1, 2, -3, 4, -5, 6] */ void gen_random_float_array_pos_neg(int size, float arr[]) { struct timeval t1; gettimeofday(&t1, NULL); srand(t1.tv_usec * t1.tv_sec); float desired_max = LARGEST_RANDOM_FP - SMALLEST_RANDOM_FP; for (int i = 0; i < size; i++) { arr[i] = (((float)rand() / (float)(RAND_MAX)) * desired_max + SMALLEST_RANDOM_FP) * ((i % 2 == 0) ? 1 : -1); } } /** * Helper that generates 0 values for a given size * and for a given array, meant for populating tensor buffers * in end-to-end unit tests. */ void gen_float_array_zeros(int size, float arr[]) { for (int i = 0; i < size; i++) { arr[i] = 0; } } /** * Helper that generates an array copy for a given size and * for a given array, meant for populating tensor buffers in * end-to-end unit tests. */ void copy_to_array(int size, float input[], float output[]) { for (int i = 0; i < size; i++) { output[i] = input[i]; } } /** * Helper that generates an array with every other value equaling zero for a * given size and for a given array, meant for populating tensor buffers in * end-to-end unit tests. * * Every other array index will be negative: * * Example: * input: [1,2,3,4,5,6] * output: [0,2,0,4,0,6] */ void fill_everyother_with_zero_float_array(int size, float arr[]) { for (int i = 0; i < size; i++) { if (i % 2 != 0) { arr[i] = 0; } } } /** * Helper that generates an array with all values equaling zero for a * given size and for a given array, meant for populating tensor buffers in * end-to-end unit tests. */ void fill_all_with_zero_float_array(int size, float arr[]) { for (int i = 0; i < size; i++) { arr[i] = 0; } } int stdout_pipe[2]; int stderr_pipe[2]; int saved_stdout; int saved_stderr; void stdout_to_pipe() { // save stream for display later saved_stdout = dup(STDOUT_FILENO); fflush(stdout); // make a pipe if (pipe(stdout_pipe) != 0) { TEST_FAIL_MESSAGE("Can't open pipe()"); } // redirect to pipe dup2(stdout_pipe[1], STDOUT_FILENO); close(stdout_pipe[1]); return; } void stderr_to_pipe() { // save stream for display later saved_stderr = dup(STDERR_FILENO); fflush(stderr); // make a pipe if (pipe(stderr_pipe) != 0) { TEST_FAIL_MESSAGE("Can't open pipe()"); } // redirect to pipe dup2(stderr_pipe[1], STDERR_FILENO); close(stderr_pipe[1]); return; } void restore_stdout(char *buf, int buf_size) { // the read() below blocks if nothing to read, so printf something fprintf(stdout, " "); fflush(stdout); // read from pipe into buffer read(stdout_pipe[0], buf, buf_size); close(stdout_pipe[0]); // restore stream to display dup2(saved_stdout, STDOUT_FILENO); } void restore_stderr(char *buf, int buf_size) { // the read() below blocks if nothing to read, so printf something fprintf(stderr, "x"); fflush(stderr); // read from pipe into buffer read(stderr_pipe[0], buf, buf_size); close(stderr_pipe[0]); // restore stream to display dup2(saved_stderr, STDERR_FILENO); } /********************************************************** * Enhanced Unity Functions/Macros **********************************************************/ #define NUM_PRE_TFRMD_TYPES 3 zdnn_data_types pre_tfrmd_types[NUM_PRE_TFRMD_TYPES] = {FP16, FP32, BFLOAT}; #define NUM_TFRMD_TYPES 1 zdnn_data_types tfrmd_types[NUM_TFRMD_TYPES] = {ZDNN_DLFLOAT16}; // indicates which data-type UnityDefaultTestRunWith*DataType() is currently // testing zdnn_data_types test_datatype = 128; // set initial value to something invalid // Wrapper of Unity's UnityDefaultTestRun() that runs func() against all // input data-types. Uses CamelCase intentionally to align with Unity void UnityDefaultTestRunWithDataType(UnityTestFunction Func, const char *FuncName, const int FuncLineNum) { for (int i = 0; i < NUM_PRE_TFRMD_TYPES; i++) { test_datatype = pre_tfrmd_types[i]; // FuncNameWithDataType is FuncName + " (data-type)" for printing char FuncNameWithDataType[FUNCNAME_BANNER_LENGTH]; Unity.CurrentTestName = FuncNameWithDataType; snprintf(FuncNameWithDataType, FUNCNAME_BANNER_LENGTH, "%s (%s)", FuncName, get_data_type_str(pre_tfrmd_types[i])); UnityDefaultTestRun(Func, FuncNameWithDataType, FuncLineNum); } } // UnityDefaultTestRunWithDataType() but with transformed data-types void UnityDefaultTestRunWithTfrmdDataType(UnityTestFunction Func, const char *FuncName, const int FuncLineNum) { for (int i = 0; i < NUM_TFRMD_TYPES; i++) { test_datatype = tfrmd_types[i]; // FuncNameWithDataType is FuncName + " (data-type)" for printing char FuncNameWithDataType[FUNCNAME_BANNER_LENGTH]; Unity.CurrentTestName = FuncNameWithDataType; snprintf(FuncNameWithDataType, FUNCNAME_BANNER_LENGTH, "%s (%s)", FuncName, get_data_type_str(tfrmd_types[i])); UnityDefaultTestRun(Func, FuncNameWithDataType, FuncLineNum); } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/tests/testsupport.h����������������������������������������������������������������������0000664�0000000�0000000�00000024024�14364043643�0016262�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TESTS_TESTSUPPORT_H_ #define TESTS_TESTSUPPORT_H_ #include "convert.h" #include "unity.h" #include "zdnn.h" #include "zdnn_private.h" // NOTE: ZDNN_CONFIG_NO_NNPA is not defined until after "zdnn_private.h" #ifdef ZDNN_CONFIG_NO_NNPA // when ZDNN_CONFIG_NO_NNPA is set we might need the scaffolded conversion // routines #include "convert.h" #endif #include <float.h> #include <stddef.h> #define AIU_METHOD_STR_LENGTH 32 extern float ZERO_ARRAY[1]; #define NO_CONCAT 0xFFFFFFFF // "default" failure when non of the ZDNN_STATUS's si appropriate, // likely due to something's wrong with the testcase itself #define GENERAL_TESTCASE_FAILURE 0xDEADBEEF // Generate path string to a pregenerated offset file #define OFFSET_FILE(layout, d4, d3, d2, d1) \ "resources/offset_files/" #layout "_" #d4 "x" #d3 "x" #d2 "x" #d1 ".txt" typedef enum offset_mode { NO_OFFSETS, // Don't generate offsets. Not a valid mode. QUICK_OFFSETS, // Fast but not always correct. Best for small dims. // see https://jsw.ibm.com/browse/ZAI-206 for details. FILE_OFFSETS // Load pre-generated offsets (see stick_fe.py). } offset_mode; uint64_t get_offsets_from_file(const char *file_name, size_t *array); size_t *alloc_offsets(zdnn_ztensor *ztensor, offset_mode mode, const char *path); size_t *alloc_rnn_output_offsets(const zdnn_ztensor *ztensor); void *alloc_and_convert_float_values(zdnn_data_types type, uint64_t num_values, bool repeat_first_value, float *values); zdnn_ztensor *alloc_ztensor_with_values(uint32_t *shape, zdnn_data_layouts pre_tfrmd_layout, zdnn_data_types type, zdnn_concat_info info, int repeat_first_value, ...); void free_ztensor_buffers(uint32_t num_ztensors, ...); // Struct for floating point value tolerance information. typedef struct fp_tolerance { uint32_t ulps; // unit in the last place uint32_t epsilon_mult; // epsilon multiplier } fp_tolerance; extern fp_tolerance tol_bfloat, tol_fp16, tol_fp32; void assert_ztensor_values(zdnn_ztensor *ztensor, bool repeat_first_expected_value, void *values); void assert_ztensor_values_adv(zdnn_ztensor *ztensor, bool repeat_first_expected_value, void *values, fp_tolerance tol); unsigned char *create_and_fill_fp_data(zdnn_tensor_desc *desc); unsigned char *create_and_fill_random_fp_data(zdnn_ztensor *ztensor); void gen_random_float_array(int size, float arr[]); void gen_random_float_array_neg(int size, float arr[]); void gen_random_float_array_pos_neg(int size, float arr[]); void gen_float_array_zeros(int size, float arr[]); void copy_to_array(int size, float input[], float output[]); void fill_everyother_with_zero_float_array(int size, float arr[]); void fill_all_with_zero_float_array(int size, float arr[]); #define SEQUENTIAL_FILL_INTERVAL 1.0F #define SEQUENTIAL_FILL_MAX 1024.0F // sacrifice BFLOAT, 256 is too small // "OK" tolerance values. // // As everything gets converted to DLFLOAT16 and back, some data types will fare // better dealing with precision loss than others, thus the different values // among the data types. // // Some ops may need higher/lower tolerance than these defaults. #define MAX_ULPS_BFLOAT 8 #define MAX_ULPS_FP16 8 #define MAX_ULPS_FLOAT (16384 * 8) #define MAX_ULPS_DLFLOAT16 8 #define MAX_EPSILON_MULT_BFLOAT 8 #define MAX_EPSILON_MULT_FP16 8 #define MAX_EPSILON_MULT_FLOAT (5120 * 8) #define MAX_EPSILON_MULT_DLFLOAT16 8 // epsilon = 2 ^ (num_mantissa_bits - 1) #define EPSILON_BFLOAT 0.00390625F // 2 ^ -8 #define EPSILON_FP16 0.00048828125F // 2 ^ -11 #define EPSILON_FLOAT 0.000000059604644775390625F // 2 ^ -24, FLT_EPSILON #define EPSILON_DLFLOAT16 0.0009765625F // 2 ^ -10 bool almost_equal_bfloat_adv(uint16_t actual, uint16_t expected, fp_tolerance tol); bool almost_equal_fp16_adv(uint16_t actual, uint16_t expected, fp_tolerance tol); bool almost_equal_float_adv(float actual, float expected, fp_tolerance tol); bool almost_equal_dlf16_adv(uint16_t actual, uint16_t expected, fp_tolerance tol); bool almost_equal_bfloat(uint16_t actual, uint16_t expected); bool almost_equal_fp16(uint16_t actual, uint16_t expected); bool almost_equal_float(float actual, float expected); bool almost_equal_dlf16(uint16_t actual, uint16_t expected); // in some cases we can't use the single-precision float values as-is for // calculating expected results. these macros convert a given single-precision // value to its "representable-by-AIU" value w.r.t. its pre-transformed data // type #define CLEANSE_BFLOAT(x) \ cnvt_1_dlf16_to_fp32( \ cnvt_1_fp32_to_dlf16(cnvt_1_bfloat_to_fp32((cnvt_1_fp32_to_bfloat(x))))) #define CLEANSE_FP16(x) \ cnvt_1_dlf16_to_fp32( \ cnvt_1_fp32_to_dlf16(cnvt_1_fp16_to_fp32((cnvt_1_fp32_to_fp16(x))))) #define CLEANSE_FP32(x) cnvt_1_dlf16_to_fp32(cnvt_1_fp32_to_dlf16(x)) // Max/min absolute values for some of the test random float generators #define LARGEST_RANDOM_FP 5.0F #define SMALLEST_RANDOM_FP 0.00006F // ----------------------------------------------------------------------------- // Max values by type (to create NNPA overflow) // ----------------------------------------------------------------------------- #define MAX_FP32 FLT_MAX //#define MAX_FP32 3.4028234663852885981170418348452e+38 #define MAX_FP16 ((float)65504) // 2^15 * (1 + 1023/1024) #define MAX_BFLOAT FLT_MAX #define MAX_DLF16 ((float)8581545984) // 2^32 * (1 + 511/512) #if defined(ZDNN_CONFIG_SIMULATION) #define NUM_PRE_TFRMD_TYPES 1 #else #define NUM_PRE_TFRMD_TYPES 3 #endif #define NUM_TFRMD_TYPES 1 extern zdnn_data_types pre_tfrmd_types[NUM_PRE_TFRMD_TYPES]; extern zdnn_data_types tfrmd_types[NUM_TFRMD_TYPES]; #define NUM_PREV_LAYERS 2 #define NUM_BIASES_USAGES 2 #define NUM_NO_VCONCAT_INFOS 3 extern zdnn_concat_info prev_layers[NUM_PREV_LAYERS]; extern zdnn_concat_info biases_usages[NUM_BIASES_USAGES]; extern zdnn_concat_info no_vconcat_infos[NUM_NO_VCONCAT_INFOS]; void stdout_to_pipe(); void stderr_to_pipe(); void restore_stdout(char *buf, int buf_size); void restore_stderr(char *buf, int buf_size); /* The following defines a macro to verify the hardware environment for our * tests to successfully run in. Most tests require the proper HW environment * to succeed. Even some of the others, like "..._fail" tests, are looking for * a specific error, but can't rely on the root cause of that error without * the proper HW environment. In the event the proper HW environment is not * available, we will ignore or skip those tests. * * When an NNPA build occurs (ZDNN_CONFIG_NO_NNPA wasn't defined) we require * that NNPA hardware be available, otherwise we must skip tests. * * When we have a non-NNPA build, we require that NNPA hardware is not * available, otherwise we must skip tests. * * Simply invoke it in the Unity "setup" proc or within specific tests. */ #ifndef ZDNN_CONFIG_NO_NNPA #define VERIFY_HW_ENV \ if (!zdnn_is_nnpa_installed()) \ TEST_IGNORE_MESSAGE("NNPA build but NNPA hardware not available"); #else #define VERIFY_HW_ENV \ if (zdnn_is_nnpa_installed()) \ TEST_IGNORE_MESSAGE("Non-NNPA build but NNPA Scaffold is not setup"); #endif /********************************************************** * Enhanced Unity Functions/Macros **********************************************************/ // standard error message string buffer for all tests to send down to Unity #define ERROR_MESSAGE_STR_LENGTH 512 extern char error_message[ERROR_MESSAGE_STR_LENGTH]; #define TEST_FAIL_MESSAGE_FORMATTED(f, ...) \ snprintf(error_message, ERROR_MESSAGE_STR_LENGTH, (f), __VA_ARGS__); \ TEST_FAIL_MESSAGE(error_message); #define TEST_ASSERT_MESSAGE_FORMATTED(cond, f, ...) \ snprintf(error_message, ERROR_MESSAGE_STR_LENGTH, (f), __VA_ARGS__); \ TEST_ASSERT_MESSAGE((cond), error_message); #define FUNCNAME_BANNER_LENGTH 256 extern zdnn_data_types test_datatype; void UnityDefaultTestRunWithDataType(UnityTestFunction Func, const char *FuncName, const int FuncLineNum); void UnityDefaultTestRunWithTfrmdDataType(UnityTestFunction Func, const char *FuncName, const int FuncLineNum); // Macro to run test func() against all pre-transformed data-types #define RUN_TEST_ALL_DATATYPES(func) \ UnityDefaultTestRunWithDataType(func, #func, __LINE__); // Macro to run test func() against all transformed data-types #define RUN_TEST_ALL_TFRMD_DATATYPES(func) \ UnityDefaultTestRunWithTfrmdDataType(func, #func, __LINE__); #endif /* TESTS_TESTSUPPORT_H_ */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/������������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14364043643�0013302�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/Makefile����������������������������������������������������������������������������0000664�0000000�0000000�00000004171�14364043643�0014745�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. _dummy := $(shell mkdir -p obj) OBJDIR := obj include ../config.make INCDIR := $(CFLAGS_NOSEARCH) -I ../zdnn -I . _dummy2 := $(shell mkdir -p $(SODIR)) CFLAGS := $(INCDIR) $(CFLAGS) CXXFLAGS := $(INCDIR) $(CXXFLAGS) H_FILES := $(filter-out $(wildcard convert*.h), $(wildcard *.h)) INIT_SRCFILE := zdnn_init.c SRCFILES := $(filter-out $(INIT_SRCFILE), $(wildcard *.c) $(wildcard *.cpp)) # Add the configure generated header H_FILES += ../config.h OBJFILES := $(patsubst %.c,$(OBJDIR)/%.o,$(patsubst %.cpp,$(OBJDIR)/%.o,$(SRCFILES))) INIT_OBJFILE := $(patsubst %.c,$(OBJDIR)/%.o,$(INIT_SRCFILE)) all: $(SODIR)/$(LIBNAME).so $(SODIR)/$(LIBNAME_PRIVATE).so $(ZDNN_MAKE_TARGETS) $(INIT_OBJFILE): $(INIT_SRCFILE) $(CC) $(CFLAGS_INIT) $(CFLAGS_SHARED) -c $< -o $@ $(OBJDIR)/%.o: %.c $(CC) $(CFLAGS) $(CFLAGS_SHARED) -c $< -o $@ $(OBJDIR)/%.o: %.cpp $(CXX) $(CXXFLAGS) $(CFLAGS_SHARED) -c $< -o $@ include $(ZDNN_TMAKE_FILES) $(SODIR)/$(LIBNAME).so: $(INIT_OBJFILE) $(OBJFILES) $(H_FILES) $(LD) $(LDFLAGS_SHARED) -o $(SODIR)/$(LIBNAME).so $(INIT_OBJFILE) $(OBJFILES) .PHONY: clean clean: $(RM) $(OBJDIR)/*.o $(OBJDIR)/*.lst $(OBJDIR)/*.d *~ core $(SODIR)/* \ *.so* ../zdnn/zdnn_private.map \ zdnn.i zdnn.dynsyms symcheck .PHONY: install install: all install_shared $(ZDNN_INSTALL_TARGETS) .PHONY: install_shared install_shared: $(INSTALL) -d $(DESTDIR)$(libdir) $(INSTALL) -d $(DESTDIR)$(includedir) $(INSTALL) -t $(DESTDIR)$(libdir) $(SODIR)/$(LIBNAME).so $(INSTALL_DATA) -t $(DESTDIR)$(includedir) zdnn.h �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/aiu_lstm_gru.c����������������������������������������������������������������������0000664�0000000�0000000�00000107214�14364043643�0016145�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <stdlib.h> #include <string.h> // External users only need to specify between FWD, BWD, and BIDIR. However our // directional_rnn() needs more detail. FWD vs BWD controls the order the // timestep input is processed along with UNI vs BIDIR which affects how we move // over the hn_output. typedef enum rnn_internal_direction { UNI_FWD, UNI_BWD, BIDIR_FWD, BIDIR_BWD, } rnn_internal_direction; // Named indices for numbers passed between the internal methods typedef enum rnn_integer_indices { TS, BATCH, HID_SIZE, IN_PAD, GATES, SLICEABLE_INPUTS, NUM_INTEGER_INDICES // Not an index, used to set size of the array later. } rnn_integer_indices; // Must match order in sliceable_inputs[]! // Named indices for sliceable ztensors passed in by the user. typedef enum rnn_user_zten_indices { H0, IN_WEIGHTS, IN_BIAS, HID_WEIGHTS, HID_BIAS, NUM_INPUTS_GRU, // Not a tensor, used to set size of the array later. C0 = NUM_INPUTS_GRU, NUM_INPUTS_LSTM // Not a tensor, used to set size of the array later. } rnn_user_zten_indices; // Named indices for ztensors created internally during a RNN call. typedef enum rnn_internal_zten_indices { FUSED, TS_FUSED, BIAS_ADD, PREV_H_OUT, TS_H_OUT, PREV_C_OUT, NUM_INTERNAL_ZTENS_GRU, // Not a ztensor, used to set size of the array later. TS_C_OUT = NUM_INTERNAL_ZTENS_GRU, NUM_INTERNAL_ZTENS_LSTM // Not a ztensor, used to set size of the array later. } rnn_internal_zten_indices; // Named indices for descriptors created internally during a RNN call. These // descriptors do not affect the work_area size. typedef enum rnn_internal_desc_indices { RNN_IN_TSFUSED_BIASADD_DESC, NUM_INTERNAL_DESCS } rnn_internal_desc_indices; // Not a descriptor, used to set size of the array. // Named indices for descriptors created internally during a RNN call. These // descriptors influence the size of the work_area. typedef enum work_area_desc_indices { FUSED_WA_DESC, MATMULBIASADD_OUT_WA_DESC, TS_HC_OUT_WA_DESC, NUM_WA_DESCS } work_area_desc_indices; // Struct of work_area descriptors and their calculated sizes. This way we can // run the calculation before slicing to get the total work_area size and not // need to recalculate the buffer_sizes after slicing the directional calls. typedef struct work_area_descriptor { zdnn_tensor_desc desc; size_t buffer_size; } work_area_descriptor; // Helper method that determines the size of the work area for a single // direction. We create some descriptors to determine that size. Save that // information in work_area_descriptor structs so we don't need to regenerate it // later. static size_t setup_work_area_descs(uint8_t function_code, const uint32_t *nums, work_area_descriptor *wa_descs) { // work_area ------------------------------------ // | FUSED <TS 0/TS 1/...> | // +--------------------------------------------- // | BIAS_ADD | // +--------------------------------------------- // | TS_C_OUT (LSTM) / TS_H_OUT (GRU) | // | TS_C_OUT (LSTM) / TS_H_OUT (GRU) <alt> | // ---------------------------------------------- size_t buff_size = 0; size_t work_area_size = 0; // Output of NNPA_MATMUL_OP_BCAST23 + ADDITION: // (ts, 1, b, in_pad) or (ts * g, 1, b, s) init_transformed_desc(ZDNN_NHWC, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &wa_descs[FUSED_WA_DESC].desc, nums[TS], 1, nums[BATCH], nums[IN_PAD]); buff_size = zdnn_getsize_ztensor(&wa_descs[FUSED_WA_DESC].desc); wa_descs[FUSED_WA_DESC].buffer_size = buff_size; work_area_size += buff_size; // Output of NNPA_MATMUL_OP + ADDITION: (4, 1, b, s) init_transformed_desc(ZDNN_NHWC, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &wa_descs[MATMULBIASADD_OUT_WA_DESC].desc, 1, 1, nums[BATCH], nums[IN_PAD]); buff_size = zdnn_getsize_ztensor(&wa_descs[MATMULBIASADD_OUT_WA_DESC].desc); wa_descs[MATMULBIASADD_OUT_WA_DESC].buffer_size = buff_size; work_area_size += buff_size; // Output of NNPA_LSTMACT/NNPA_GRUACT: (1 or 2, 1, b, s) // Depending on number of timesteps, we may or may not need to get temporary // storage for h/c output. If nums[TS] == ... // 1: Save the output right into hn/cf_output buffer. // 2: Need space for a single output. // 3+: Get 2 times the hn/cf_output buffer_size for TS_H/C_OUT because h/c is // both input and output within the same operation. As we do not support // in-place changes, we must have different input and output pointers. init_transformed_desc(ZDNN_NHWC, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &wa_descs[TS_HC_OUT_WA_DESC].desc, 1, 1, nums[BATCH], nums[HID_SIZE]); buff_size = zdnn_getsize_ztensor(&wa_descs[TS_HC_OUT_WA_DESC].desc); wa_descs[TS_HC_OUT_WA_DESC].buffer_size = buff_size; work_area_size += buff_size * MIN(nums[TS] - 1, 2); // final math: ((ts * g) + 4 + (1 or 2), 1, b, s) return work_area_size; } // Setup internal ztensors to store output from our internal NNPA calls. // // FUSED will be the output from the matmul_bcast_op with addition call. The // dimensions will be in the form of (num_ts, 1, batch_size, in_pad) // // BIAS_ADD acts as both an output for MATMULBIASADD and an input to RNN NNPA op // calls. Both require different descriptors. The following are required // shapes for the recurring ops: // // Legend: (see aiu_lstm_gru()) // ----------------------+--------------+----------------------| // AIU Op | Input/Output | Shape | // ----------------------+--------------+----------------------| // NNPA_MATMUL_OP w/ Add | Output | (1, 1, b, in_pad) | // NNPA_LSTMACT/GRUACT | Input | (num_gates, 1, b, s) | // ----------------------+--------------+----------------------| // // TS_C_OUT will be the output (and reused) for each lstm_act // over the timesteps. The dimensions will be in the form // (1, 1, batch_size, hidden_state_size). The same as the cell state output. // // For each, setup dims (if required), then initialize descriptor and // determine buffer_size using helper functions. static void setup_internal_ztensors(uint8_t function_code, const uint32_t *nums, const zdnn_ztensor **sliced_inputs, const zdnn_ztensor *hn_output, const zdnn_ztensor *cf_output, work_area_descriptor *wa_descs, void *work_area, zdnn_tensor_desc *int_descs, zdnn_ztensor *internal_ztens) { // work_area ------------------------------------------------ // | <-- [FUSED].buffer | // +--------------------------------------------------------- // | <-- [BIAS_ADD].buffer | // +--------------------------------------------------------- // | <-- [TS_H_OUT].buffer (GRU) / [TS_C_OUT].buffer (LSTM) | // +--------------------------------------------------------- // Setup FUSED ztensor. internal_ztens[FUSED].pre_transformed_desc = NULL; internal_ztens[FUSED].transformed_desc = &wa_descs[FUSED_WA_DESC].desc; internal_ztens[FUSED].buffer = work_area; internal_ztens[FUSED].buffer_size = wa_descs[FUSED_WA_DESC].buffer_size; // TS_FUSED and the TS based BIAS_ADD both need a (g x 1 x b x s) tfrmd_desc. init_transformed_desc(ZDNN_NHWC, ZDNN_DLFLOAT16, ZDNN_FORMAT_4DFEATURE, &int_descs[RNN_IN_TSFUSED_BIASADD_DESC], nums[GATES], 1, nums[BATCH], nums[HID_SIZE]); // Setup TS_FUSED which will point to a slice of FUSED which matches the // current timestep in the loop. // Note: If TS is 0, it will result in ABEND. Pre-check will catch this if // enabled. internal_ztens[TS_FUSED].pre_transformed_desc = NULL; internal_ztens[TS_FUSED].transformed_desc = &int_descs[RNN_IN_TSFUSED_BIASADD_DESC]; internal_ztens[TS_FUSED].buffer = internal_ztens[FUSED].buffer; internal_ztens[TS_FUSED].buffer_size = internal_ztens[FUSED].buffer_size / nums[TS]; // Setup BIAS_ADD ztensor. Its buffer starts just after the FUSED buffer. Set // its buffer_size to the larger of the two possible descriptors internal_ztens[BIAS_ADD].pre_transformed_desc = NULL; internal_ztens[BIAS_ADD].buffer = (char *)work_area + internal_ztens[FUSED].buffer_size; internal_ztens[BIAS_ADD].buffer_size = wa_descs[MATMULBIASADD_OUT_WA_DESC].buffer_size; // PREV_H_OUT is used to point to the previous loop's h result. The // initial H0 is specified by the user. Afterward, during each loop, // we update this to be the previous loop's result. internal_ztens[PREV_H_OUT].pre_transformed_desc = NULL; internal_ztens[PREV_H_OUT].transformed_desc = sliced_inputs[H0]->transformed_desc; internal_ztens[PREV_H_OUT].buffer = sliced_inputs[H0]->buffer; internal_ztens[PREV_H_OUT].buffer_size = zdnn_getsize_ztensor(internal_ztens[PREV_H_OUT].transformed_desc); // TS_H_OUT is used to track an addr for storing each loop's h output. // It's buffer points to an addr inside of hn_output which was passed in by // the user for returning output. // // When returning all timesteps, each loop, this temporary pointer shifts // along hn_output's buffer causing all results to be returned. // // When sized for returning only the final timestep: // - LSTM: each iteration will effectively point back to the start of // hn_output through this temp tensor, causing only the last timestep // result to be retained. // - GRU: work_area buffer will be used instead through this temp tensor, // until the last timestep internal_ztens[TS_H_OUT].pre_transformed_desc = NULL; internal_ztens[TS_H_OUT].transformed_desc = &wa_descs[TS_HC_OUT_WA_DESC].desc; // Use work_area buffer if GRU and request only last ts H output, otherwise // write directly to the returned hn_output. This also implies LSTM never uses // work_area for H output. if (function_code == NNPA_GRUACT && (hn_output->transformed_desc->dim4 < nums[TS])) { internal_ztens[TS_H_OUT].buffer = (char *)internal_ztens[BIAS_ADD].buffer + internal_ztens[BIAS_ADD].buffer_size; } else { internal_ztens[TS_H_OUT].buffer = hn_output->buffer; } internal_ztens[TS_H_OUT].buffer_size = wa_descs[TS_HC_OUT_WA_DESC].buffer_size; // Only LSTM has C output if (function_code == NNPA_LSTMACT) { // PREV_C_OUT is used to point to the pervious loop's c result. The // initial "c0" is specified by the user. Afterward, during each loop, // we update this to be the previous loop's result. internal_ztens[PREV_C_OUT].pre_transformed_desc = NULL; internal_ztens[PREV_C_OUT].transformed_desc = sliced_inputs[C0]->transformed_desc; internal_ztens[PREV_C_OUT].buffer = sliced_inputs[C0]->buffer; internal_ztens[PREV_C_OUT].buffer_size = zdnn_getsize_ztensor(internal_ztens[PREV_C_OUT].transformed_desc); internal_ztens[TS_C_OUT].pre_transformed_desc = NULL; internal_ztens[TS_C_OUT].transformed_desc = &wa_descs[TS_HC_OUT_WA_DESC].desc; // If only 1 TS, write directly to the returned cf_output. if (nums[TS] == 1) { internal_ztens[TS_C_OUT].buffer = cf_output->buffer; // Otherwise use work_area buffer (last TS will write to returned // cf_output) } else { internal_ztens[TS_C_OUT].buffer = (char *)internal_ztens[BIAS_ADD].buffer + internal_ztens[BIAS_ADD].buffer_size; } internal_ztens[TS_C_OUT].buffer_size = wa_descs[TS_HC_OUT_WA_DESC].buffer_size; } } // Helper method that performs the bulk of the actual RNN processing. It takes // the inputs for a single direction and processes each timestep over a loop of // RNN activation op calls. static zdnn_status directional_rnn(uint8_t function_code, const uint32_t *nums, const zdnn_ztensor *input, const zdnn_ztensor **sliced_inputs, zdnn_ztensor *hn_output, zdnn_ztensor *cf_output, rnn_internal_direction direction, void *work_area, work_area_descriptor *wa_descs) { zdnn_status nnpa_results; BEGIN_BLOCK_IF_LOGLEVEL_TRACE { printf("%s(): For rnn_internal_direction %d input: dumpdata_ztensor()\n", __func__, direction); dumpdata_ztensor(input, AS_FLOAT, false); for (uint32_t input_idx = 0; input_idx < nums[SLICEABLE_INPUTS]; input_idx++) { printf("%s(): For rnn_internal_direction %d on input_idx %u: " "dumpdata_ztensor()\n", __func__, direction, input_idx); dumpdata_ztensor(sliced_inputs[input_idx], AS_FLOAT, false); } } // Determine type of output based on hn_output's timestep dimension. bool all_timesteps; if (hn_output->transformed_desc->dim4 == nums[TS]) { all_timesteps = true; } else { all_timesteps = false; } uint32_t num_internal_ztens = (function_code == NNPA_LSTMACT) ? NUM_INTERNAL_ZTENS_LSTM : NUM_INTERNAL_ZTENS_GRU; zdnn_ztensor internal_ztens[num_internal_ztens]; zdnn_tensor_desc int_descs[NUM_INTERNAL_DESCS]; setup_internal_ztensors(function_code, nums, sliced_inputs, hn_output, cf_output, wa_descs, work_area, int_descs, internal_ztens); // Build a func_sp_parm1_matmul_bcast_op as MATMUL_BCAST_OP_ADDITION for // NNPA_MATMUL_OP_BCAST23 call func_sp_parm1_matmul_bcast_op matmul_bcast_op_parm1; matmul_bcast_op_parm1.val = 0; matmul_bcast_op_parm1.bits.operation = MATMUL_BCAST_OP_ADDITION; // Perform matmul broadcast against input features, weights, and biases if ((nnpa_results = aiu_ops_func_specific( NNPA_MATMUL_OP_BCAST23, input, sliced_inputs[IN_WEIGHTS], sliced_inputs[IN_BIAS], &internal_ztens[FUSED], NULL, 0, matmul_bcast_op_parm1.val, 0, 0, 0, 0)) != ZDNN_OK) { return ZDNN_STATUS( nnpa_results, "Failure within Matmul Biasadd Broadcast call (status = %d)\n", nnpa_results); } // We'll be altering the ztensor's pointer each loop for the NNPA call but // we need the original address so we can update that pointer each // iteration. void *org_buffer_start = internal_ztens[TS_FUSED].buffer; // Set loop interation variables based on direction uint32_t loop_start; int64_t loop_end; int8_t loop_delta; // See where TS_H_OUT/TS_C_OUT is updated each loop for explanation on // hn_out_shift int8_t hn_out_shift; // UNI hn_output (all ts) ----- // | TS_H_OUT 0 | // | TS_H_OUT 1 | // | ... | // | TS_H_OUT N | // ---------------------------- // // UNI hn_output (LSTM 1 ts) -- // | TS_H_OUT 0 > 1 .. > N | // ---------------------------- // // UNI hn_output (GRU 1 ts) -- // | TS_H_OUT N | // --------------------------- // // BIDIR hn_output (all ts) --- FWD loop_start // | FWD TS_H_OUT 0 | | // +--------------------------- | loop_end // | BWD TS_H_OUT 0 | <hn_out_shift> ^ // +--------------------------- | | // | FWD TS_H_OUT 1 | | <hn_out_shift> // +--------------------------- | | // | BWD TS_H_OUT 1 | <hn_out_shift> | // +--------------------------- | | // | ... | . . // +--------------------------- | | // | FWD TS_H_OUT N | V <hn_out_shift> // +--------------------------- loop_end BWD loop_start // | BWD TS_H_OUT N | // ---------------------------- // // BIDIR hn_output (LSTM 1 ts) -- // | FWD TS_H_OUT 0 > 1 .. > N | // +----------------------------- // | BWD TS_H_OUT 0 > 1 .. > N | // ------------------------------ // // BIDIR hn_output (GRU 1 ts) -- // | FWD TS_H_OUT N | // +---------------------------- // | BWD TS_H_OUT N | // ----------------------------- // // UNI cf_output (LSTM) -- // | TS_C_OUT N | // ----------------------- // // BIDIR cf_output (LSTM) -- // | FWD TS_C_OUT N | // | BWD TS_C_OUT N | // ------------------------- switch (direction) { case UNI_FWD: loop_start = 0; loop_end = nums[TS]; loop_delta = 1; hn_out_shift = (all_timesteps) ? 1 : 0; break; case UNI_BWD: loop_start = nums[TS] - 1; loop_end = -1; loop_delta = -1; hn_out_shift = (all_timesteps) ? 1 : 0; internal_ztens[TS_H_OUT].buffer = (char *)internal_ztens[TS_H_OUT].buffer + loop_start * hn_out_shift * internal_ztens[TS_H_OUT].buffer_size; break; case BIDIR_FWD: loop_start = 0; loop_end = nums[TS]; loop_delta = 1; hn_out_shift = (all_timesteps) ? 2 : 0; break; case BIDIR_BWD: loop_start = nums[TS] - 1; loop_end = -1; loop_delta = -1; hn_out_shift = (all_timesteps) ? 2 : 0; // Start at the last single h output position for BWD. See comment where // TS_H_OUT is updated each loop for explanation for why. Since // hn_output.buffer_size is set by the user and we only require they set it // big enough (but not necessarily exact), we can't use it to find the right // output address. So instead we use the TS_H_OUT size that we created // which is the exact size of a single FWD or BWD output. Here loop_start // gives us the index for the last horizontally concatenated output. So to // reach the start of the correct concatenated output address we jump // hn_out_shift (ie 2 or 0) * num concatenated outputs plus one more single // output to reach the reverse's half. internal_ztens[TS_H_OUT].buffer = (char *)internal_ztens[TS_H_OUT].buffer + loop_start * hn_out_shift * internal_ztens[TS_H_OUT].buffer_size + internal_ztens[TS_H_OUT].buffer_size; // TS_C_OUT is similar to TS_H_OUT. For BIDIR_BWD must write to the back // half of the concatenated cf_output. We only ever return the final C // output so there's no shifting like TS_H_OUT. However we only write to // cf_output's buffer on the last timestep, any other we write to work_area // which is sliced between FWD and BWD BIDIR. So the only case we have to // handle right here is if there's only one TS total. if (function_code == NNPA_LSTMACT && nums[TS] == 1) { internal_ztens[TS_C_OUT].buffer = (char *)internal_ztens[TS_C_OUT].buffer + internal_ztens[TS_C_OUT].buffer_size; } break; default: // Users should never see this as a switch in aiu_lstm_gru() checks their // input is valid and our rnn_internal_direction is set afterward. return ZDNN_STATUS(ZDNN_INVALID_DIRECTION, "%d is not a valid rnn_internal_direction", direction); break; } // Used for alternating the intermediate TS_C_OUT (LSTM) / TS_H_OUT (GRU) // buffer each timestep. void *outbuf[2] = {function_code == NNPA_LSTMACT ? internal_ztens[TS_C_OUT].buffer : internal_ztens[TS_H_OUT].buffer, function_code == NNPA_LSTMACT ? (void *)((uintptr_t)internal_ztens[TS_C_OUT].buffer + internal_ztens[TS_C_OUT].buffer_size) : (void *)((uintptr_t)internal_ztens[TS_H_OUT].buffer + internal_ztens[TS_H_OUT].buffer_size)}; // Build a func_sp_parm1_matmul_op as MATMUL_OP_ADDITION for NNPA_MATMUL_OP // call func_sp_parm1_matmul_op matmul_op_parm1; matmul_op_parm1.val = 0; matmul_op_parm1.bits.operation = MATMUL_OP_ADDITION; // Loop through timesteps based on direction for (int64_t i = loop_start, c = 0; i != loop_end; i += loop_delta, c++) { // Set iteration's timestep input based on direction. internal_ztens[TS_FUSED].buffer = (char *)org_buffer_start + (i * internal_ztens[TS_FUSED].buffer_size); // Use the BIAS_ADD descriptor setup for MATMULBIASADD output. internal_ztens[BIAS_ADD].transformed_desc = &wa_descs[MATMULBIASADD_OUT_WA_DESC].desc; // Set BIAS_ADD based on previous loop's output (or H0 if first loop). if ((nnpa_results = aiu_ops_func_specific( NNPA_MATMUL_OP, &internal_ztens[PREV_H_OUT], sliced_inputs[HID_WEIGHTS], sliced_inputs[HID_BIAS], &internal_ztens[BIAS_ADD], NULL, 0, matmul_op_parm1.val, 0, 0, 0, 0)) != ZDNN_OK) { return ZDNN_STATUS( nnpa_results, "Failure within Matmul Biasadd for timestep %ld (status = %d)\n", i, nnpa_results); } // Use the BIAS_ADD descriptor setup for the RNN op call. internal_ztens[BIAS_ADD].transformed_desc = &int_descs[RNN_IN_TSFUSED_BIASADD_DESC]; // Get results from NNPA if ((nnpa_results = aiu_ops( function_code, &internal_ztens[TS_FUSED], &internal_ztens[BIAS_ADD], (function_code == NNPA_LSTMACT) ? &internal_ztens[PREV_C_OUT] : &internal_ztens[PREV_H_OUT], &internal_ztens[TS_H_OUT], (function_code == NNPA_LSTMACT) ? &internal_ztens[TS_C_OUT] : NULL)) != ZDNN_OK) { return ZDNN_STATUS(nnpa_results, "Failure within LSTM/GRU Activation call for timestep " "%ld (status = %d)\n", i, nnpa_results); } // Update PREV_H/C_OUT so next loop uses previous loop's h/c output. internal_ztens[PREV_H_OUT].buffer = internal_ztens[TS_H_OUT].buffer; if (function_code == NNPA_LSTMACT) { internal_ztens[PREV_C_OUT].buffer = internal_ztens[TS_C_OUT].buffer; } if ((function_code == NNPA_LSTMACT) || (function_code == NNPA_GRUACT && all_timesteps)) { // Shift the TS_H_OUT buffer each timestep. TS_H_OUT ultimately points // back an address in the returned hn_output. // // If only returning the final hn result, hn_out_shift will be 0 so the // same location is overwritten each time. This causes only the last // result to be returned // // If returning all timesteps, the shift will be 1 for unidirectional // output. We write and move one output space each loop. // // For BIDIR we return a horizontally concatenated output, where the FWDs // and BWDs are interleaved: // // timestep // ------------- // 0 | FWD | BWD | // 1 | FWD | BWD | // ... | ... | // n | FWD | BWD | // ------------- // // The BIDIR_FWD and BIDIR_BWD call each starts at different addresses in // the same hn_output buffer. Each loop writes one output and shifts 2 // spaces. This way each direction for each timestep can write to it's // half of the concatenated output without overwriting the other's output. // // For all timesteps FWD (uni or bidir), the pointer starts at the // beginning of hn_ouput and each loop shifts forward toward the end of // hn_output since loop_delta will be positive. // // For all timesteps BWD (uni or bidir), we start at the last h output // space. Then each loop we shift backward toward the start of hn_output // buffer since loop_delta will be negative. This way h output order // always matches input timesteps order rather than the order they are // processed. internal_ztens[TS_H_OUT].buffer = (char *)internal_ztens[TS_H_OUT].buffer + hn_out_shift * loop_delta * internal_ztens[PREV_H_OUT].buffer_size; } else { // If GRU and only returning the final hn result: // Use the work_area buffer and alternate between the two available spaces // for intermediate h output, until about to move to final timestep then // we would use hn_output->buffer instead. // Do this on the second to last loop so it affects the last // iteration... if (i + (2 * loop_delta) == loop_end) { internal_ztens[TS_H_OUT].buffer = hn_output->buffer; if (direction == BIDIR_BWD) { internal_ztens[TS_H_OUT].buffer = (char *)internal_ztens[TS_H_OUT].buffer + internal_ztens[TS_H_OUT].buffer_size; } } else { // c == 0 --> [1], == 1 --> [0], == 2 --> [1] etc etc internal_ztens[TS_H_OUT].buffer = outbuf[(~c) & 1]; } } // For TS_C_OUT, if we are about to move to final timestep, we // will now point to cf_output->buffer so it can be returned to the user. // Otherwise, it will use the work_area buffer and alternate between the two // available spaces for intermediate c output. if (function_code == NNPA_LSTMACT) { // Do this on the second to last loop so it affects the last // iteration... if (i + (2 * loop_delta) == loop_end) { internal_ztens[TS_C_OUT].buffer = cf_output->buffer; // For BIDIR, cf_output returns a horizontally concatenated FWD and BWD // output. For BIDIR_BWD shift one output space size to separate FWD and // BWD output. if (direction == BIDIR_BWD) { internal_ztens[TS_C_OUT].buffer = (char *)cf_output->buffer + internal_ztens[TS_C_OUT].buffer_size; } } // Otherwise alternate between intermediate c output buffers else { internal_ztens[TS_C_OUT].buffer = outbuf[(~c) & 1]; } } } return ZDNN_STATUS_OK; } /// Calls the NNPA operations that makeup LSTM. This method preforms "pre and /// post" work. For "pre" it allocates the work_area (if necessary) it then /// calls directional_rnn() to perform the RNN op (slicing the input and calling /// directional_rnn() twice for BIDIR case). After all directions are processed /// it cleans up the work area and returns the final status. Method stops and /// returns on the first error encountered or ZDNN_OK. /// /// \param[in] function_code NNPA_LSTMACT or NNPA_GRUACT /// \param[in] input The lstm input ztensor fed into the AIU. /// \param[in] h0 The hidden state ztensor fed into the AIU. /// \param[in] c0 The cell state ztensor from the AIU (ignored when mode is GRU) /// \param[in] weights The input weights ztensor from the AIU. /// \param[in] biases The input biases ztensor from the AIU. /// \param[in] hidden_weights The hidden weights ztensor from the AIU. /// \param[in] hidden_biases The hidden biases ztensor from the AIU. /// \param[in] direction LSTM/GRU direction (FWD, BWD, BIDIR) /// \param[in] work_area Pointer to pre-allocated work area for our internal /// output ztensors or NULL. /// \param[out] hn_output The returned hidden_state ztensor from the AIU. /// \param[out] cf_output The returned cell_state ztensor from the AIU. /// /// \return ZDNN_OK if all checks pass or a failure based on why it failed. /// zdnn_status aiu_lstm_gru(uint8_t function_code, const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *c0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, void *work_area, zdnn_ztensor *hn_output, zdnn_ztensor *cf_output) { /* DIMENSION REQUIREMENTS (stickified, i.e., NHWC) Legend: b = number of batches d = number of directions (2 if BIDIR or otherwise 1) f = number of features g = number of gates (4 LSTM or 3 GRU) s = hidden state size s_pad = ceil(s/64) * 64 (s with padding to nearest multiple of 64) in_pad = g * s_pad (horizontally concatenated gate input with padding between gates) out_pad = d * s_pad (horizontally concatenated output with padding between directions) ts = number of timesteps Note: The *_output expected shape differs based on unidirectional versus bidirectional. For hn_output, the user specified shape also controls whether all timestep results are returned or just the final result processed. tensor | tfrmd (dim4, 3, 2, 1) | Note ---------------+------------------------------------- input | (ts, 1, b, f) | h0 | (d, 1, b, s) | c0 | (d, 1, b, s) | (LSTM only, GRU NULL) weights | (d, 1, f, in_pad) | biases | (d, 1, 1, in_pad) | hidden_weights | (d, 1, s, in_pad) | hidden_biases | (d, 1, 1, in_pad) | ----------------------------+----------+----------------| hn_output | (ts, 1, b, s) | (uni all timesteps) | (1, 1, b, s) | (uni final only) | (ts, 1, b, out_pad) | (bidir all out_pad) | (1, 1, b, out_pad) | (bidir final only) cf_output | (1, 1, b, s) | (uni LSTM only, GRU NULL) | (1, 1, b, out_pad) | (bidir LSTM only, GRU NULL) When bidir output of the previous layer is used as the input of the current layer, number of features (f) has the same value as out_pad of the previous layer. In such case, the weights tensor for the current layer needs to be vertically concatenated at dim2: input: (ts, 1, b, prev_out_pad) weights: (d, 1, prev_out_pad, in_pad) */ zdnn_status status; // Store special dimensions/values to pass to various internal methods. uint32_t nums[NUM_INTEGER_INDICES]; nums[TS] = input->transformed_desc->dim4; nums[BATCH] = input->transformed_desc->dim2; nums[HID_SIZE] = h0->transformed_desc->dim1; nums[IN_PAD] = weights->transformed_desc->dim1; // LSTM and GRU expect different numbers of tensors (ie gates) horizontally // concatenated into weights and biases tensors. nums[GATES] = get_func_code_num_gates(function_code); // Accounts for extra "cell" tensors in LSTM that aren't in GRU. nums[SLICEABLE_INPUTS] = (function_code == NNPA_LSTMACT) ? NUM_INPUTS_LSTM : NUM_INPUTS_GRU; // Work area is heap memory allocated for RNN internal ztensor buffers bool alloced_work_area = false; // Calculate the work_area size. Save the descriptors used to calculate it. work_area_descriptor wa_descs[NUM_WA_DESCS]; size_t dir_work_area_size = setup_work_area_descs(function_code, nums, wa_descs); // RNN calls can be unidirectional (FWD or BWD) or bidirectional (BIDIR). // Use this to set the number of directions to expect. uint32_t num_dirs = (direction == BIDIR) ? 2 : 1; // If not passed in a pointer to pre-allocated space for the work_area, // allocate it now and record that we need to free what we allocated. void *internal_work_area = work_area; if (internal_work_area == NULL) { size_t total_size = dir_work_area_size * num_dirs; if (!(internal_work_area = malloc_aligned_4k(total_size))) { return ZDNN_STATUS(ZDNN_ALLOCATION_FAILURE, "Unable to allocate %" PRIu64 " bytes for work_area.", total_size); } // Used so we only free the work_area if we allocated it. alloced_work_area = true; } // Order must match rnn_user_zten_indices! const zdnn_ztensor *sliceable_inputs[] = { h0, weights, biases, hidden_weights, hidden_biases, c0}; switch (direction) { // Skip slicing for unidirectional RNN calls case FWD: status = directional_rnn(function_code, nums, input, sliceable_inputs, hn_output, cf_output, UNI_FWD, internal_work_area, wa_descs); break; case BWD: status = directional_rnn(function_code, nums, input, sliceable_inputs, hn_output, cf_output, UNI_BWD, internal_work_area, wa_descs); break; // Slice input along direction dim and make unidirectional calls for each. case BIDIR: { // A sliced input's buffer size won't change between directions so memoize. size_t sliced_zten_buff_sizes[nums[SLICEABLE_INPUTS]]; // Structs to hold slices of the user's original ztensors. zdnn_ztensor sliced_inputs[num_dirs][nums[SLICEABLE_INPUTS]]; const zdnn_ztensor *sliced_inputs_ptrs[num_dirs][nums[SLICEABLE_INPUTS]]; zdnn_tensor_desc input_descs[num_dirs * nums[SLICEABLE_INPUTS]]; uint32_t in_desc_idx = 0; // Slice the user's original ztensors based on direction dimension. for (uint32_t dir_idx = 0; dir_idx < num_dirs; dir_idx++) { // First direction slices are for FWD, the second are BWD. rnn_internal_direction rnn_direction = (dir_idx == 0) ? BIDIR_FWD : BIDIR_BWD; // Slice the inputs over the direction dimension (dim4) for (uint32_t input_idx = 0; input_idx < nums[SLICEABLE_INPUTS]; input_idx++) { const zdnn_ztensor *unsliced_input = sliceable_inputs[input_idx]; // Retrieve or calculate the sliced buffer size for this input. if (dir_idx == 0) { uint32_t unsliced_dim4 = unsliced_input->transformed_desc->dim4; sliced_zten_buff_sizes[input_idx] = zdnn_getsize_ztensor(unsliced_input->transformed_desc) / unsliced_dim4; } uint32_t tfrmd_idx = in_desc_idx++; status = ztensor_slice_dim4( unsliced_input, dir_idx, sliced_zten_buff_sizes[input_idx], NULL, &input_descs[tfrmd_idx], &sliced_inputs[dir_idx][input_idx]); if (status != ZDNN_OK) { break; } sliced_inputs_ptrs[dir_idx][input_idx] = &sliced_inputs[dir_idx][input_idx]; } if (status != ZDNN_OK) { break; } void *dir_work_area = (char *)internal_work_area + (dir_idx * dir_work_area_size); status = directional_rnn( function_code, nums, input, sliced_inputs_ptrs[dir_idx], hn_output, cf_output, rnn_direction, dir_work_area, wa_descs); if (status != ZDNN_OK) { break; } } } break; default: status = ZDNN_STATUS(ZDNN_INVALID_DIRECTION, "%d is not a valid direction", direction); break; } // Frees the entire work_area for all directions (if required) if (alloced_work_area) { free_aligned_4k(internal_work_area); } // Upon success, indicate that the hn_output and cf_output tensors have a // stickified (4DFeature) tensor and return status. if (status == ZDNN_OK) { hn_output->is_transformed = true; BEGIN_BLOCK_IF_LOGLEVEL_TRACE { printf("%s(): Returning hn_output: dumpdata_ztensor()\n", __func__); dumpdata_ztensor(hn_output, AS_FLOAT, false); } if (function_code == NNPA_LSTMACT) { cf_output->is_transformed = true; BEGIN_BLOCK_IF_LOGLEVEL_TRACE { printf("%s(): Returning cf_output: dumpdata_ztensor()\n", __func__); dumpdata_ztensor(cf_output, AS_FLOAT, false); } } } // We break from loops if any status was not OK so we'll return either the // first failure or OK if everything works. return status; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/aiu_ops.c���������������������������������������������������������������������������0000664�0000000�0000000�00000015074�14364043643�0015114�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <string.h> /// Convenience wrapper for AIU ops that don't need function specific parameters zdnn_status aiu_ops(uint8_t function_code, const zdnn_ztensor *input1, const zdnn_ztensor *input2, const zdnn_ztensor *input3, zdnn_ztensor *output1, zdnn_ztensor *output2) { return aiu_ops_func_specific(function_code, input1, input2, input3, output1, output2, 0, 0, 0, 0, 0, 0); } /// Common routine for invoking AIU operations with function specific /// parameters /// /// \note Caller MUST set the unused input parameters to NULL (for pointers) or /// 0 (for ints) /// /// \param[in] function_code NNPA function code /// \param[in] input1 /// \param[in] input2 /// \param[in] input3 /// \param[in] output1 /// \param[in] output2 /// \param[in] func_sp_savearea_addr Function-specific-save-area-address /// \param[in] func_sp_parm1 Function-specific-parameter-1 /// \param[in] func_sp_parm2 Function-specific-parameter-2 /// \param[in] func_sp_parm3 Function-specific-parameter-3 /// \param[in] func_sp_parm4 Function-specific-parameter-4 /// \param[in] func_sp_parm5 Function-specific-parameter-5 /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status aiu_ops_func_specific(uint8_t function_code, const zdnn_ztensor *input1, const zdnn_ztensor *input2, const zdnn_ztensor *input3, zdnn_ztensor *output1, zdnn_ztensor *output2, uint64_t func_sp_savearea_addr, uint32_t func_sp_parm1, uint32_t func_sp_parm2, uint32_t func_sp_parm3, uint32_t func_sp_parm4, uint32_t func_sp_parm5) { zdnn_status status; uint8_t ef = 0; #define EF_RANGE_VIOLATION_MASK 0x80 if (precheck_enabled) { // some ops use their own verifier. for everything else use the simple one. switch (function_code) { case NNPA_BATCHNORMALIZATION: if ((status = verify_batchnorm_tensors(input1, input2, input3, output1)) != ZDNN_OK) { return status; } break; case NNPA_LSTMACT: case NNPA_GRUACT: if ((status = verify_lstm_or_gru_act_tensors(function_code, input1, input2, input3, output1, output2)) != ZDNN_OK) { return status; } break; case NNPA_MATMUL_OP: if ((status = verify_matmul_op_tensors(input1, input2, input3, output1)) != ZDNN_OK) { return status; } break; case NNPA_MATMUL_OP_BCAST23: if ((status = verify_matmul_bcast_op_tensors(input1, input2, input3, output1)) != ZDNN_OK) { return status; } break; case NNPA_AVGPOOL2D: case NNPA_MAXPOOL2D: // The switch in arg order below is intentional. NNPA func_sp_params2-5 // are ordered stride_w, stride_h, kernel_w, kernel_h but our function // expects a different order. if ((status = verify_pool_avg_max_tensors( input1, func_sp_parm1, func_sp_parm5, func_sp_parm4, func_sp_parm3, func_sp_parm2, output1)) != ZDNN_OK) { return status; } break; case NNPA_CONVOLUTION: // verify_conv2d_tensors() expects (height, width) order, thus // (func_sp_parm3, func_sp_parm2) if ((status = verify_conv2d_tensors(input1, input2, input3, func_sp_parm1, func_sp_parm3, func_sp_parm2, func_sp_parm4, output1)) != ZDNN_OK) { return status; } break; case NNPA_RELU: if ((status = verify_relu_tensors(input1, func_sp_parm1, output1)) != ZDNN_OK) { return status; } break; default: if ((status = verify_tensors(input1, input2, input3, output1)) != ZDNN_OK) { return status; } break; } } // SOFTMAX requires a 4k-aligned save area. Either use caller's or allocate // our own. void *savearea_addr = (void *)func_sp_savearea_addr; if (function_code == NNPA_SOFTMAX && func_sp_savearea_addr == 0) { if (!(savearea_addr = malloc_aligned_4k(ZDNN_SOFTMAX_SAVEAREA_SIZE))) { return ZDNN_STATUS(ZDNN_ALLOCATION_FAILURE, "Unable to allocate %" PRIu64 " bytes for save area.", ZDNN_SOFTMAX_SAVEAREA_SIZE); } } nnpa_parameter_block parm_block; populate_nnpa_parm_block(&parm_block, input1, input2, input3, output1, output2, savearea_addr, func_sp_parm1, func_sp_parm2, func_sp_parm3, func_sp_parm4, func_sp_parm5); status = invoke_nnpa(function_code, (char *)&parm_block, &ef); // free the savearea if using our own, regardless of op if (savearea_addr && !func_sp_savearea_addr) { free_aligned_4k(savearea_addr); } // Indicate output tensor is stickified only if invoke_nnpa() was OK if (status == ZDNN_OK) { if (ef & EF_RANGE_VIOLATION_MASK) { status = ZDNN_STATUS(ZDNN_ELEMENT_RANGE_VIOLATION, "Range violation on tensor data", NO_ARG); /* AIU operation returned a RANGE VIOLATION, set as a warning code and continue processing */ } else if (ef & ~EF_RANGE_VIOLATION_MASK) { return status = ZDNN_STATUS(ZDNN_UNSUPPORTED_AIU_EXCEPTION, "Unsupported exception on ZDNN operation", NO_ARG); /* AIU operation returned an unexpected exception, return as a failure */ } output1->is_transformed = true; if (function_code == NNPA_LSTMACT) { output2->is_transformed = true; } } return status; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/allochelper.c�����������������������������������������������������������������������0000664�0000000�0000000�00000006000�14364043643�0015734�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <stdio.h> #include <stdlib.h> #ifdef __MVS__ #pragma export(zdnn_allochelper_ztensor) #pragma export(zdnn_free_ztensor_buffer) #pragma export(zdnn_getsize_ztensor) #endif /// Allocate a buffer with size required for storing transformed tensor data of /// shape specified in the transformed descriptor, and assocate the buffer with /// the incoming zTensor /// /// \param[out] ztensor Pointer to zdnn_ztensor /// /// \return ZDNN_OK /// ZDNN_INVALID_FORMAT /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_SHAPE /// ZDNN_ALLOCATION_FAILURE /// zdnn_status zdnn_allochelper_ztensor(zdnn_ztensor *ztensor) { uint64_t size; zdnn_status status; // only the information in transformed_desc matters, so make sure it's // reasonable if ((status = verify_transformed_descriptor(ztensor->transformed_desc)) != ZDNN_OK) { return status; } // get the size and allocate space aligned on a 4k boundary. If the malloc // fails, return error. size = zdnn_getsize_ztensor(ztensor->transformed_desc); if (!(ztensor->buffer = malloc_aligned_4k(size))) { return ZDNN_STATUS(ZDNN_ALLOCATION_FAILURE, "Unable to allocate %" PRIu64 " bytes.", size); } // With a successful malloc, set our ztensor's buffer_size with the allocated // size. ztensor->buffer_size = size; // Successful zdnn_allochelper_ztensor call return ZDNN_STATUS_OK; } /// Free the stickified tensor data buffer within the incoming zTensor /// /// \param[in] ztensor Pointer to zdnn_ztensor /// /// \return ZDNN_OK /// ZDNN_INVALID_BUFFER /// zdnn_status zdnn_free_ztensor_buffer(const zdnn_ztensor *ztensor) { if (!ztensor->buffer) { return ZDNN_STATUS_NO_MSG(ZDNN_INVALID_BUFFER); } free_aligned_4k(ztensor->buffer); return ZDNN_STATUS_OK; } /// Calculates the number of bytes required for storing transformed tensor data /// of shape specified in the transformed descriptor /// /// \param[in] tfrmd_desc Pointer to transformed tensor descriptor /// /// \return Memory size (in bytes) /// uint64_t zdnn_getsize_ztensor(const zdnn_tensor_desc *tfrmd_desc) { // same formula for 4DFEATURE and 4DKERNEL tensors return (uint64_t)(tfrmd_desc->dim4) * tfrmd_desc->dim3 * CEIL(tfrmd_desc->dim2, AIU_STICKS_PER_PAGE) * CEIL(tfrmd_desc->dim1, AIU_2BYTE_CELLS_PER_STICK) * AIU_PAGESIZE_IN_BYTES; } zDNN-1.0.1/zdnn/convert.h���������������������������������������������������������������������������0000664�0000000�0000000�00000010231�14364043643�0015130�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ZDNN_CONVERT_H_ #define ZDNN_CONVERT_H_ #include <inttypes.h> #include <stddef.h> /* Within convert.h/convert.c, we must treat the floating point values to be converted as simple INT values for the conversions to be successful, so we typedef those here. */ typedef uint16_t float_bit16; /* Generic type for any of the 16 bit items that are really considered "short floats": dlfloat, fp16 or bfloat */ typedef uint32_t float_bit32; /* Generic type for the 32 bit items that are really considered "floats": float or fp32 */ // used to get around "breaking strict-aliasing rules" so that we can // manipulate the bits within a float typedef union uint32_float_u { uint32_t u; float f; } uint32_float_u; uint64_t fp16_to_dlf16(uint16_t *input_fp16_data, uint16_t *output_dflt16_data, uint64_t nbr_fields_to_convert); uint64_t fp32_to_dlf16(float *input_data, uint16_t *output_data, uint64_t nbr_fields_to_convert); uint64_t bfloat_to_dlf16(uint16_t *input_data, uint16_t *output_data, uint64_t nbr_fields_to_convert); uint64_t dlf16_to_fp16(uint16_t *input_dflt16_data, uint16_t *output_fp16_data, uint64_t nbr_fields_to_convert); uint64_t dlf16_to_fp32(uint16_t *input_data, float *output_data, uint64_t nbr_fields_to_convert); uint64_t dlf16_to_bfloat(uint16_t *input_data, uint16_t *output_data, uint64_t nbr_fields_to_convert); uint64_t fp16_to_dlf16_in_stride(uint16_t *fp16_data, uint16_t *dflt16_data, uint64_t nbr_fields_to_convert, uint32_t input_stride); uint64_t fp32_to_dlf16_in_stride(float *fp32_data, uint16_t *dflt16_data, uint64_t nbr_fields_to_convert, uint32_t input_stride); uint64_t bfloat_to_dlf16_in_stride(uint16_t *bflt_data, uint16_t *dflt16_data, uint64_t nbr_fields_to_convert, uint32_t input_stride); uint64_t dlf16_to_fp16_in_stride(uint16_t *dflt16_data, uint16_t *fp16_data, uint64_t nbr_fields_to_convert, uint32_t input_stride); uint64_t dlf16_to_fp32_in_stride(uint16_t *dflt16_data, float *fp32_data, uint64_t nbr_fields_to_convert, uint32_t input_stride); uint64_t dlf16_to_bfloat_in_stride(uint16_t *dflt16_data, uint16_t *bflt_data, uint64_t nbr_fields_to_convert, uint32_t input_stride); /********************************************************************** * cnvt_1 functions - These functions invoke the aiu_vec functions to * convert one value. Highly inefficient. **********************************************************************/ /* cnvt_1_fp32_to_dlf */ uint16_t cnvt_1_fp32_to_dlf16(float a); /* cnvt_1_dlf16_to_fp32 */ float cnvt_1_dlf16_to_fp32(uint16_t a); /* cnvt_1_fp16_to_dlf */ uint16_t cnvt_1_fp16_to_dlf16(uint16_t a); /* cnvt_1_dlf16_to_fp16 */ uint16_t cnvt_1_dlf16_to_fp16(uint16_t a); /* cnvt_1_bfloat_to_dlf */ uint16_t cnvt_1_bfloat_to_dlf16(uint16_t a); /* cnvt_1_dlf16_to_bfloat */ uint16_t cnvt_1_dlf16_to_bfloat(uint16_t a); float cnvt_1_bfloat_to_fp32(uint16_t a); float cnvt_1_fp16_to_fp32(uint16_t a); uint16_t cnvt_1_fp32_to_bfloat(float a); uint16_t cnvt_1_fp32_to_fp16(float a); // End of cnvt_1 functions #endif /* ZDNN_CONVERT_H_ */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/convert_hw.c������������������������������������������������������������������������0000664�0000000�0000000�00000161404�14364043643�0015632�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <stdbool.h> #include <stddef.h> #include <stdio.h> #include <string.h> #include "convert.h" #include "zdnn.h" #include "zdnn_private.h" /* * Implementation note: This routine receives various floating point * data types. But for the purposes of type conversion, we treat * these as integers. C likes to help convert floats to integers, * but we need to control all aspects of conversion to ensure * proper results for the AIU. Hence, routines that receive * "float"-types will immediately cast to one of the float_bitxx * types and use those from then on. */ #define STICKCVT_MAX_ENTRIES_TO_CONVERT 8 /* Number of entries to be converted at a time. Conversion to/from FP32 to DLFLOAT require 2 vector regs to contain the 8 values, all others use 1 VR */ vec_char8 selection_vector = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; static vec_int16 zero_vector16 = {0, 0, 0, 0, 0, 0, 0, 0}; /*********************************************************************** * aiu_vec_round_from_fp32 routines * * Converts 2 vectors (4 elements each) of 32-bit floating point * numbers to 1 vector of 16-bit DLFLOAT numbers (8 numbers total) * * Input: 2 vectors of 4 FP32 data elements to convert * Output: vector of 8 DLFloat16 floats * * Note: There is also a non-inlined wrapper function as well. **********************************************************************/ static vec_int16 inline aiu_vec_round_from_fp32_inline(vec_float32 a, vec_float32 b) { vec_int16 out; #ifndef ZDNN_CONFIG_NO_NNPA #if defined(__MVS__) /* Invoke the VCRNF "* VCRNF VReg0,VRegL,VRegR,mask2,0 \n\t" Note that registers are hardcoded (vs using %0 notation) to ensure that the hardcoded instruction (E60120020075) has expected regs free */ // clang-format off __asm volatile(" VL 1,%[in_vector_left] \n\t" " VL 2,%[in_vector_right] \n\t" " DC XL6'E60120020075' \n\t" " DS 0H \n\t" " VST 0,%[out_vector] \n\t" : /* Outputs - out_vector */ [out_vector] "=m"(out) //(out_vector) : /* Inputs */ [mask2] "i"(2), /* 2 = Internal NNPA format (DLF) */ [mask0] "i"(0), /* 0 = FP32 */ [in_vector_left] "m"(a), /* data */ [in_vector_right] "m"(b) /* data */ : /* "%v0", "%v1", "%v2" Clobbered */ ); // clang-format on #else // clang-format off __asm volatile(".insn vrr,0xe60000000075,%[out],%[in_hi],%[in_lo],0,2,0" : [ out ] "=v"(out) : [ in_hi ] "v"(a), [ in_lo ] "v"(b)); // clang-format on #endif #else // cast our 32 bit vectors as bytes, then select via vec_perm which // bytes to return. (Will be first 2 bytes of every float32) out = (vec_int16)vec_perm((vec_char8)a, (vec_char8)b, selection_vector); #endif // ZDNN_CONFIG_NO_NNPA return out; } // End aiu_vec_round_from_fp32 // Common version of non-inlined aiu_vec_round_from_fp32 vec_int16 aiu_vec_round_from_fp32(vec_float32 a, vec_float32 b) { return aiu_vec_round_from_fp32_inline(a, b); } /*********************************************************************** * aiu_vec_convert_from_fp16 * * Converts 1 vector (8 elements) of 16-bit floating point * numbers to 1 vector of 16-bit DLFLOAT numbers (8 numbers total) * * Input: 1 vector of 8 FP16 data elements to convert * Output: vector of 8 DLFloat16 floats * * Note: There is also a non-inlined wrapper function as well. **********************************************************************/ static vec_int16 inline aiu_vec_convert_from_fp16_inline(vec_int16 a) { vec_int16 out; #ifndef ZDNN_CONFIG_NO_NNPA #if defined(__MVS__) /* Invoke the VCNF "* VCNF VReg0,VReg1,,mask1,0 \n\t" Note that registers are hardcoded (vs using %0 notation) to ensure that the hardcoded instruction (E60100010055) has expected regs free */ // clang-format off __asm volatile(" VL 1,%[in_vector] \n\t" " DC XL6'E60100010055' \n\t" " DS 0H \n\t" " VST 0,%[out_vector] \n\t" : /* Outputs - out_vector */ [out_vector] "=m"(out) //(out_vector) : /* Inputs */ [mask1] "i"(1), /* 1 = BFP tiny format (FP16) */ [mask0] "i"(0), /* 0 = NNP format */ [in_vector] "m"(a) /* data */ : /* "%v0", "%v1" Clobbered */ // clang-format on ); #else // clang-format off __asm volatile(".insn vrr,0xe60000000055,%[out],%[in_vec],0,0,1,0" : [ out ] "=v"(out) : [ in_vec ] "v"(a)); // clang-format on #endif #else // scaffolding: just copy the input 16-bit elements as is to output memcpy(&out, &a, sizeof(vec_int16)); #endif // ZDNN_CONFIG_NO_NNPA return out; } // End aiu_vec_convert_from_fp16 // Common wrapper version of non-inlined aiu_vec_convert_from_fp16 vec_int16 aiu_vec_convert_from_fp16(vec_int16 a) { return aiu_vec_convert_from_fp16_inline(a); } /*********************************************************************** * aiu_vec_lengthen_to_fp32 * * Converts 1 vector of 16-bit DLFLOAT numbers (8 numbers total) to * 2 vectors (4 elements each) of 32-bit floating point * * Input: 1 vector (input) of 8 DLFloat16 floats to convert * 2 vectors (output) of 4 FP32 data elements * * Note: There is also a non-inlined wrapper function as well. **********************************************************************/ static void inline aiu_vec_lengthen_to_fp32_inline(vec_int16 a, vec_float32 *out1, vec_float32 *out2) { #ifndef ZDNN_CONFIG_NO_NNPA vec_float32 work_float_1; vec_float32 work_float_2; #if defined(__MVS__) /* * Invoke the VCLFNx * "* VCLFN(H/L) VReg0,VReg2,mask0,mask2 \n\t" */ // clang-format off __asm volatile(" VL 2,%[in_vector] \n\t" // load VR with 8 DLFs " DC XL6'E60200002056' \n\t" //VCLFNH to VR0 " DC XL6'E6120000205E' \n\t" //VCLFNL to VR1 " DS 0H \n\t" " VST 0,%[out_vector_left] \n\t" //store 1-4 FP32s to output " VST 1,%[out_vector_right] \n\t" //store 5-8 FP32s to output : /* Outputs - out_vector */ [ out_vector_left ] "=m"(work_float_1), //(out_vector) [ out_vector_right ] "=m"(work_float_2) //(out_vector) : /* Inputs */ [ in_vector ] "m" (a), /* data */ [ mask2 ] "i"(2), /* 2 = Internal NNPA format (DLF) */ [ mask0 ] "i"(0) /* 0 = FP32 */ : /* "%v0", "%v1", "%v2" Clobbered */ ); // clang-format on *out1 = work_float_1; *out2 = work_float_2; #else // clang-format off __asm volatile(".insn vrr,0xe60000000056,%[out1],%[in_vec],0,2,0,0 \n\t" ".insn vrr,0xe6000000005E,%[out2],%[in_vec],0,2,0,0 \n\t" : [ out1 ] "=&v"(work_float_1), [ out2 ] "=v"(work_float_2) : [ in_vec ] "v"(a)); // clang-format on *out1 = work_float_1; *out2 = work_float_2; #endif #else *out1 = (vec_float32)vec_mergeh(a, zero_vector16); *out2 = (vec_float32)vec_mergel(a, zero_vector16); #endif // ZDNN_CONFIG_NO_NNPA return; } // End aiu_vec_lengthen_to_fp32 // Common wrapper version of non-inlined aiu_vec_lengthen_to_fp32 void aiu_vec_lengthen_to_fp32(vec_int16 a, vec_float32 *out1, vec_float32 *out2) { aiu_vec_lengthen_to_fp32_inline(a, out1, out2); } /*********************************************************************** * aiu_vec_convert_to_fp16 * * Converts 1 vector (8 elements) of 16-bit DLFloat numbers * to 1 vector of 16-bit FP16 numbers (8 numbers total) * * Input: 1 vector of 8 DLFloat data elements to convert * Output: 1 vector of 8 FP16 elements * * Note: There is also a non-inlined wrapper function as well. **********************************************************************/ static vec_int16 inline aiu_vec_convert_to_fp16_inline(vec_int16 a) { vec_int16 work_short_1; #ifndef ZDNN_CONFIG_NO_NNPA #if defined(__MVS__) /* * Invoke the VCFN * "* VCFN VReg0,VReg2,mask0,mask1 \n\t" */ // clang-format off __asm volatile(" VL 2,%[in_vector] \n\t" // load VR with 8 DLFs " DC XL6'E6020000105D' \n\t" //VCFN to VR0 " DS 0H \n\t" " VST 0,%[out_vector] \n\t" //store 8 FP16s to output : /* Outputs - out_vector */ [ out_vector ] "=m"(work_short_1) : /* Inputs */ [ in_vector ] "m" (a), /* data */ [ mask1 ] "i"(1), /* 1 = FP16 */ [ mask0 ] "i"(0) /* 0 = Internal NNPA format (DLF) */ : /* "%v0", "%v2" Clobbered */ ); // clang-format on #else // clang-format off __asm volatile(".insn vrr,0xe6000000005D,%[out_vec],%[in_vec],0,1,0,0 \n\t" : [out_vec] "=v"(work_short_1) : [in_vec] "v"(a)); // clang-format on #endif #else // scaffolding: just copy the input 16-bit elements as is to output memcpy(&work_short_1, &a, sizeof(vec_int16)); #endif // #ifndef ZDNN_CONFIG_NO_NNPA return work_short_1; } // Common wrapper version of non-inlined aiu_vec_convert_to_fp16 vec_int16 aiu_vec_convert_to_fp16(vec_int16 a) { return aiu_vec_convert_to_fp16_inline(a); } // End of ASM functions /*********************************************************************** * cnvt_1 functions - These functions invoke the aiu_vec functions to * convert one value. Highly inefficient. **********************************************************************/ /* cnvt_1_fp32_to_dlf16 */ uint16_t cnvt_1_fp32_to_dlf16(float a) { vec_int16 aiu_op_output_dfloat; // vector output from aiu_vec_round... /* Copy value to work area, use AIU op routine to convert value from fp32 to dlfloat in pseudo vector (array), then copy the 1 converted entry into the expected data area */ uint32_float_u tempfp32array[8] = {0}; memcpy(tempfp32array, &a, sizeof(float)); /* used as input to aiu_vec_round conversion */ aiu_op_output_dfloat = aiu_vec_round_from_fp32( *((vec_float32 *)&tempfp32array[0]), *((vec_float32 *)&tempfp32array[4])); /* Convert from fp32 to dlfloat with rounding */ return (uint16_t)aiu_op_output_dfloat[0]; // return first value from vector } /* cnvt_1_dlf16_to_fp32 */ float cnvt_1_dlf16_to_fp32(uint16_t a) { vec_float32 aiu_op_output_fp32[2]; // vector output from aiu_vec_lengthen /* Copy value to work area, use AIU op routine to convert value from dlfloat to fp32 in pseudo vector (array), then copy the 1 converted entry into the expected data area */ float_bit16 tempshortarray[8] = {a}; // used as input to aiu_vec_lengthen... // conversion aiu_vec_lengthen_to_fp32(*((vec_int16 *)&tempshortarray[0]), aiu_op_output_fp32, aiu_op_output_fp32 + 1); /* Convert from dlfloat to fp32 with lengthening */ return (*(uint32_float_u *)aiu_op_output_fp32) .f; /* return first value from vector output */ } /* cnvt_1_fp16_to_dlf */ uint16_t cnvt_1_fp16_to_dlf16(uint16_t a) { vec_int16 aiu_op_output; /* Copy value to work area, use AIU op routine to convert value from fp16 to dlfloat in pseudo vector (array), then copy the 1 converted entry into the expected data area */ float_bit16 tempFP16array[8] = {a}; /* used as input to aiu_vec_convert... conversion */ aiu_op_output = aiu_vec_convert_from_fp16( *(vec_int16 *)(tempFP16array)); // Convert from fp16 to dlfloat return (uint16_t)aiu_op_output[0]; // return first value from vector } /* cnvt_1_dlf16_to_fp16 */ uint16_t cnvt_1_dlf16_to_fp16(uint16_t a) { vec_int16 aiu_op_output; /* Copy value to work area, use AIU op routine to convert value from dlfloat to fp16 in pseudo vector (array), then copy the 1 converted entry into the expected data area */ float_bit16 tempFP16array[8] = {a}; /* input to aiu_vec_lengthen conversion, with input as first (only) entry */ aiu_op_output = aiu_vec_convert_to_fp16( *(vec_int16 *)(&tempFP16array)); // Convert from dlfloat to fp16 return (float_bit16)aiu_op_output[0]; // return value from vector } uint16_t cnvt_1_bfloat_to_dlf16(uint16_t a) { /* Copy value to work area adding decimal places to make it into a FP32, use AIU op routine to convert value from FP32 to dlfloat */ uint32_float_u temp_pseudo_float; // copy bfloat value into left side of a float, implementing a pseudo version // of the vector merge op temp_pseudo_float.u = ((float_bit32)a << 16); return cnvt_1_fp32_to_dlf16(temp_pseudo_float.f); /* Convert value (now fp32) to dlfloat with rounding */ } uint16_t cnvt_1_dlf16_to_bfloat(uint16_t a) { uint32_float_u temp_pseudo_float; /* Convert (and lengthen) the dlfloat back to fp32 */ temp_pseudo_float.f = cnvt_1_dlf16_to_fp32(a); // Return the left 2 bytes of the returned float as our bfloat return (temp_pseudo_float.u >> 16); } // convert 1 BFLOAT element to FP32 (C float) float cnvt_1_bfloat_to_fp32(uint16_t a) { // simply appends 16 0-bits as mantissa uint32_t u = (uint32_t)a << 16; return (*(uint32_float_u *)&u).f; } /*********************************************************************** * There's no direct hardware support for the following conversions, * therefore do it via a x -> DLFLOAT16 -> y chain. Precision loss * may occur ***********************************************************************/ // convert 1 FP16 element to FP32 (C float) float cnvt_1_fp16_to_fp32(uint16_t a) { uint32_float_u x = {cnvt_1_dlf16_to_fp32(cnvt_1_fp16_to_dlf16(a))}; return x.f; } // convert 1 FP32 element to BFLOAT uint16_t cnvt_1_fp32_to_bfloat(float a) { uint32_float_u x = {cnvt_1_dlf16_to_bfloat(cnvt_1_fp32_to_dlf16(a))}; return x.u; } // convert 1 FP32 element to FP16 uint16_t cnvt_1_fp32_to_fp16(float a) { uint32_float_u x = {cnvt_1_dlf16_to_fp16(cnvt_1_fp32_to_dlf16(a))}; return x.u; } // End of cnvt_1 functions /*********************************************************************** * fp16_to_dlf16 * * Converts 16-bit floating point elements (BFP tiny) * to 16-bit DLFLOAT stick elements * * Input: Address of N consecutive fp16 data elements to convert * Address to store N converted DLFLOAT16 data elements * Number of elements to convert (N) * Output: Number of elements that were converted * * Dependency: the number of elements to convert in this call should * not cross from one stick to another! **********************************************************************/ uint64_t fp16_to_dlf16(uint16_t *input_fp16_data, uint16_t *output_dflt16_data, uint64_t nbr_fields_to_convert) { // Set vector pointers from input/output pointers passed in. // Note: adding 1 to a vector pointer will move it ahead 16 bytes vec_int16 *cur_input_data = (vec_int16 *)input_fp16_data; // Point to input vector data vec_int16 *cur_output_data = (vec_int16 *)output_dflt16_data; // Point to output vector data vec_int16 in_vector; // Define a vector to load eight of the input data // fields into. A vector can fit 8 int16 fields vec_int16 out_vector; // Define a output vector for PACK operation. // Vector can fit 8 int16 fields /*If there's 8 or more to convert, convert groups of 8 FP16s to 8 DL16s */ for (int i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { *(cur_output_data) = aiu_vec_convert_from_fp16_inline( *(vec_int16 *)(cur_input_data)); // Convert from fp16 cur_input_data++; /* bump ptr to start of next vector (8 uint16s = 16 bytes = 1 vector) */ cur_output_data++; /* bump ptr to start of next output vector (8 shorts = 1 vector) */ } int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left to // convert if (!curnbr_fields_to_convert) // If none, return nbr_fields_to_convert; // Return, indicating all converted // If there's still some to convert, it will be 7 or less, and we should // tread carefully to avoid touching user data beyond what they said they // gave us. Simply load by length the proper amount of data, convert the // whole vector, then store with proper length. in_vector = (vec_int16)vec_load_len((const uint16_t *)cur_input_data, curnbr_fields_to_convert * sizeof(uint16_t) - 1); // Invoke the VCNF function out_vector = aiu_vec_convert_from_fp16_inline(in_vector); // Store results from vector to caller's storage vec_store_len(out_vector, (uint16_t *)cur_output_data, curnbr_fields_to_convert * 2 - 1); return nbr_fields_to_convert; } /*********************************************************************** * dlf16_to_fp16 * * Converts 16-bit DLFloat floating point elements (NNP format) * to 16-bit floating point (BFP tiny format) * * Input: Address of N consecutive DLFloat16 data elements to convert * Address to store N converted FP16 data elements * Number of elements to convert (N) * Output: Number of elements that were converted * * Dependency: the number of elements to convert in this call should * not cross from one stick to another! **********************************************************************/ uint64_t dlf16_to_fp16(uint16_t *input_dflt16_data, uint16_t *output_fp16_data, uint64_t nbr_fields_to_convert) { // Set vector pointers from input/output pointers passed in. // Note: adding 1 to a vector pointer will move it ahead 16 bytes vec_int16 *cur_input_data = (vec_int16 *)input_dflt16_data; // Point to input vector data vec_int16 *cur_output_data = (vec_int16 *)output_fp16_data; // Point to output vector data vec_int16 in_vector; // Define a vector to load eight of the input data // fields into. A vector can fit 8 int16 fields vec_int16 out_vector; // Define a output vector for PACK operation. // Vector can fit 8 int16 fields /* If there's 8 or more to convert, convert groups of 8 FP16s to 8 DL16s */ for (int i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { *(cur_output_data) = aiu_vec_convert_to_fp16_inline( *(vec_int16 *)(cur_input_data)); // Convert from dlfloat to fp16 cur_input_data++; /* bump ptr to start of next vector (8 uint16s = 16 bytes = 1 vector) */ cur_output_data++; /* bump ptr to start of next output vector (8 shorts = 1 vector) */ } int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left to // convert if (!curnbr_fields_to_convert) // If none, return nbr_fields_to_convert; // Return, indicating all converted // If there's still some to convert, it will be 7 or less, and we should // tread carefully to avoid touching user data beyond what they said they // gave us. Simply load by length the proper amount of data, convert the // whole vector, then store with proper length. in_vector = (vec_int16)vec_load_len((const uint16_t *)cur_input_data, curnbr_fields_to_convert * sizeof(uint16_t) - 1); // Invoke the VCNF function out_vector = aiu_vec_convert_to_fp16_inline(in_vector); // Store results from vector to caller's storage vec_store_len(out_vector, (uint16_t *)cur_output_data, curnbr_fields_to_convert * 2 - 1); return nbr_fields_to_convert; } /*********************************************************************** * fp32_to_dlf16 * * Converts 32-bit Floating Point elements to 16 bit DLFLOAT stick elements * * Input: Address of N FP32 data elements to convert * Address to store N converted DLFLOAT16 data elements * Number of elements to convert (N) * Output: Number of elements that were converted * * Dependency: the number of elements to convert in this call should * not cross from one stick to another! * (i.e. 'N' must be <= 64) **********************************************************************/ uint64_t fp32_to_dlf16(float *input_data, uint16_t *output_data, uint64_t nbr_fields_to_convert) { // Set vector pointers from input/output pointers passed in. // Note: adding 1 to a vector pointer will move it ahead 16 bytes // Point to input vector followed by point to output vector data // cppcheck-suppress invalidPointerCast vec_float32 *cur_input_data = (vec_float32 *)input_data; vec_int16 *cur_output_data = (vec_int16 *)output_data; vec_float32 in_vector_left; // Define a vector to load four of the input data // fields into. This will be the Left half of the // concatenated vector. Vector can fit 4 int32 fields vec_float32 in_vector_right; // Define a vector to load four more input data fields // into. This will be the Right half of the // concatenated vector. Vector can fit 4 int32 fields vec_int16 out_vector; // Define a output vector for PACK operation. // Vector can fit 8 int16 fields /* If there's 8 or more to convert, convert groups of 8 FP32s to 8 DL16s */ for (int i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { *(cur_output_data) = aiu_vec_round_from_fp32_inline( *(vec_float32 *)(cur_input_data), *(vec_float32 *)(cur_input_data + 1)); // Convert from fp32 with rounding cur_input_data += 2; /* bump ptr to start of next concatenated vector (8 uint32s = 32 bytes = 2 vectors) */ cur_output_data++; /* bump ptr to start of next output vector (8 shorts = 1 vector) */ } int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left to // convert if (!curnbr_fields_to_convert) // If none, return nbr_fields_to_convert; // Return, indicating all converted // If there's still some to convert, it will be 7 or less, and we should // tread carefully to avoid touching user data beyond what they said they // gave us. // Handle the 1-3 and 4-7 leftover values cases. if (curnbr_fields_to_convert >= 4) { /* If there are 4 or more, load left vector, then decide how to load partial right */ in_vector_left = *(vec_float32 *) cur_input_data++; /* Load vector with left 4 FP32 elements */ if (curnbr_fields_to_convert > 4) /* if more than 4, partially load right vector from data */ in_vector_right = (vec_float32)vec_load_len((const float *)cur_input_data, (curnbr_fields_to_convert - 4) * 4 - 1); /* Partial load right vector with proper number of FP32 elements */ else in_vector_right = (vec_float32){0, 0, 0, 0}; // Else clear right vector } else { /* Else there are less than 4 values, so partially load the left, and clear the right */ in_vector_left = (vec_float32)vec_load_len( (const float *)cur_input_data, curnbr_fields_to_convert * 4 - 1); in_vector_right = (vec_float32){0, 0, 0, 0}; } // Invoke the VCRNF out_vector = aiu_vec_round_from_fp32_inline(in_vector_left, in_vector_right); vec_store_len(out_vector, (uint16_t *)cur_output_data, curnbr_fields_to_convert * 2 - 1); // Don't need to update the cur_input_data or cur_output_data because // we're done. Also, don't need to update curnbr_fields_to_convert. return nbr_fields_to_convert; } // End fp32_to_dlf16 /*********************************************************************** * dlf16_to_fp32 * * Converts stick elements from 16 bit DLFLOAT to 32 bit Floating Point * * Input: Address of N DLFLOAT16 data elements to convert * Address to store N FP32 data elements. * Number of elements to convert (N) * Output: Number of elements that were converted * * Dependency: the number of elements to convert in this call should * not cross from one stick to another! * (i.e. 'N' must be <= 64) **********************************************************************/ uint64_t dlf16_to_fp32(uint16_t *input_data, float *output_data, uint64_t nbr_fields_to_convert) { // Set vector pointers from input/output pointers passed in. // Note: adding 1 to a vector pointer will move it ahead 16 bytes // Point to input vector followed by point to output vector data vec_int16 *cur_input_data = (vec_int16 *)input_data; // cppcheck-suppress invalidPointerCast vec_float32 *cur_output_data = (vec_float32 *)output_data; vec_int16 in_vector; /* Define a input vector for UNPACK operation. a Vector Register can fit 8 int16 fields */ vec_float32 out_vector_left; /* Define a vector to store the left four output data fields from. This will be the Left half of the result vector. Vector can fit 4 int32 fields */ vec_float32 out_vector_right; /* Define a vector to store the right four output data fields from. This will be the right half of the result vector. Vector can fit 4 int32 fields */ // If there's more than 8 to convert, convert groups of 8 FP16s to 8 DL32s for (int i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { aiu_vec_lengthen_to_fp32_inline(*(vec_int16 *)(cur_input_data), (vec_float32 *)(cur_output_data), (vec_float32 *)(cur_output_data + 1)); cur_input_data++; /* bump ptr to start of next input vector (8 shorts) */ cur_output_data += 2; /* bump ptr to start of next pair of vector (8 float32s = 32 bytes) */ } // End of for loop int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left to // convert if (!curnbr_fields_to_convert) // If none, return nbr_fields_to_convert; // Return, indicating all converted // If there's still some to convert, it will be 7 or less, and we should // tread carefully to avoid touching user data beyond what they said they // gave us. // use functions to load partial vector int curnbr_bytes_to_set = curnbr_fields_to_convert * sizeof(uint32_t); in_vector = vec_load_len((uint16_t *)cur_input_data, curnbr_fields_to_convert * sizeof(uint16_t) - 1); /* Load vector with up to 8 elements, Length is offset by 1. */ aiu_vec_lengthen_to_fp32_inline(in_vector, (vec_float32 *)&out_vector_left, (vec_float32 *)&out_vector_right); vec_store_len(out_vector_left, (uint32_t *)cur_output_data, curnbr_bytes_to_set - 1); /* Store left FP32 to output (1 to 4 values), Length is offset by 1. */ // If there's more than 4 to convert, store values 5-8 if (curnbr_fields_to_convert > 4) { curnbr_bytes_to_set -= sizeof(uint32_t) * 4; /* Reduce bytes_to_set by how many we already stored */ vec_store_len(out_vector_right, (uint32_t *)(cur_output_data + 1), curnbr_bytes_to_set - 1); /* Store right 4 FP32 to output */ } return nbr_fields_to_convert; } // End dlf16_to_fp32 /********************************************************************** * bfloat_to_dlf16 * * Converts stick elements from bfloat to 16 bit DLFLOAT by: * - extending the 16-bit bfloat to a 32-bit float (FP32) with * vector merge ops, inserting extra decimal into each value * - using aiu_vec_round_from_fp32 (vector DLFloat op) to convert * all values to DLFloat * * Input: Address of N bfloat data elements to convert * Address to store N dlfloat data elements. * Number of elements to convert (N) * Output: Number of elements that were converted * * Dependency: the number of elements to convert in this call should * not cross from one stick to another! * (i.e. 'N' must be <= 64) **********************************************************************/ uint64_t bfloat_to_dlf16(uint16_t *input_data, uint16_t *output_data, uint64_t nbr_fields_to_convert) { // Set vector pointers from input/output pointers passed in. // Note: adding 1 to a vector pointer will move it ahead 16 bytes vec_int16 *cur_input_data = (vec_int16 *)input_data; // Point to input vector data vec_int16 interim_data1; // Holds interim FP32 data vec_int16 interim_data2; // Holds interim FP32 data vec_int16 *cur_output_data = (vec_int16 *)output_data; // Point to output data vec_int16 in_vector; // Define a input vector for UNPACK operation. // a Vector Register can fit 8 int16 fields vec_int16 out_vector; // Define a vector to hold a partial output // vector. // If there's more than 8 to convert, convert groups of 8 FP16s to 8 DL32s for (int i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { // Conversion processing: Use vector merge to insert extra decimal // places into the vector, expanding the bfloat16 into an FP32, // then use our "convert and round" routine to transform to dlfloat interim_data1 = vec_mergeh(*cur_input_data, zero_vector16); interim_data2 = vec_mergel(*cur_input_data, zero_vector16); *cur_output_data = aiu_vec_round_from_fp32_inline( (vec_float32)interim_data1, (vec_float32)interim_data2); cur_input_data++; /* bump ptr to start of next input vector (8 shorts) */ cur_output_data++; /* bump ptr to start of next vector (8 short) */ } // End of for loop int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left to // convert if (!curnbr_fields_to_convert) // If none, return nbr_fields_to_convert; // Return, indicating all converted // If there's still some to convert, it will be 7 or less, and we should // tread carefully to avoid touching user data beyond what they said they // gave us. // use functions to load partial vector int curnbr_bytes_to_set = curnbr_fields_to_convert * sizeof(uint16_t); in_vector = vec_load_len((uint16_t *)cur_input_data, curnbr_fields_to_convert * sizeof(uint16_t) - 1); /* Load vector with up to 8 elements, Length is offset by 1. */ // Conversion processing: Use vector merge to insert extra decimal // places into the vector, expanding the bfloat16 into an FP32, // then use our "convert and round" routine to transform to dlfloat interim_data1 = vec_mergeh(in_vector, zero_vector16); interim_data2 = vec_mergel(in_vector, zero_vector16); out_vector = aiu_vec_round_from_fp32_inline((vec_float32)interim_data1, (vec_float32)interim_data2); // Store the vector (with 1-7 elements) using a computed length to // ensure an exact fit. vec_store_len(out_vector, (uint16_t *)cur_output_data, curnbr_bytes_to_set - 1); /* Store left bfloat to output (1 to 4 values), Length is offset by 1. */ return nbr_fields_to_convert; } // End bfloat_to_dlf16 /*********************************************************************** * dlf16_to_bfloat * * Converts stick elements from 16 bit DLFLOAT to BFLOAT by: * - using aiu_vec_lengthen_to_fp32 (vector DLFloat op) to convert * all values to FP32 * - Truncate the 32-bit float (FP32) to a 16-bit BFLOAT with * vector permute ops, selecting which bytes of each 32-bit value * to keep, discarding the rest * * Input: Address of N DLFLOAT16 data elements to convert * Address to store N bfloat data elements. * Number of elements to convert (N) * Output: Number of elements that were converted * * Dependency: the number of elements to convert in this call should * not cross from one stick to another! * (i.e. 'N' must be <= 64) **********************************************************************/ uint64_t dlf16_to_bfloat(uint16_t *input_data, uint16_t *output_data, uint64_t nbr_fields_to_convert) { // Set vector pointers from input/output pointers passed in. // Note: adding 1 to a vector pointer will move it ahead 16 bytes vec_int16 *cur_input_data = (vec_int16 *)input_data; // Point to input vector data vec_int16 *cur_output_data = (vec_int16 *)output_data; // Point to output data vec_float32 interim_data1; // Holds interim FP32 data vec_float32 interim_data2; // Holds interim FP32 data vec_int16 in_vector; // Define a input vector for UNPACK operation. // a Vector Register can fit 8 int16 fields vec_int16 out_vector; // Define a vector to store the partial output // data fields. // If there's more than 8 to convert, convert groups of 8 FP16s to 8 DL32s for (int i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { // Conversion processing: Use our "convert and lengthen" routine to // transform the DLFloat to FP32, then use vector permute to select // which bytes to keep (e.g. the two high order bytes of each FP32), // further transforming our FP32 elements into BFLOAT. aiu_vec_lengthen_to_fp32_inline(*(vec_int16 *)(cur_input_data), (vec_float32 *)&interim_data1, (vec_float32 *)&interim_data2); *cur_output_data = (vec_int16)vec_perm( (vec_char8)interim_data1, (vec_char8)interim_data2, selection_vector); cur_input_data++; /* bump ptr to start of next input vector (8 shorts) */ cur_output_data++; /* bump ptr to start of next output vector (8 shorts) */ } // End of for loop int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left to // convert if (!curnbr_fields_to_convert) // If none, return nbr_fields_to_convert; // Return, indicating all converted // If there's still some to convert, it will be 7 or less, and we should // tread carefully to avoid touching user data beyond what they said they // gave us. // use functions to load partial vector in_vector = vec_load_len((uint16_t *)cur_input_data, curnbr_fields_to_convert * sizeof(uint16_t) - 1); /* Load vector with up to 8 elements, Length is offset by 1. */ // Conversion processing: Use our "convert and lengthen" routine to // transform the DLFloat to FP32, then use vector permute to select // which bytes to keep (e.g. the two high order bytes of each FP32), // further transforming our FP32 elements into BFLOAT. aiu_vec_lengthen_to_fp32_inline(in_vector, (vec_float32 *)&interim_data1, (vec_float32 *)&interim_data2); out_vector = (vec_int16)vec_perm((vec_char8)interim_data1, (vec_char8)interim_data2, selection_vector); vec_store_len(out_vector, (uint16_t *)cur_output_data, (curnbr_fields_to_convert * sizeof(uint16_t)) - 1); /* Store left bfloat to output (1 to 4 values), Length is offset by 1. */ return nbr_fields_to_convert; } // End dlf16_to_bfloat /*********************************************************************** * fp16_to_dlf16_in_stride * * Converts N 16-bit Floating Point to 16-bit DLFLOAT stick elements, * gathering the elements from a "strided" input in the user's buffer, * storing into contiguous elements in a stick * * Input: Address of N FP16 data elements to gather and convert * Address to store N DLFLOAT16 data elements. * Number of elements to convert (N) * Output: Number of elements that were converted * * Dependency: the number of elements to convert in this call should * not cross from one stick to another! * (i.e. 'N' must be <= 64) **********************************************************************/ uint64_t fp16_to_dlf16_in_stride(uint16_t *fp16_data, uint16_t *dflt16_data, uint64_t nbr_fields_to_convert, uint32_t input_stride) { float_bit16 gathered_data[STICKCVT_MAX_ENTRIES_TO_CONVERT] = {0}; vec_int16 *gathered_vector = (vec_int16 *)&gathered_data; float_bit16 *cur_fp16_data = fp16_data; vec_int16 *cur_dflt16_data = (vec_int16 *)dflt16_data; for (uint64_t i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { // Gather values from across sticks for (int j = 0; j < STICKCVT_MAX_ENTRIES_TO_CONVERT; ++j) { gathered_data[j] = *cur_fp16_data; cur_fp16_data += input_stride; } // Convert the values *(vec_int16 *)(cur_dflt16_data) = aiu_vec_convert_from_fp16_inline( *(vec_int16 *)gathered_vector); /* Convert gathered values directly to user tensor buffer */ cur_dflt16_data += 1; // bump ptr to next target area (16 bytes) } int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left // to convert if (!curnbr_fields_to_convert) return nbr_fields_to_convert; else { vec_int16 aiu_op_output; // temp area for partial vector output // Gather values from across sticks for (int j = 0; j < (curnbr_fields_to_convert); ++j) { gathered_data[j] = *cur_fp16_data; cur_fp16_data += input_stride; } // Convert the values aiu_op_output = aiu_vec_convert_from_fp16_inline(*(vec_int16 *)(&gathered_data)); // Copy remaining values to user tensor area memcpy(cur_dflt16_data, &aiu_op_output, (sizeof(uint16_t) * (curnbr_fields_to_convert))); } return nbr_fields_to_convert; } // End fp16_to_dlf16_in_stride /*********************************************************************** * fp32_to_dlf16_in_stride * * Converts N 32-bit Floating Point to 16-bit DLFLOAT stick elements, * gathering the elements from a "strided" input across multiple sticks, * storing into contiguous elements in a stick * * Input: Address of N FP32 data elements to gather and convert * Address to store N DLFLOAT16 data elements. * Number of elements to convert (N) * Output: Number of elements that were converted * * Dependency: the number of elements to convert in this call should * not cross from one stick to another! * (i.e. 'N' must be <= 64) **********************************************************************/ uint64_t fp32_to_dlf16_in_stride(float *fp32_data, uint16_t *dflt16_data, uint64_t nbr_fields_to_convert, uint32_t input_stride) { float_bit32 gathered_data[STICKCVT_MAX_ENTRIES_TO_CONVERT] = { 0}; /* define an array */ vec_float32 *gathered_vector = (vec_float32 *)&gathered_data; /* redefine the same array storage as a vector */ // cppcheck-suppress invalidPointerCast float_bit32 *cur_fp32_data = &(*(float_bit32 *)fp32_data); vec_int16 *cur_dflt16_data = (vec_int16 *)dflt16_data; for (uint64_t i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { // Gather values from across sticks for (int j = 0; j < STICKCVT_MAX_ENTRIES_TO_CONVERT; ++j) { gathered_data[j] = *cur_fp32_data; cur_fp32_data += input_stride; } // Convert the values *(vec_int16 *)(cur_dflt16_data) = aiu_vec_round_from_fp32_inline( *(vec_float32 *)(gathered_vector), *(vec_float32 *)(gathered_vector + 1)); /* Convert gathered values directly to stick ztensor buffer */ cur_dflt16_data += 1; // bump ptr to next target area (16 bytes) } int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left // to convert if (!curnbr_fields_to_convert) return nbr_fields_to_convert; else { vec_int16 aiu_op_output; // temp area for partial vector output // Gather values from across sticks for (int j = 0; j < (curnbr_fields_to_convert); ++j) { gathered_data[j] = *cur_fp32_data; cur_fp32_data += input_stride; } // Convert the values aiu_op_output = aiu_vec_round_from_fp32_inline( *(vec_float32 *)(gathered_vector), *(vec_float32 *)(gathered_vector + 1)); /* Convert gathered values directly to stick ztensor buffer */ // Copy remaining values to user tensor area memcpy(cur_dflt16_data, &aiu_op_output, (sizeof(uint16_t) * (curnbr_fields_to_convert))); } return nbr_fields_to_convert; } // End fp32_to_dlf16_in_stride /*********************************************************************** * bfloat_to_dlf16_in_stride * * Converts N 16-bit BFLOAT values to 16-bit DLFLOAT stick elements, * gathering the elements from a "strided" input across multiple sticks, * storing into contiguous elements in a stick * * Input: Address of N BFLOAT data elements to gather and convert * Address to store N DLFLOAT16 data elements. * Number of elements to convert (N) * Output: Number of elements that were converted * * Dependency: the number of elements to convert in this call should * not cross from one stick to another! * (i.e. 'N' must be <= 64) **********************************************************************/ uint64_t bfloat_to_dlf16_in_stride(uint16_t *bflt_data, uint16_t *dflt16_data, uint64_t nbr_fields_to_convert, uint32_t input_stride) { float_bit16 gathered_data[STICKCVT_MAX_ENTRIES_TO_CONVERT] = {0}; /* define an array */ vec_int16 *gathered_vector = (vec_int16 *)&gathered_data; /* redefine the same array storage as a vector */ vec_float32 interim_data1; // Holds interim FP32 data vec_float32 interim_data2; // Holds interim FP32 data float_bit16 *cur_bflt_data = bflt_data; vec_int16 *cur_dflt16_data = (vec_int16 *)dflt16_data; for (uint64_t i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { // Gather values from across sticks for (int j = 0; j < STICKCVT_MAX_ENTRIES_TO_CONVERT; ++j) { gathered_data[j] = *cur_bflt_data; cur_bflt_data += input_stride; } // Conversion processing: Use vector merge to insert extra decimal // places into the vector, expanding the bfloat16 into an FP32, // then use our "convert and round" routine to transform to dlfloat interim_data1 = (vec_float32)vec_mergeh(*gathered_vector, zero_vector16); interim_data2 = (vec_float32)vec_mergel(*gathered_vector, zero_vector16); *cur_dflt16_data = aiu_vec_round_from_fp32_inline( (vec_float32)interim_data1, (vec_float32)interim_data2); /* Convert gathered values directly to user tensor buffer */ cur_dflt16_data += 1; // bump ptr to next target area (16 bytes) } int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left // to convert if (!curnbr_fields_to_convert) return nbr_fields_to_convert; else { vec_int16 aiu_op_output; // temp area for partial vector output // Gather values from across sticks for (int j = 0; j < (curnbr_fields_to_convert); ++j) { gathered_data[j] = *cur_bflt_data; cur_bflt_data += input_stride; } // Conversion processing: Use vector merge to insert extra decimal // places into the vector, expanding the bfloat16 into an FP32, // then use our "convert and round" routine to transform to dlfloat interim_data1 = (vec_float32)vec_mergeh(*gathered_vector, zero_vector16); interim_data2 = (vec_float32)vec_mergel(*gathered_vector, zero_vector16); aiu_op_output = aiu_vec_round_from_fp32_inline((vec_float32)interim_data1, (vec_float32)interim_data2); // Copy remaining values to user tensor area memcpy(cur_dflt16_data, &aiu_op_output, (sizeof(uint16_t) * (curnbr_fields_to_convert))); } return nbr_fields_to_convert; } // End bfloat_to_dlf16_in_stride /*********************************************************************** * dlf16_to_fp16_in_stride * * Converts N 16-bit DLFLOAT elements from across multiple sticks * to 16 bit Floating Point, storing them contiguously in the * user's data area * * Input: Address of N DLFLOAT16 data elements to convert * Address to store N FP16 data elements. * Number of elements to convert (N) * Length of the element stride arcoss sticks * Output: Number of elements that were converted * * Assumption: Caller will provide a stride value that allows us * to gather discontiguous values from the sticks and store * in contiguous output values in the user's data area. * The 'N' is not required to be <= 64, because the input * data area to be converted is taken from the same * relative position within each stick, and contiguously * written to the users data area, which is not stickified. **********************************************************************/ uint64_t dlf16_to_fp16_in_stride(uint16_t *dflt16_data, uint16_t *fp16_data, uint64_t nbr_fields_to_convert, uint32_t input_stride) { float_bit16 gathered_data[STICKCVT_MAX_ENTRIES_TO_CONVERT] = {0}; vec_int16 *gathered_vector = (vec_int16 *)&gathered_data; float_bit16 *cur_dflt16_data = dflt16_data; vec_int16 *cur_fp16_data = (vec_int16 *)fp16_data; for (uint64_t i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { // Gather values from across sticks for (int j = 0; j < STICKCVT_MAX_ENTRIES_TO_CONVERT; ++j) { gathered_data[j] = *cur_dflt16_data; cur_dflt16_data += input_stride; } // Convert the values *(vec_int16 *)(cur_fp16_data) = aiu_vec_convert_to_fp16_inline( *(vec_int16 *)gathered_vector); /* Convert gathered values directly to user tensor buffer */ cur_fp16_data += 1; // bump ptr to next target area (16 bytes) } int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left // to convert if (!curnbr_fields_to_convert) return nbr_fields_to_convert; else { vec_int16 aiu_op_output; // temp area for partial vector output // Gather values from across sticks for (int j = 0; j < (curnbr_fields_to_convert); ++j) { gathered_data[j] = *cur_dflt16_data; cur_dflt16_data += input_stride; } // Convert the values aiu_op_output = aiu_vec_convert_to_fp16_inline(*(vec_int16 *)(&gathered_data)); // Copy remaining values to user tensor area memcpy(cur_fp16_data, &aiu_op_output, (sizeof(uint16_t) * (curnbr_fields_to_convert))); } return nbr_fields_to_convert; } // End dlf16_to_fp16_in_stride /*********************************************************************** * dlf16_to_fp32_in_stride * * Converts N 16-bit DLFLOAT elements from across multiple sticks * to 32 bit Floating Point, storing them contiguously in the * user's data area * * Input: Address of N DLFLOAT16 data elements to convert * Address to store N FP32 data elements. * Number of elements to convert (N) * Length of the element stride arcoss sticks * Output: Number of elements that were converted * * Assumption: Caller will provide a stride value that allows us * to gather discontiguous values from the sticks and store * in contiguous output values in the user's data area. * The 'N' is not required to be <= 64, because the input * data area to be converted is taken from the same * relative position within each stick, and contiguously * written to the users data area, which is not stickified. **********************************************************************/ uint64_t dlf16_to_fp32_in_stride(uint16_t *dflt16_data, float *fp32_data, uint64_t nbr_fields_to_convert, uint32_t input_stride) { float_bit16 gathered_data[STICKCVT_MAX_ENTRIES_TO_CONVERT] = {0}; float_bit16 *cur_dflt16_data = dflt16_data; // cppcheck-suppress invalidPointerCast float_bit32 *cur_fp32_data = (float_bit32 *)fp32_data; for (uint64_t i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { // Gather values from across sticks for (int j = 0; j < STICKCVT_MAX_ENTRIES_TO_CONVERT; ++j) { gathered_data[j] = *cur_dflt16_data; cur_dflt16_data += input_stride; } // Convert the values aiu_vec_lengthen_to_fp32_inline( *(vec_int16 *)(&gathered_data), (vec_float32 *)(cur_fp32_data), (vec_float32 *)(cur_fp32_data + 4)); /* Convert gathered values directly into user tensor buffer */ cur_fp32_data += STICKCVT_MAX_ENTRIES_TO_CONVERT; // bump ptr to next target // area (32 bytes) } int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left // to convert if (!curnbr_fields_to_convert) return nbr_fields_to_convert; else { vec_float32 aiu_op_output[2]; // temp area for partial vector output // Gather values from across sticks for (int j = 0; j < (curnbr_fields_to_convert); ++j) { gathered_data[j] = *cur_dflt16_data; cur_dflt16_data += input_stride; } // Convert the values aiu_vec_lengthen_to_fp32_inline(*(vec_int16 *)(&gathered_data), (&aiu_op_output[0]), (&aiu_op_output[1])); // Copy remaining values to user tensor area memcpy(cur_fp32_data, &aiu_op_output[0], (sizeof(uint32_t) * curnbr_fields_to_convert)); } return nbr_fields_to_convert; } // End dlf16_to_fp32_in_stride /*********************************************************************** * dlf16_to_bfloat_in_stride * * Converts N 16-bit DLFLOAT elements from across multiple sticks * to 16 bit Floating Point (bfloat), storing them contiguously in the * user's data area * * Input: Address of N DLFLOAT16 data elements to convert * Address to store N bfloat data elements. * Number of elements to convert (N) * Length of the element stride arcoss sticks * Output: Number of elements that were converted * * Assumption: Caller will provide a stride value that allows us * to gather discontiguous values from the sticks and store * in contiguous output values in the user's data area. * The 'N' is not required to be <= 64, because the input * data area to be converted is taken from the same * relative position within each stick, and contiguously * written to the users data area, which is not stickified. **********************************************************************/ uint64_t dlf16_to_bfloat_in_stride(uint16_t *dflt16_data, uint16_t *bflt_data, uint64_t nbr_fields_to_convert, uint32_t input_stride) { float_bit16 gathered_data[STICKCVT_MAX_ENTRIES_TO_CONVERT] = {0}; vec_int16 *gathered_vector = (vec_int16 *)&gathered_data; vec_float32 interim_data1; // Holds interim FP32 data vec_float32 interim_data2; // Holds interim FP32 data float_bit16 *cur_dflt16_data = dflt16_data; vec_int16 *cur_bflt_data = (vec_int16 *)bflt_data; for (uint64_t i = 0; i < nbr_fields_to_convert / STICKCVT_MAX_ENTRIES_TO_CONVERT; ++i) { // Gather values from across sticks for (int j = 0; j < STICKCVT_MAX_ENTRIES_TO_CONVERT; ++j) { gathered_data[j] = *cur_dflt16_data; cur_dflt16_data += input_stride; } // Conversion processing: Use our "convert and lengthen" routine to // transform the DLFloat to FP32, then use vector permute to select // which bytes to keep (e.g. the two high order bytes of each FP32), // further transforming our FP32 elements into BFLOAT. aiu_vec_lengthen_to_fp32_inline(*(vec_int16 *)(gathered_vector), (vec_float32 *)&interim_data1, (vec_float32 *)&interim_data2); *cur_bflt_data = (vec_int16)vec_perm( (vec_char8)interim_data1, (vec_char8)interim_data2, selection_vector); cur_bflt_data += 1; // bump ptr to next target area (16 bytes) } int curnbr_fields_to_convert = nbr_fields_to_convert % STICKCVT_MAX_ENTRIES_TO_CONVERT; // Determine # fields left // to convert if (!curnbr_fields_to_convert) // If none, return nbr_fields_to_convert; // Return, indicating all converted else { vec_int16 aiu_op_output; // temp area for partial vector output // Gather values from across sticks for (int j = 0; j < (curnbr_fields_to_convert); ++j) { gathered_data[j] = *cur_dflt16_data; cur_dflt16_data += input_stride; } // Conversion processing: Use our "convert and lengthen" routine to // transform the DLFloat to FP32, then use vector permute to select // which bytes to keep (e.g. the two high order bytes of each FP32), // further transforming our FP32 elements into BFLOAT. aiu_vec_lengthen_to_fp32_inline(*(vec_int16 *)(gathered_vector), (vec_float32 *)&interim_data1, (vec_float32 *)&interim_data2); aiu_op_output = (vec_int16)vec_perm( (vec_char8)interim_data1, (vec_char8)interim_data2, selection_vector); memcpy(cur_bflt_data, &aiu_op_output, (sizeof(uint16_t) * curnbr_fields_to_convert)); } return nbr_fields_to_convert; } // End dlf16_to_bfloat_in_stride ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/get.c�������������������������������������������������������������������������������0000664�0000000�0000000�00000033554�14364043643�0014237�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ // SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #ifdef __MVS__ #pragma export(zdnn_get_library_version_str) #pragma export(zdnn_get_library_version) #endif #define DECLARE_DATA_LAYOUT_STR(a) static const char *DATA_LAYOUT_STR_##a = #a; // const char *DATA_LAYOUT_STR_X DECLARE_DATA_LAYOUT_STR(ZDNN_1D) DECLARE_DATA_LAYOUT_STR(ZDNN_2D) DECLARE_DATA_LAYOUT_STR(ZDNN_2DS) DECLARE_DATA_LAYOUT_STR(ZDNN_3D) DECLARE_DATA_LAYOUT_STR(ZDNN_3DS) DECLARE_DATA_LAYOUT_STR(ZDNN_ZRH) DECLARE_DATA_LAYOUT_STR(ZDNN_4D) DECLARE_DATA_LAYOUT_STR(ZDNN_4DS) DECLARE_DATA_LAYOUT_STR(ZDNN_NHWC) DECLARE_DATA_LAYOUT_STR(ZDNN_NCHW) DECLARE_DATA_LAYOUT_STR(ZDNN_FICO) DECLARE_DATA_LAYOUT_STR(ZDNN_HWCK) DECLARE_DATA_LAYOUT_STR(ZDNN_BIDIR_ZRH) DECLARE_DATA_LAYOUT_STR(ZDNN_BIDIR_FICO) #define DECLARE_DATA_FORMAT_STR(a) static const char *DATA_FORMAT_STR_##a = #a; // const char *DATA_FORMAT_STR_X DECLARE_DATA_FORMAT_STR(ZDNN_FORMAT_4DFEATURE) DECLARE_DATA_FORMAT_STR(ZDNN_FORMAT_4DKERNEL) #define DECLARE_DATA_TYPE_STR(a) static const char *DATA_TYPE_STR_##a = #a; // const char *DATA_TYPE_STR_X DECLARE_DATA_TYPE_STR(BFLOAT) DECLARE_DATA_TYPE_STR(FP16) DECLARE_DATA_TYPE_STR(FP32) DECLARE_DATA_TYPE_STR(ZDNN_DLFLOAT16) #define DECLARE_RNN_DIR_STR(a) static const char *RNN_DIR_STR_##a = #a; // const char *RNN_DIR_STR_X DECLARE_RNN_DIR_STR(FWD) DECLARE_RNN_DIR_STR(BWD) DECLARE_RNN_DIR_STR(BIDIR) #define DECLARE_SOFTMAX_ACT_STR(a) static const char *SOFTMAX_ACT_STR_##a = #a; // const char *SOFTMAX_ACT_STR_X DECLARE_SOFTMAX_ACT_STR(SOFTMAX_ACT_NONE) DECLARE_SOFTMAX_ACT_STR(SOFTMAX_ACT_LOG) #define DECLARE_MATMUL_OP_STR(a) static const char *MATMUL_OP_STR_##a = #a; // const char *MATMUL_OP_STR_X DECLARE_MATMUL_OP_STR(MATMUL_OP_ADDITION); DECLARE_MATMUL_OP_STR(MATMUL_OP_GREATER); DECLARE_MATMUL_OP_STR(MATMUL_OP_GREATER_EQUAL); DECLARE_MATMUL_OP_STR(MATMUL_OP_EQUAL); DECLARE_MATMUL_OP_STR(MATMUL_OP_NOT_EQUAL); DECLARE_MATMUL_OP_STR(MATMUL_OP_LESSER_EQUAL); DECLARE_MATMUL_OP_STR(MATMUL_OP_LESSER); #define DECLARE_MATMUL_BCAST_OP_STR(a) \ static const char *MATMUL_BCAST_OP_STR_##a = #a; // const char *MATMUL_BCAST_OP_STR_X DECLARE_MATMUL_BCAST_OP_STR(MATMUL_BCAST_OP_ADDITION); #define DECLARE_POOL_PADDING_STR(a) \ static const char *POOL_PADDING_STR_##a = #a; // const char *POOL_PADDING_STR_X DECLARE_POOL_PADDING_STR(SAME_PADDING) DECLARE_POOL_PADDING_STR(VALID_PADDING) #define DECLARE_CONV2D_ACT_STR(a) static const char *CONV2D_ACT_STR_##a = #a; // const char *CONV2D_ACT_STR_X DECLARE_CONV2D_ACT_STR(CONV2D_ACT_NONE) DECLARE_CONV2D_ACT_STR(CONV2D_ACT_RELU) static const char *UNDEFINED_STR = "UNDEFINED"; /// Returns number of dimension of a layout /// /// \param[in] layout tensor layout, must be a non-concatenated layout /// /// \return number of dimensions, or 0 if concatenated or no such layout exists /// short get_data_layout_dims(zdnn_data_layouts layout) { #define CASE_RTN_DIM(a, b) \ case a: \ return b; switch (layout) { CASE_RTN_DIM(ZDNN_1D, 1); CASE_RTN_DIM(ZDNN_2D, 2); CASE_RTN_DIM(ZDNN_2DS, 2); CASE_RTN_DIM(ZDNN_3D, 3); CASE_RTN_DIM(ZDNN_3DS, 3); CASE_RTN_DIM(ZDNN_4D, 4); CASE_RTN_DIM(ZDNN_4DS, 4); CASE_RTN_DIM(ZDNN_NHWC, 4); CASE_RTN_DIM(ZDNN_NCHW, 4); CASE_RTN_DIM(ZDNN_HWCK, 4); default: LOG_WARN("Unknown or concatenated layout: %d", layout); return 0; } #undef CASE_RTN_DIM } /// Returns number of gates of a concatenated layout /// /// \param[in] layout data layout, must be a concatenated layout /// /// \return number of gates, or 0 if not concatenated or no such layout exists /// short get_data_layout_num_gates(zdnn_data_layouts layout) { #define CASE_RTN_GATES(a, b) \ case a: \ return b; switch (layout) { CASE_RTN_GATES(ZDNN_ZRH, 3); CASE_RTN_GATES(ZDNN_FICO, 4); CASE_RTN_GATES(ZDNN_BIDIR_ZRH, 3); CASE_RTN_GATES(ZDNN_BIDIR_FICO, 4); default: LOG_WARN("Unknown or not concatenated layout: %d", layout); return 0; } #undef CASE_RTN_GATES } /// Returns concatenated dim1 value based on concatenation info /// /// \param val incoming dim1 value /// \param info concatenation info /// /// \returns concatenated dim1 value /// uint32_t get_rnn_concatenated_dim1(uint32_t val, zdnn_concat_info info) { if (CONCAT_RNN_TYPE(info) == RNN_TYPE_LSTM) { return PADDED(val) * 4; } else if (CONCAT_RNN_TYPE(info) == RNN_TYPE_GRU) { return PADDED(val) * 3; } else { return val; } } /// Returns concatenated dim2 value based on concatenation info /// /// \param val incoming dim2 value /// \param info concatenation info /// /// \returns concatenated dim2 value /// uint32_t get_rnn_concatenated_dim2(uint32_t val, zdnn_concat_info info) { // the only case we need vertical concatenation is when a weight tensor is // used with bidir output from the previous layer. if (CONCAT_USAGE(info) == USAGE_WEIGHTS && CONCAT_PREV_LAYER(info) == PREV_LAYER_BIDIR) { return PADDED(val / 2) * 2; } else { return val; } } /// Returns number of gates, based on RNN function code /// /// \param[in] func_code NNPA function code, in zdnn_nnpa_function_code enum /// /// \return number of gates, or 0 if function code is not RNN related /// short get_func_code_num_gates(nnpa_function_code func_code) { #define CASE_RTN_GATES(a, b) \ case a: \ return get_data_layout_num_gates(b); // piggyback thus no need to hardcode switch (func_code) { CASE_RTN_GATES(NNPA_LSTMACT, ZDNN_FICO); CASE_RTN_GATES(NNPA_GRUACT, ZDNN_ZRH); default: LOG_WARN("Unknown or not RNN related function code : %d", func_code); return 0; } #undef CASE_RTN_GATES } /// Returns string representation of the layout /// /// \param[in] layout tensor layout /// /// \return string representation of the layout, or UNDEFINED_STR if no such /// layout exists /// const char *get_data_layout_str(zdnn_data_layouts layout) { #define CASE_RTN_STR(a) \ case a: \ return DATA_LAYOUT_STR_##a; switch (layout) { CASE_RTN_STR(ZDNN_1D); CASE_RTN_STR(ZDNN_2D); CASE_RTN_STR(ZDNN_2DS); CASE_RTN_STR(ZDNN_3D); CASE_RTN_STR(ZDNN_3DS); CASE_RTN_STR(ZDNN_ZRH); CASE_RTN_STR(ZDNN_4D); CASE_RTN_STR(ZDNN_4DS); CASE_RTN_STR(ZDNN_NHWC); CASE_RTN_STR(ZDNN_NCHW); CASE_RTN_STR(ZDNN_FICO); CASE_RTN_STR(ZDNN_HWCK); CASE_RTN_STR(ZDNN_BIDIR_ZRH); CASE_RTN_STR(ZDNN_BIDIR_FICO); default: LOG_WARN("Unknown layout: %d", layout); return UNDEFINED_STR; } #undef CASE_RTN_STR } /// Returns string representation of the format /// /// \param[in] layout tensor format /// /// \return string representation of the format, or UNDEFINED_STR if no such /// layout exists /// const char *get_data_format_str(zdnn_data_formats format) { #define CASE_RTN_STR(a) \ case a: \ return DATA_FORMAT_STR_##a; switch (format) { CASE_RTN_STR(ZDNN_FORMAT_4DFEATURE); CASE_RTN_STR(ZDNN_FORMAT_4DKERNEL); default: LOG_WARN("Unknown format: %d", format); return UNDEFINED_STR; } #undef CASE_RTN_STR } /// Returns number of bytes of a data type /// /// \param[in] type data type /// /// \return size in number of bytes, or 0 if no such data type exists /// short get_data_type_size(zdnn_data_types type) { #define CASE_RTN_SIZE(a, b) \ case a: \ return b; switch (type) { CASE_RTN_SIZE(BFLOAT, 2); CASE_RTN_SIZE(FP16, 2); CASE_RTN_SIZE(FP32, 4); CASE_RTN_SIZE(ZDNN_DLFLOAT16, 2); default: LOG_WARN("Unknown data type: %d", type); return 0; } #undef CASE_RTN_SIZE } /// Returns string representation of the data type /// /// \param[in] type tensor data type /// /// \return string representation of the data type, or UNDEFINED_STR if no such /// data type exists /// const char *get_data_type_str(zdnn_data_types type) { #define CASE_RTN_STR(a) \ case a: \ return DATA_TYPE_STR_##a; switch (type) { CASE_RTN_STR(BFLOAT); CASE_RTN_STR(FP16); CASE_RTN_STR(FP32); CASE_RTN_STR(ZDNN_DLFLOAT16); default: LOG_WARN("Unknown data type: %d", type); return UNDEFINED_STR; } #undef CASE_RTN_STR } /// Returns string representation of the RNN direction /// /// \param[in] dir direction /// /// \return string representation of the direction, or UNDEFINED_STR if no such /// direction exists /// const char *get_rnn_direction_str(lstm_gru_direction dir) { #define CASE_RTN_STR(a) \ case a: \ return RNN_DIR_STR_##a; switch (dir) { CASE_RTN_STR(FWD); CASE_RTN_STR(BWD); CASE_RTN_STR(BIDIR); default: LOG_WARN("Unknown direction: %d", dir); return UNDEFINED_STR; } #undef CASE_RTN_STR } /// Returns string representation of the softmax activation function /// /// \param[in] func activation function /// /// \return string representation of the activation function, or UNDEFINED_STR /// if no such activation function exists /// const char *get_softmax_act_str(zdnn_softmax_act func) { #define CASE_RTN_STR(a) \ case a: \ return SOFTMAX_ACT_STR_##a; switch (func) { CASE_RTN_STR(SOFTMAX_ACT_NONE); CASE_RTN_STR(SOFTMAX_ACT_LOG); default: LOG_WARN("Unknown activation function: %d", func); return UNDEFINED_STR; } #undef CASE_RTN_STR } /// Returns string representation of the matmul operation /// /// \param[in] op operation /// /// \return string representation of the operation, or UNDEFINED_STR /// if no such operation exists /// const char *get_matmul_op_str(zdnn_matmul_ops op) { #define CASE_RTN_STR(a) \ case a: \ return MATMUL_OP_STR_##a; switch (op) { CASE_RTN_STR(MATMUL_OP_ADDITION); CASE_RTN_STR(MATMUL_OP_GREATER); CASE_RTN_STR(MATMUL_OP_GREATER_EQUAL); CASE_RTN_STR(MATMUL_OP_EQUAL); CASE_RTN_STR(MATMUL_OP_NOT_EQUAL); CASE_RTN_STR(MATMUL_OP_LESSER_EQUAL); CASE_RTN_STR(MATMUL_OP_LESSER); default: LOG_WARN("Unknown operation: %d", op); return UNDEFINED_STR; } #undef CASE_RTN_STR } /// Returns string representation of the matmul bcast operation /// /// \param[in] op operation /// /// \return string representation of the operation, or UNDEFINED_STR /// if no such operation exists /// const char *get_matmul_bcast_op_str(zdnn_matmul_bcast_ops op) { #define CASE_RTN_STR(a) \ case a: \ return MATMUL_BCAST_OP_STR_##a; switch (op) { CASE_RTN_STR(MATMUL_BCAST_OP_ADDITION); default: LOG_WARN("Unknown operation: %d", op); return UNDEFINED_STR; } #undef CASE_RTN_STR } /// Returns string representation of the pool padding type /// /// \param[in] pad padding /// /// \return string representation of the pool padding, or UNDEFINED_STR if no /// such padding exists /// const char *get_pool_padding_str(zdnn_pool_padding pad) { #define CASE_RTN_STR(a) \ case a: \ return POOL_PADDING_STR_##a; switch (pad) { CASE_RTN_STR(SAME_PADDING); CASE_RTN_STR(VALID_PADDING); default: LOG_WARN("Unknown pool padding: %d", pad); return UNDEFINED_STR; } #undef CASE_RTN_STR } /// Returns string representation of the conv2d activation function /// /// \param[in] func activation function /// /// \return string representation of the activation function, or UNDEFINED_STR /// if no such activation function exists /// const char *get_conv2d_act_str(zdnn_conv2d_act func) { #define CASE_RTN_STR(a) \ case a: \ return CONV2D_ACT_STR_##a; switch (func) { CASE_RTN_STR(CONV2D_ACT_NONE); CASE_RTN_STR(CONV2D_ACT_RELU); default: LOG_WARN("Unknown activation function: %d", func); return UNDEFINED_STR; } #undef CASE_RTN_STR } /// Retrieve library version number (ZDNN_VERNUM) /// /// \param[in] None /// /// \return ZDNN_VERNUM /// uint32_t zdnn_get_library_version() { return ZDNN_VERNUM; } /// Retrieve library version string (ZDNN_VERSION) /// /// \param[in] None /// /// \return string pointer containing ZDNN_VERSION /// char *zdnn_get_library_version_str() { return ZDNN_VERSION; } ����������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/init_ztensor.c����������������������������������������������������������������������0000664�0000000�0000000�00000004615�14364043643�0016203�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <string.h> #ifdef __MVS__ #pragma export(zdnn_init_ztensor) #pragma export(zdnn_init_ztensor_with_malloc) #pragma export(zdnn_reset_ztensor) #endif /// Initialize a zTensor with the pre-transformed and transformed shape /// informations /// /// \param[in] pre_tfrmd_desc pre-transformed shape information /// \param[in] tfrmd_desc transformed shape information /// \param[out] output the zdnn_ztensor struct being initialized. /// /// \return None /// void zdnn_init_ztensor(zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc, zdnn_ztensor *output) { output->pre_transformed_desc = pre_tfrmd_desc; output->transformed_desc = tfrmd_desc; output->is_transformed = false; memset(&output->reserved, 0, sizeof(output->reserved)); } /// Reset a zTensor for reuse /// /// \param[out] ztensor the zdnn_ztensor struct being reset. /// /// \return None /// void zdnn_reset_ztensor(zdnn_ztensor *ztensor) { ztensor->is_transformed = false; } /// Convenience function for initializing a zTensor and allocating a buffer for /// storing transformed tensor data /// /// \param[in] pre_tfrmd_desc pre-transformed shape information /// \param[in] tfrmd_desc transformed shape information /// \param[out] output the zdnn_ztensor struct being initialized. /// /// \return ZDNN_OK /// ZDNN_INVALID_FORMAT /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_SHAPE /// ZDNN_ALLOCATION_FAILURE /// zdnn_status zdnn_init_ztensor_with_malloc(zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc, zdnn_ztensor *output) { zdnn_init_ztensor(pre_tfrmd_desc, tfrmd_desc, output); return zdnn_allochelper_ztensor(output); } �������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/initializer.cpp���������������������������������������������������������������������0000664�0000000�0000000�00000001602�14364043643�0016330�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ extern "C" { #include "zdnn.h" } #include <iostream> /// Invoke initializer routine(s) at DLL-load time. /// /// The class is not meant to be used or referenced explicitly. /// class Initializer { public: Initializer() { zdnn_init(); } }; static Initializer i; ������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/logger.c����������������������������������������������������������������������������0000664�0000000�0000000�00000011122�14364043643�0014722�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ // SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <stdio.h> #include <stdlib.h> #include <string.h> /// Determine if file_name is within ZDNN_LOGMODULE /// /// \param[in] file_name Pointer to file name /// /// \return true/false /// bool logmodule_matches(const char *file_name) { if (log_module[0] == '\0') { // ZDNN_LOGMODULE is never set return true; } else { // want only the filename, don't want the path const char *basename = strrchr(file_name, '/'); if (basename) { basename++; } else { basename = file_name; } return (strstr(log_module, basename) ? true : false); } } void log_error(const char *func_name, const char *file_name, int line_no, char *format, ...) { va_list argptr; va_start(argptr, format); log_message(LOGLEVEL_ERROR, func_name, file_name, line_no, format, argptr); va_end(argptr); } void log_warn(const char *func_name, const char *file_name, int line_no, char *format, ...) { va_list argptr; va_start(argptr, format); log_message(LOGLEVEL_WARN, func_name, file_name, line_no, format, argptr); va_end(argptr); } void log_info(const char *func_name, const char *file_name, int line_no, char *format, ...) { va_list argptr; va_start(argptr, format); log_message(LOGLEVEL_INFO, func_name, file_name, line_no, format, argptr); va_end(argptr); } void log_debug(const char *func_name, const char *file_name, int line_no, char *format, ...) { va_list argptr; va_start(argptr, format); log_message(LOGLEVEL_DEBUG, func_name, file_name, line_no, format, argptr); va_end(argptr); } void log_trace(const char *func_name, const char *file_name, int line_no, char *format, ...) { va_list argptr; va_start(argptr, format); log_message(LOGLEVEL_TRACE, func_name, file_name, line_no, format, argptr); va_end(argptr); } void log_fatal(const char *func_name, const char *file_name, int line_no, char *format, ...) { va_list argptr; va_start(argptr, format); log_message(LOGLEVEL_FATAL, func_name, file_name, line_no, format, argptr); va_end(argptr); } #define LOG_BUFFER_LEN 512 // max length of entire log message #define LOG_HEADER_LEN 96 // max length of header within the message #define LOG_HEADER "%s: %s() (%s:%d): " // level, __func__, __FILE__, __LINE /// Log message to STDOUT/STDERR /// /// \param[in] lvl Message's LOGLEVEL /// \param[in] func_name Calling module's function name /// \param[in] file_name Calling module's fila name /// \param[in] line_no Calling module's line number /// \param[in] format printf()-style format string /// \param[in] arg Variadic parameters list in va_list form /// /// /// \return None /// void log_message(log_levels lvl, const char *func_name, const char *file_name, int line_no, const char *format, va_list arg) { // when ZDNN_CONFIG_DEBUG is off, LOGLEVEL and LOGMODULE are not supported so // always execute this block of code #ifdef ZDNN_CONFIG_DEBUG BEGIN_IF_LOGLEVEL(lvl, file_name) { #endif char msg_buf[LOG_BUFFER_LEN]; FILE *stream; log_levels lvl_real = (lvl > LOGLEVEL_TRACE) ? LOGLEVEL_TRACE : lvl; char *log_levels_str[] = {"", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"}; int header_len = snprintf(msg_buf, LOG_BUFFER_LEN, LOG_HEADER, log_levels_str[lvl_real], func_name, file_name, line_no); if (arg) { vsnprintf(msg_buf + header_len, LOG_BUFFER_LEN - header_len, format, arg); } else { // nothing to format, copy it as-is strncpy(msg_buf + header_len, format, LOG_BUFFER_LEN - header_len); } if (lvl_real == LOGLEVEL_ERROR || lvl_real == LOGLEVEL_FATAL) { stream = stderr; } else { stream = stdout; } // auto '\n` the string if (msg_buf[strlen(msg_buf) - 1] == '\n') { fprintf(stream, "%s", msg_buf); } else { fprintf(stream, "%s\n", msg_buf); } #ifdef ZDNN_CONFIG_DEBUG } #endif } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/malloc4k.c��������������������������������������������������������������������������0000664�0000000�0000000�00000004413�14364043643�0015156�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <errno.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> /// malloc() that does 4k-alignment /// /// \param[in] size Size to be malloc'd /// /// \return Pointer to the malloc'd area if successful, or NULL otherwise /// void *malloc_aligned_4k(size_t size) { // request one more page + size of a pointer from the OS unsigned short extra_allocation = (AIU_PAGESIZE_IN_BYTES - 1) + sizeof(void *); // make sure size is reasonable if (!size || size > SIZE_MAX) { return NULL; } void *ptr = malloc(size + extra_allocation); if (!ptr) { perror("Error during malloc"); fprintf(stderr, "errno = %d\n", errno); return ptr; } // find the 4k boundary after ptr void *aligned_ptr = (void *)(((uintptr_t)ptr + extra_allocation) & ~(AIU_PAGESIZE_IN_BYTES - 1)); // put the original malloc'd address right before aligned_ptr ((void **)aligned_ptr)[-1] = ptr; LOG_DEBUG("malloc_aligned_4k() malloc() at %016lx, aligned at %016lx, of " "size %zu", (uintptr_t)ptr, (uintptr_t)aligned_ptr, size); return aligned_ptr; } /// free() what was allocated via malloc_aligned_4k() /// /// \param[in] ptr Pointer returned by malloc_aligned_4k() /// /// \return None /// void free_aligned_4k(void *aligned_ptr) { if (aligned_ptr) { // get the original malloc'd address from where we put it and free it void *original_ptr = ((void **)aligned_ptr)[-1]; LOG_DEBUG("free_aligned_4k() aligned_ptr = %016lx original_ptr = %016lx", (uintptr_t)aligned_ptr, (uintptr_t)original_ptr); free(original_ptr); } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/operations.c������������������������������������������������������������������������0000664�0000000�0000000�00000064127�14364043643�0015643�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "convert.h" #include "zdnn.h" #include "zdnn_private.h" #ifdef __MVS__ #pragma export(zdnn_add) #pragma export(zdnn_sub) #pragma export(zdnn_mul) #pragma export(zdnn_div) #pragma export(zdnn_min) #pragma export(zdnn_max) #pragma export(zdnn_log) #pragma export(zdnn_exp) #pragma export(zdnn_relu) #pragma export(zdnn_tanh) #pragma export(zdnn_sigmoid) #pragma export(zdnn_softmax) #pragma export(zdnn_lstm) #pragma export(zdnn_gru) #pragma export(zdnn_matmul_op) #pragma export(zdnn_matmul_bcast_op) #pragma export(zdnn_batchnorm) #pragma export(zdnn_meanreduce2d) #pragma export(zdnn_avgpool2d) #pragma export(zdnn_maxpool2d) #pragma export(zdnn_conv2d) #endif #define BEGIN_PRINT_PARMS \ printf("\n%s parameters start " \ ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", \ __func__); #define PRINT_PARM_ZTENSOR_PTR(ztnsr) print_ztensor(ztnsr, #ztnsr, false); #define PRINT_PARM_PTR(ptr) \ printf("\nParameter %s (pointer): %" PRIxPTR "\n", #ptr, (uintptr_t)ptr); #define PRINT_PARM_RNN_DIR(dir) \ printf("\nDirection: %s\n", get_rnn_direction_str(dir)); #define PRINT_PARM_FLOAT_PTR(val) \ printf("\nParameter %s (float): %f\n", #val, val); #define PRINT_PARM_UINT32T(val) \ printf("\nParameter %s (uint32_t): %u\n", #val, val); #define PRINT_PARM_UINT64T(val) \ printf("\nParameter %s (uint64_t): %" PRIu64 "\n", #val, val); #define PRINT_PARM_SOFTMAX_ACT(func) \ printf("\nSoftmax Activation Function: %s\n", get_softmax_act_str(func)); #define PRINT_PARM_MATMUL_OP(op) \ printf("\nMatmul Operation: %s\n", get_matmul_op_str(op)); #define PRINT_PARM_MATMUL_BCAST_OP(op) \ printf("\nMatmul Bcast Operation: %s\n", get_matmul_bcast_op_str(op)); #define PRINT_PARM_POOL_PADDING(pad) \ printf("\nPool padding: %s\n", get_pool_padding_str(pad)); #define PRINT_PARM_CONV2D_ACT(func) \ printf("\nConv2D Activation Function: %s\n", get_conv2d_act_str(func)); #define END_PRINT_PARMS \ printf("\n%s parameters end " \ "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", \ __func__); // ----------------------------------------------------------------------------- // External Activation Operations // ----------------------------------------------------------------------------- /// External interface for Relu operation /// /// \param[in] input The input tensor /// \param[in] clipping_value A pointer to an FP32 clipping value /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_relu(const zdnn_ztensor *input, const void *clipping_value, zdnn_ztensor *output) { // Create Function Specific Parm 1 for Relu first to optimize conditional // checks. func_sp_parm1_relu parm1; parm1.val = 0; // Create variable for parameter output. Check if value is NULL, followed by a // check if it is not 0. If it is 0 it is unnecessary to convert 0 to DLFloat // or setting clipping_value (as it is already set by val) float clip_val = 0; if (clipping_value) { clip_val = *(float *)clipping_value; if (clip_val != 0) { parm1.bits.clipping_value = cnvt_1_fp32_to_dlf16(clip_val); } } if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_FLOAT_PTR(clip_val); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } // NNPA parameter block expects: // - function-specific-parameter-1: clipping value return aiu_ops_func_specific(NNPA_RELU, input, NULL, NULL, output, NULL, 0, parm1.val, 0, 0, 0, 0); } /// External interface for Tanh operation /// /// \param[in] input The input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_tanh(const zdnn_ztensor *input, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_TANH, input, NULL, NULL, output, NULL); } /// External interface for Sigmoid operation /// /// \param[in] input The input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_sigmoid(const zdnn_ztensor *input, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_SIGMOID, input, NULL, NULL, output, NULL); } /// External interface for Softmax operation /// /// \param[in] input The input tensor /// \param[in] save_area Pointer to the save area required by NNPA_SOFTMAX /// \param[in] act_func activation function as specified in the zdnn_softmax_act /// enum /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_softmax(const zdnn_ztensor *input, void *save_area, zdnn_softmax_act act_func, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_PTR(save_area); PRINT_PARM_SOFTMAX_ACT(act_func); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } func_sp_parm1_softmax parm1; parm1.val = 0; parm1.bits.act = act_func; // NNPA parameter block expects: // - function-specific-parameter-1: ACTIVATION function return aiu_ops_func_specific(NNPA_SOFTMAX, input, NULL, NULL, output, NULL, (uintptr_t)save_area, parm1.val, 0, 0, 0, 0); } // ----------------------------------------------------------------------------- // External RNN Operations // ----------------------------------------------------------------------------- /// External interface for LSTM operation /// /// \param[in] input The input tensor /// \param[in] h0 The initial hidden state tensor /// \param[in] c0 The initial cell state tensor /// \param[in] weights The concatenated weights tensor /// \param[in] biases The concatenated biases tensor /// \param[in] hidden_weights The concatenated hidden weights tensor /// \param[in] hidden_biases The concatenated hidden biases tensor /// \param[in] direction Direction (FWD, BWD, BIDIR) /// \param[in] work_area Pointer to pre-allocated work area, or NULL /// \param[out] hn_output The output hidden_state tensor /// \param[out] cf_output The output cell_state tensor /// /// \return ZDNN_OK if all checks pass or a failure based on why it failed. /// zdnn_status zdnn_lstm(const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *c0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, void *work_area, zdnn_ztensor *hn_output, zdnn_ztensor *cf_output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_ZTENSOR_PTR(h0); PRINT_PARM_ZTENSOR_PTR(c0); PRINT_PARM_ZTENSOR_PTR(weights); PRINT_PARM_ZTENSOR_PTR(biases); PRINT_PARM_ZTENSOR_PTR(hidden_weights); PRINT_PARM_ZTENSOR_PTR(hidden_biases); PRINT_PARM_RNN_DIR(direction); PRINT_PARM_PTR(work_area); PRINT_PARM_ZTENSOR_PTR(hn_output); PRINT_PARM_ZTENSOR_PTR(cf_output); END_PRINT_PARMS; // aiu_lstm_gru() dissects the input tensors and makes multiple calls to the // AIU. check the overall input tensors here and precheck will check the // dissected tensors later before each and every AIU call zdnn_status precheck_status; if ((precheck_status = verify_zdnn_lstm_or_gru_tensors( NNPA_LSTMACT, input, h0, c0, weights, biases, hidden_weights, hidden_biases, direction, hn_output, cf_output)) != ZDNN_OK) { return precheck_status; } } return aiu_lstm_gru(NNPA_LSTMACT, input, h0, c0, weights, biases, hidden_weights, hidden_biases, direction, work_area, hn_output, cf_output); } /// External interface for GRU operation /// /// \param[in] input The input tensor /// \param[in] h0 The initial hidden state tensor /// \param[in] weights The concatenated weights tensor /// \param[in] biases The concatenated biases tensor /// \param[in] hidden_weights The concatenated hidden weights tensor /// \param[in] hidden_biases The concatenated hidden biases tensor /// \param[in] direction Direction (FWD, BWD, BIDIR) /// \param[in] work_area Pointer to pre-allocated work area, or NULL /// \param[out] hn_output The output hidden_state tensor /// /// \return ZDNN_OK if all checks pass or a failure based on why it failed. /// zdnn_status zdnn_gru(const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, void *work_area, zdnn_ztensor *hn_output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_ZTENSOR_PTR(h0); PRINT_PARM_ZTENSOR_PTR(weights); PRINT_PARM_ZTENSOR_PTR(biases); PRINT_PARM_ZTENSOR_PTR(hidden_weights); PRINT_PARM_ZTENSOR_PTR(hidden_biases); PRINT_PARM_RNN_DIR(direction); PRINT_PARM_PTR(work_area); PRINT_PARM_ZTENSOR_PTR(hn_output); END_PRINT_PARMS; // aiu_lstm_gru() dissects the input tensors and makes multiple calls to the // AIU. check the overall input tensors here and precheck will check the // dissected tensors later before the AIU calls zdnn_status precheck_status; if ((precheck_status = verify_zdnn_lstm_or_gru_tensors( NNPA_GRUACT, input, h0, NULL, weights, biases, hidden_weights, hidden_biases, direction, hn_output, NULL)) != ZDNN_OK) { return precheck_status; } } return aiu_lstm_gru(NNPA_GRUACT, input, h0, NULL, weights, biases, hidden_weights, hidden_biases, direction, work_area, hn_output, NULL); } // ----------------------------------------------------------------------------- // External Elementwise Operations // ----------------------------------------------------------------------------- /// External interface for Add operation /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_add(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input_a); PRINT_PARM_ZTENSOR_PTR(input_b); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_ADD, input_a, input_b, NULL, output, NULL); } /// External interface for Subtract operation /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_sub(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input_a); PRINT_PARM_ZTENSOR_PTR(input_b); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_SUB, input_a, input_b, NULL, output, NULL); } /// External interface for Divide operation /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_div(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input_a); PRINT_PARM_ZTENSOR_PTR(input_b); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_DIV, input_a, input_b, NULL, output, NULL); } /// External interface for Multiply operation /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_mul(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input_a); PRINT_PARM_ZTENSOR_PTR(input_b); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_MUL, input_a, input_b, NULL, output, NULL); } /// External interface for Max operation /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_max(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input_a); PRINT_PARM_ZTENSOR_PTR(input_b); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_MAX, input_a, input_b, NULL, output, NULL); } /// External interface for Min operation /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_min(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input_a); PRINT_PARM_ZTENSOR_PTR(input_b); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_MIN, input_a, input_b, NULL, output, NULL); } /// External interface for Log operation /// /// \param[in] input The input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_log(const zdnn_ztensor *input, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_LOG, input, NULL, NULL, output, NULL); } /// External interface for Exponential operation /// /// \param[in] input The input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_exp(const zdnn_ztensor *input, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_EXP, input, NULL, NULL, output, NULL); } /// External interface for Matmul operation /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[in] input_c The third input tensor /// \param[in] op_type The operation performed against matmul dot product /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_matmul_op(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, zdnn_matmul_ops op_type, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input_a); PRINT_PARM_ZTENSOR_PTR(input_b); PRINT_PARM_ZTENSOR_PTR(input_c); PRINT_PARM_MATMUL_OP(op_type); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } func_sp_parm1_matmul_op parm1; parm1.val = 0; parm1.bits.operation = op_type; // NNPA parameter block expects: // - function-specific-parameter-1: OPERATION field return aiu_ops_func_specific(NNPA_MATMUL_OP, input_a, input_b, input_c, output, NULL, 0, parm1.val, 0, 0, 0, 0); } /// External interface for Matmul Broadcast operation /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[in] input_c The third input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_matmul_bcast_op(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, zdnn_matmul_bcast_ops op_type, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input_a); PRINT_PARM_ZTENSOR_PTR(input_b); PRINT_PARM_ZTENSOR_PTR(input_c); PRINT_PARM_MATMUL_BCAST_OP(op_type); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } func_sp_parm1_matmul_bcast_op parm1; parm1.val = 0; parm1.bits.operation = op_type; // NNPA parameter block expects: // - function-specific-parameter-1: OPERATION field return aiu_ops_func_specific(NNPA_MATMUL_OP_BCAST23, input_a, input_b, input_c, output, NULL, 0, parm1.val, 0, 0, 0, 0); } // ----------------------------------------------------------------------------- // External Norm Operations // ----------------------------------------------------------------------------- /// External interface for Batch Normalization operation /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[in] input_c The third input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_batchnorm(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input_a); PRINT_PARM_ZTENSOR_PTR(input_b); PRINT_PARM_ZTENSOR_PTR(input_c); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops(NNPA_BATCHNORMALIZATION, input_a, input_b, input_c, output, NULL); } // ----------------------------------------------------------------------------- // External Pool Operations // ----------------------------------------------------------------------------- /// External interface for Average Pool 2D operation /// /// \param[in] input The input tensor /// \param[in] padding_type VALID_PADDING or SAME_PADDING /// \param[in] kernel_height height of the kernel /// \param[in] kernel_width width of the kernel /// \param[in] stride_height height movement per kernel slide /// \param[in] stride_width width movement per kernel slide /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_avgpool2d(const zdnn_ztensor *input, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_POOL_PADDING(padding_type); PRINT_PARM_UINT32T(kernel_height); PRINT_PARM_UINT32T(kernel_width); PRINT_PARM_UINT32T(stride_height); PRINT_PARM_UINT32T(stride_width); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } // The switch in arg order is intentional. The AIU op expects a different // order than our API. return aiu_ops_func_specific(NNPA_AVGPOOL2D, input, NULL, NULL, output, NULL, 0, padding_type, stride_width, stride_height, kernel_width, kernel_height); } /// External interface for Max Pool 2D operation /// /// \param[in] input The input tensor /// \param[in] padding_type VALID_PADDING or SAME_PADDING /// \param[in] kernel_height height of the kernel /// \param[in] kernel_width width of the kernel /// \param[in] stride_height height movement per kernel slide /// \param[in] stride_width width movement per kernel slide /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_maxpool2d(const zdnn_ztensor *input, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_POOL_PADDING(padding_type); PRINT_PARM_UINT32T(kernel_height); PRINT_PARM_UINT32T(kernel_width); PRINT_PARM_UINT32T(stride_height); PRINT_PARM_UINT32T(stride_width); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } // The switch in arg order is intentional. The AIU op expects a different // order than our API. return aiu_ops_func_specific(NNPA_MAXPOOL2D, input, NULL, NULL, output, NULL, 0, padding_type, stride_width, stride_height, kernel_width, kernel_height); } /// Reduces both input tensor's H and W dimensions to 1 storing a mean of /// the original dimensions' values. Issued to NNPA as a NNPA_AVGPOOL2D /// call with 0 strides. /// /// \param[in] input The input tensor /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_meanreduce2d(const zdnn_ztensor *input, zdnn_ztensor *output) { if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } return aiu_ops_func_specific( NNPA_AVGPOOL2D, input, NULL, NULL, output, NULL, 0, VALID_PADDING, 0, 0, input->transformed_desc->dim2, input->transformed_desc->dim3); } /// Preforms 2D convolution operation using input tensor and a filter kernel /// tensor, and computes the output. /// /// \param[in] input The input tensor /// \param[in] kernel The input kernel tensor /// \param[in] bias The input bias tensor /// \param[in] padding_type VALID_PADDING or SAME_PADDING /// \param[in] stride_height height movement per kernel slide /// \param[in] stride_width width movement per kernel slide /// \param[in] act_func /// activation function as specified in the zdnn_conv2d_act enum /// \param[in] clipping_value A pointer to an FP32 clipping value /// \param[out] output The output tensor /// /// \return ZDNN_OK if all checks pass. or a failure based on why it failed /// zdnn_status zdnn_conv2d(const zdnn_ztensor *input, const zdnn_ztensor *kernel, const zdnn_ztensor *bias, zdnn_pool_padding padding_type, uint32_t stride_height, uint32_t stride_width, zdnn_conv2d_act act_func, const void *clipping_value, zdnn_ztensor *output) { // Create Function Specific Parm 4 for Convolution first to optimize // conditional checks. func_sp_parm4_conv2d conv2d_parm4; conv2d_parm4.val = 0; // Create variable for parameter output. Check if value is NULL, followed by a // check if it is not 0. If it is 0 it is unnecessary to convert 0 to DLFloat // or setting clipping_value (as it is already set by val) float clip_val = 0; if (clipping_value) { clip_val = *(float *)clipping_value; if (clip_val != 0) { conv2d_parm4.bits.clipping_value = cnvt_1_fp32_to_dlf16(clip_val); } } if (precheck_enabled) { BEGIN_PRINT_PARMS; PRINT_PARM_ZTENSOR_PTR(input); PRINT_PARM_ZTENSOR_PTR(kernel); PRINT_PARM_ZTENSOR_PTR(bias); PRINT_PARM_POOL_PADDING(padding_type); PRINT_PARM_UINT32T(stride_height); PRINT_PARM_UINT32T(stride_width); PRINT_PARM_CONV2D_ACT(act_func); PRINT_PARM_FLOAT_PTR(clip_val); PRINT_PARM_ZTENSOR_PTR(output); END_PRINT_PARMS; } func_sp_parm1_conv2d conv2d_parm1; conv2d_parm1.val = 0; conv2d_parm1.bits.act = act_func; conv2d_parm1.bits.pad = padding_type; // NNPA parameter block expects: // - function-specific-parameter-2: dimension-2 (W) stride of NHWC // - function-specific-parameter-3: dimension-3 (H) stride of NHWC // thus in (stride_width, stride_height) order return aiu_ops_func_specific(NNPA_CONVOLUTION, input, kernel, bias, output, NULL, 0, conv2d_parm1.val, stride_width, stride_height, conv2d_parm4.val, 0); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/query.c�����������������������������������������������������������������������������0000664�0000000�0000000�00000017641�14364043643�0014624�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #if defined(__MVS__) #include <cvt.h> #include <ihaecvt.h> #include <ihafacl.h> #include <ihapsa.h> #endif #include "zdnn.h" #include "zdnn_private.h" #ifdef __MVS__ #pragma export(zdnn_is_nnpa_function_installed) #pragma export(zdnn_is_nnpa_parmblk_fmt_installed) #pragma export(zdnn_is_nnpa_datatype_installed) #pragma export(zdnn_is_nnpa_layout_fmt_installed) #pragma export(zdnn_get_nnpa_max_dim_idx_size) #pragma export(zdnn_get_nnpa_max_tensor_size) #pragma export(zdnn_refresh_nnpa_query_result) #pragma export(zdnn_is_nnpa_conversion_installed) #endif // Cached copy of the NNPA-QAF result. zdnn_refresh_nnpa_query_result() is // responsible for setting and modifying this. For performance reasons, all // query functions that involve NNPA-QAF result read from this cached copy nnpa_qaf_parameter_block nnpa_query_result; /// Query if NNPA functions are installed /// /// \param[in] count, number of NNPA functions to query /// \param[in] ... (additional arguments), function numbers defined in /// nnpa_function_code enum /// /// \return true if all queried functions are installed, false if any is not /// bool zdnn_is_nnpa_function_installed(int count, ...) { va_list ap; va_start(ap, count); bool result = true; uint16_t max_func = BIT_SIZEOF(nnpa_query_result.installed_functions_vector); for (uint16_t i = 0; i < count; i++) { uint16_t func_num = va_arg(ap, int); if (func_num >= max_func || // protect ourselves from out-of-range input !is_bitset_256(nnpa_query_result.installed_functions_vector, func_num)) { result = false; break; } } va_end(ap); return result; } /// Query if NNPA parameter block formats are installed /// /// \param[in] count, number of NNPA parameter block formats to query /// \param[in] ... (additional arguments), NNPA parameter block formats defined /// in nnpa_parmblk_format enum /// /// \return true if all queried formats are installed, false if any is not /// bool zdnn_is_nnpa_parmblk_fmt_installed(int count, ...) { va_list ap; va_start(ap, count); bool result = true; uint8_t max_format = BIT_SIZEOF(nnpa_query_result.installed_parameter_block_formats); for (uint8_t i = 0; i < count; i++) { uint8_t func_num = va_arg(ap, int); if (func_num >= max_format || // protect ourselves from out-of-range input !is_bitset_128(nnpa_query_result.installed_parameter_block_formats, func_num)) { result = false; break; } } va_end(ap); return result; } /// Query if NNPA data types are installed /// /// \param[in] types_bitmask OR'd type numbers as defined in /// zdnn_query_datatypes /// enum /// /// \return true if all queried data types are installed, false if any is not /// bool zdnn_is_nnpa_datatype_installed(uint16_t types_bitmask) { return (~nnpa_query_result.installed_data_types & types_bitmask) == 0; } /// Query if NNPA data layout formats are installed /// /// \param[in] layout_bitmask OR'd layout numbers as defined in /// zdnn_query_layout_fmts enum /// /// \return true if all queried data layout formats are installed, false if any /// is not /// bool zdnn_is_nnpa_layout_fmt_installed(uint32_t layout_bitmask) { return (~nnpa_query_result.installed_data_layout_formats & layout_bitmask) == 0; } /// Query if NNPA data type to/from BFP format conversions are installed /// /// \param[in] type NNPA data type as defined in nnpa_data_type enum /// \param[in] format_bitmask OR'd BFP format numbers as defined in /// zdnn_query_bfpfmts enum /// /// \return true if all queried format conversions are installed, false if any /// is not /// bool zdnn_is_nnpa_conversion_installed(nnpa_data_type type, uint16_t format_bitmask) { switch (type) { case NNPA_DATATYPE_1: return (~nnpa_query_result.installed_dt1_conversions_vector & format_bitmask) == 0; default: // unknown nnp data-type means "not installed" regardless of mask return false; } } /// Query the NNPA maximum supported dimension index size value /// /// \param[in] None /// /// \return maximum dimension index size value supported by NNPA /// uint32_t zdnn_get_nnpa_max_dim_idx_size() { return nnpa_query_result.maximum_dimension_index_size; } /// Query the NNPA maximum supported tensor size (in bytes) /// /// \param[in] None /// /// \return maximum tensor size value supported by NNPA /// uint64_t zdnn_get_nnpa_max_tensor_size() { return nnpa_query_result.maximum_tensor_size; } /// Refresh the nnpa_query_result struct from zAIU /// /// \param[in] result pointer to aiu_parameter_block_nnpa_qaf struct /// /// \return ZDNN_OK /// ZDNN_UNAVAILABLE_FUNCTION /// zdnn_status zdnn_refresh_nnpa_query_result() { zdnn_status query_status; #ifndef ZDNN_CONFIG_NO_NNPA query_status = invoke_nnpa_query(&nnpa_query_result); #else query_status = ZDNN_STATUS_OK; #define MAXIMUM_DIMENSION_INDEX_SIZE ((uint32_t)1 << 15) // 32768 #define MAXIMUM_TENSOR_SIZE ((uint64_t)1 << 32) // 4294967296 setbit_128(&nnpa_query_result.installed_parameter_block_formats, NNPA_PARMBLKFORMAT_0); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_QAF); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_ADD); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_SUB); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_MUL); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_DIV); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_MIN); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_MAX); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_LOG); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_EXP); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_RELU); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_TANH); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_SIGMOID); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_SOFTMAX); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_BATCHNORMALIZATION); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_MAXPOOL2D); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_AVGPOOL2D); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_LSTMACT); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_GRUACT); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_CONVOLUTION); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_MATMUL_OP); setbit_256(&nnpa_query_result.installed_functions_vector, NNPA_MATMUL_OP_BCAST23); nnpa_query_result.installed_data_types |= QUERY_DATATYPE_INTERNAL1; nnpa_query_result.installed_data_layout_formats |= (QUERY_LAYOUTFMT_4DFEATURE | QUERY_LAYOUTFMT_4DKERNEL); nnpa_query_result.installed_dt1_conversions_vector |= (QUERY_BFPFMT_TINY | QUERY_BFPFMT_SHORT); nnpa_query_result.maximum_dimension_index_size = MAXIMUM_DIMENSION_INDEX_SIZE; nnpa_query_result.maximum_tensor_size = MAXIMUM_TENSOR_SIZE; #endif refresh_aiu_lib_vernum(); return query_status; } �����������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/reshape_ztensor.c�������������������������������������������������������������������0000664�0000000�0000000�00000017071�14364043643�0016667�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <stdlib.h> #include <string.h> #include "zdnn.h" #include "zdnn_private.h" #ifdef __MVS__ #pragma export(zdnn_reshape_ztensor) #endif /// Reshape and copy buffer content from source zTensor's buffer to destination /// zTensor's in accordance to destination zTensor's shape. The following /// conditions must be satisfied: /// /// - Both transformed_desc must be fully initialized /// - dest->buffer must be pre-allocated /// - src must be transformed /// - dest must be not already transformed /// - Both transformed_desc->layout must be the same and either NHWC or HWCK /// - Both zTensors must contain equal number of elements /// /// \param[in] src Pointer to source ztensor to copy from /// \param[out] dest Pointer to destination ztensor to copy to /// /// \return ZDNN_OK /// ZDNN_INVALID_SHAPE /// ZDNN_INVALID_LAYOUT /// ZDNN_INVALID_STATE /// ZDNN_INVALID_FORMAT /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_BUFFER /// ZDNN_CONVERT_FAILURE /// zdnn_status zdnn_reshape_ztensor(const zdnn_ztensor *src, zdnn_ztensor *dest) { // It's caller's responsibility to ensure pre_transformed_desc and // transformed_desc agree with each other. This function does not // look at pre_transformed_desc at all. zdnn_tensor_desc *src_tfrmd_desc = src->transformed_desc, *dest_tfrmd_desc = dest->transformed_desc; LOG_TRACE("(transformed) src: %d %d %d %d -> dest: %d %d %d %d\n", src_tfrmd_desc->dim4, src_tfrmd_desc->dim3, src_tfrmd_desc->dim2, src_tfrmd_desc->dim1, dest_tfrmd_desc->dim4, dest_tfrmd_desc->dim3, dest_tfrmd_desc->dim2, dest_tfrmd_desc->dim1); if (get_num_elements(src, ELEMENTS_PRE) != get_num_elements(dest, ELEMENTS_PRE)) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "src (%d * %d * %d * %d) does not have the same number " "of elements as dest (%d * %d * %d * %d)", src_tfrmd_desc->dim4, src_tfrmd_desc->dim3, src_tfrmd_desc->dim2, src_tfrmd_desc->dim1, dest_tfrmd_desc->dim4, dest_tfrmd_desc->dim3, dest_tfrmd_desc->dim2, dest_tfrmd_desc->dim1); } if (src_tfrmd_desc->layout != dest_tfrmd_desc->layout) { return ZDNN_STATUS( ZDNN_INVALID_LAYOUT, "Layouts not the same. src layout: %d, dest layout: %d.", src_tfrmd_desc->layout, dest_tfrmd_desc->layout); } // check either src/dest, both layouts are same by now if (src_tfrmd_desc->layout != ZDNN_NHWC && src_tfrmd_desc->layout != ZDNN_HWCK) { return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Layout must be either NHWC or HWCK. layout: %d.", src_tfrmd_desc->layout); } if (!src->is_transformed) { return ZDNN_STATUS(ZDNN_INVALID_STATE, "src tensor is not transformed.", NO_ARG); } if (dest->is_transformed) { return ZDNN_STATUS(ZDNN_INVALID_STATE, "dest tensor contains transformed tensor data.", NO_ARG); } /* / Different strategies for different shape combinations */ // Scenario: Both have the exact same shape. Just memcpy() everything. if (src_tfrmd_desc->dim4 == dest_tfrmd_desc->dim4 && src_tfrmd_desc->dim3 == dest_tfrmd_desc->dim3 && src_tfrmd_desc->dim2 == dest_tfrmd_desc->dim2 && src_tfrmd_desc->dim1 == dest_tfrmd_desc->dim1) { LOG_TRACE("Strategy: full memcpy()", NO_ARG); memcpy(dest->buffer, src->buffer, zdnn_getsize_ztensor(src_tfrmd_desc)); return ZDNN_STATUS_OK; } // Scenario: src: (x, y, z, c), dest: (i, j, k, c), // Both sides have the exact same # of sticks, so memcpy() each stick if (src_tfrmd_desc->dim1 == dest_tfrmd_desc->dim1) { LOG_TRACE("Strategy: same C, memcpy() every stick", NO_ARG); uint32_t x = 0, y = 0, z = 0; for (uint32_t i = 0; i < dest_tfrmd_desc->dim4; i++) { for (uint32_t j = 0; j < dest_tfrmd_desc->dim3; j++) { for (uint32_t k = 0; k < dest_tfrmd_desc->dim2; k++) { for (uint32_t c = 0; c < CEIL(dest_tfrmd_desc->dim1, AIU_2BYTE_CELLS_PER_STICK); c++) { // get_stick_offset() tells us where the sticks are // use transformed_desc here so we don't need to transposed shapes // (e.g., 3DS) size_t offset_src = get_stick_offset( x, y, z, c * AIU_2BYTE_CELLS_PER_STICK, src->transformed_desc); size_t offset_dest = get_stick_offset( i, j, k, c * AIU_2BYTE_CELLS_PER_STICK, dest->transformed_desc); LOG_TRACE("%d %d %d %d (%" PRIx64 ") -> %d %d %d %d (%" PRIx64 ")\n", x, y, z, c, offset_src, i, j, k, c, offset_dest); // memcpy() the entire stick to simplify things memcpy((void *)((uintptr_t)dest->buffer + offset_dest), (void *)((uintptr_t)src->buffer + offset_src), AIU_BYTES_PER_STICK); } // go to the next stick on the src side z++; if (z == src_tfrmd_desc->dim2) { z = 0; y++; if (y == src_tfrmd_desc->dim3) { y = 0; x++; } } } } } return ZDNN_STATUS_OK; } LOG_TRACE("Strategy: last resort", NO_ARG); #define STACK_TMPBUF_SIZE (1024 * 1024) // 1MB // last resort: fully unstick and restick // NOTE: this will change when we have "no conversion stick/unstick" // for now, unstick to FP32 and restick to preserve precision. char stack_tmpbuf[STACK_TMPBUF_SIZE]; void *malloc_tmpbuf = NULL; zdnn_ztensor tmp_tensor_src, tmp_tensor_dest; zdnn_tensor_desc tmp_pre_tfrmd_desc_src, tmp_pre_tfrmd_desc_dest; memcpy(&tmp_tensor_src, src, sizeof(zdnn_ztensor)); memcpy(&tmp_tensor_dest, dest, sizeof(zdnn_ztensor)); memcpy(&tmp_pre_tfrmd_desc_src, src->pre_transformed_desc, sizeof(zdnn_tensor_desc)); memcpy(&tmp_pre_tfrmd_desc_dest, dest->pre_transformed_desc, sizeof(zdnn_tensor_desc)); tmp_pre_tfrmd_desc_src.type = FP32; tmp_pre_tfrmd_desc_dest.type = FP32; tmp_tensor_src.pre_transformed_desc = &tmp_pre_tfrmd_desc_src; tmp_tensor_dest.pre_transformed_desc = &tmp_pre_tfrmd_desc_dest; zdnn_status status; // if unstickified content is small enough (=< STACK_TMPBUF_SIZE) then use // stack_tmpbuf instead of malloc()-ing one on heap uint64_t s = get_num_elements(src, ELEMENTS_PRE) * get_data_type_size(FP32); if (s > STACK_TMPBUF_SIZE) { malloc_tmpbuf = malloc(s); } // no need to log status, zdnn_transform_origtensor() and // zdnn_transform_ztensor() already do if ((status = zdnn_transform_origtensor( &tmp_tensor_src, malloc_tmpbuf ? malloc_tmpbuf : stack_tmpbuf)) == ZDNN_OK) { status = zdnn_transform_ztensor( &tmp_tensor_dest, malloc_tmpbuf ? malloc_tmpbuf : stack_tmpbuf); } if (malloc_tmpbuf) { free(malloc_tmpbuf); } return status; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/status.c����������������������������������������������������������������������������0000664�0000000�0000000�00000030404�14364043643�0014772�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <stdarg.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifndef __MVS__ #include <execinfo.h> #include <unistd.h> #else #include <ctest.h> #endif #ifdef __MVS__ #pragma export(zdnn_get_status_message) #endif /* this macro declares 2 strings: 1) STATUS_STR_XXX, which is the stringification of the status code itself 2) STATUS_MSG_XXX, which is the default status message of the status code in "ZDNN_XXX: message" form */ #define DECLARE_STATUS_STR_N_MSG(a, b) \ const char *STATUS_STR_##a = #a; \ const char *STATUS_MSG_##a = #a ": " b; DECLARE_STATUS_STR_N_MSG(ZDNN_OK, "Success.") DECLARE_STATUS_STR_N_MSG(ZDNN_ELEMENT_RANGE_VIOLATION, "One or more output tensor values were not valid.") DECLARE_STATUS_STR_N_MSG( ZDNN_INVALID_SHAPE, "Invalid shape in one (or more) of the input/output tensor(s).") DECLARE_STATUS_STR_N_MSG( ZDNN_INVALID_LAYOUT, "Invalid layout in one (or more) of the input/output tensor(s).") DECLARE_STATUS_STR_N_MSG( ZDNN_INVALID_TYPE, "Invalid type in one (or more) of the input/output tensor(s).") DECLARE_STATUS_STR_N_MSG( ZDNN_INVALID_FORMAT, "Invalid format in one (or more) of the input/output tensor(s).") DECLARE_STATUS_STR_N_MSG(ZDNN_INVALID_DIRECTION, "Invalid RNN direction.") DECLARE_STATUS_STR_N_MSG(ZDNN_INVALID_CONCAT_INFO, "Invalid concatenation info.") DECLARE_STATUS_STR_N_MSG( ZDNN_INVALID_STRIDE_PADDING, "Padding type is not valid for the current stride inputs.") DECLARE_STATUS_STR_N_MSG(ZDNN_INVALID_STRIDES, "Invalid stride height or width.") DECLARE_STATUS_STR_N_MSG(ZDNN_MISALIGNED_PARMBLOCK, "NNPA parameter block is not on doubleword boundary.") DECLARE_STATUS_STR_N_MSG(ZDNN_INVALID_CLIPPING_VALUE, "Invalid clipping for the specified operation.") DECLARE_STATUS_STR_N_MSG(ZDNN_ALLOCATION_FAILURE, "Can not allocate storage.") DECLARE_STATUS_STR_N_MSG( ZDNN_INVALID_BUFFER, "Buffer address is NULL or not on 4K-byte boundary, or " "insufficient buffer size.") DECLARE_STATUS_STR_N_MSG(ZDNN_CONVERT_FAILURE, "Floating point data conversion failure.") DECLARE_STATUS_STR_N_MSG(ZDNN_INVALID_STATE, "Invalid zTensor state.") DECLARE_STATUS_STR_N_MSG(ZDNN_UNSUPPORTED_AIU_EXCEPTION, "AIU operation returned an unexpected exception.") DECLARE_STATUS_STR_N_MSG( ZDNN_UNSUPPORTED_PARMBLOCK, "NNPA parameter block format is not supported by the model.") DECLARE_STATUS_STR_N_MSG( ZDNN_UNAVAILABLE_FUNCTION, "Specified NNPA function is not defined or installed on the machine.") DECLARE_STATUS_STR_N_MSG( ZDNN_UNSUPPORTED_FORMAT, "Specified tensor data layout format is not supported.") DECLARE_STATUS_STR_N_MSG(ZDNN_UNSUPPORTED_TYPE, "Specified tensor data type is not supported.") DECLARE_STATUS_STR_N_MSG( ZDNN_EXCEEDS_MDIS, "Tensor dimension exceeds maximum dimension index size (MDIS).") DECLARE_STATUS_STR_N_MSG( ZDNN_EXCEEDS_MTS, "Total number of elements in tensor exceeds maximum tensor size (MTS).") DECLARE_STATUS_STR_N_MSG(ZDNN_MISALIGNED_TENSOR, "Tensor address is not on 4K-byte boundary.") DECLARE_STATUS_STR_N_MSG( ZDNN_MISALIGNED_SAVEAREA, "Function specific save area address is not on 4K-byte boundary.") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F000, "Function specific response code (F000).") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F001, "Function specific response code (F001).") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F002, "Function specific response code (F002).") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F003, "Function specific response code (F003).") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F004, "Function specific response code (F004).") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F005, "Function specific response code (F005).") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F006, "Function specific response code (F006).") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F007, "Function specific response code (F007).") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F008, "Function specific response code (F008).") DECLARE_STATUS_STR_N_MSG(ZDNN_FUNC_RC_F009, "Function specific response code (F009).") const char *STATUS_MSG_UNKNOWN_STATUS = "(Status string is not defined.)"; const char *STATUS_STR_UNKNOWN_STATUS = "(?)"; /// Retrieve default status message of the status code /// /// \param[in] status status code /// /// /// \return pointer to the default status message /// const char *zdnn_get_status_message(zdnn_status status) { #define CASE_RTN_MSG(a) \ case a: \ return STATUS_MSG_##a; switch (status) { CASE_RTN_MSG(ZDNN_OK); CASE_RTN_MSG(ZDNN_ELEMENT_RANGE_VIOLATION); CASE_RTN_MSG(ZDNN_INVALID_SHAPE); CASE_RTN_MSG(ZDNN_INVALID_LAYOUT); CASE_RTN_MSG(ZDNN_INVALID_TYPE); CASE_RTN_MSG(ZDNN_INVALID_FORMAT); CASE_RTN_MSG(ZDNN_INVALID_DIRECTION); CASE_RTN_MSG(ZDNN_INVALID_CONCAT_INFO); CASE_RTN_MSG(ZDNN_INVALID_STRIDE_PADDING); CASE_RTN_MSG(ZDNN_INVALID_STRIDES); CASE_RTN_MSG(ZDNN_MISALIGNED_PARMBLOCK); CASE_RTN_MSG(ZDNN_INVALID_CLIPPING_VALUE); CASE_RTN_MSG(ZDNN_ALLOCATION_FAILURE); CASE_RTN_MSG(ZDNN_INVALID_BUFFER); CASE_RTN_MSG(ZDNN_CONVERT_FAILURE); CASE_RTN_MSG(ZDNN_INVALID_STATE); CASE_RTN_MSG(ZDNN_UNSUPPORTED_AIU_EXCEPTION); CASE_RTN_MSG(ZDNN_UNSUPPORTED_PARMBLOCK); CASE_RTN_MSG(ZDNN_UNAVAILABLE_FUNCTION); CASE_RTN_MSG(ZDNN_UNSUPPORTED_FORMAT); CASE_RTN_MSG(ZDNN_UNSUPPORTED_TYPE); CASE_RTN_MSG(ZDNN_EXCEEDS_MDIS); CASE_RTN_MSG(ZDNN_EXCEEDS_MTS); CASE_RTN_MSG(ZDNN_MISALIGNED_TENSOR); CASE_RTN_MSG(ZDNN_MISALIGNED_SAVEAREA); CASE_RTN_MSG(ZDNN_FUNC_RC_F000); CASE_RTN_MSG(ZDNN_FUNC_RC_F001); CASE_RTN_MSG(ZDNN_FUNC_RC_F002); CASE_RTN_MSG(ZDNN_FUNC_RC_F003); CASE_RTN_MSG(ZDNN_FUNC_RC_F004); CASE_RTN_MSG(ZDNN_FUNC_RC_F005); CASE_RTN_MSG(ZDNN_FUNC_RC_F006); CASE_RTN_MSG(ZDNN_FUNC_RC_F007); CASE_RTN_MSG(ZDNN_FUNC_RC_F008); CASE_RTN_MSG(ZDNN_FUNC_RC_F009); default: // can't find the corresponding string LOG_WARN("Unknown status code: %08x", status); return STATUS_MSG_UNKNOWN_STATUS; } #undef CASE_RTN_MSG } /// Retrieve status string of the status code /// /// \param[in] status status code /// /// /// \return pointer to the status string /// static const char *get_status_str(zdnn_status status) { #define CASE_RTN_STR(a) \ case a: \ return STATUS_STR_##a; switch (status) { CASE_RTN_STR(ZDNN_OK); CASE_RTN_STR(ZDNN_ELEMENT_RANGE_VIOLATION); CASE_RTN_STR(ZDNN_INVALID_SHAPE); CASE_RTN_STR(ZDNN_INVALID_LAYOUT); CASE_RTN_STR(ZDNN_INVALID_TYPE); CASE_RTN_STR(ZDNN_INVALID_FORMAT); CASE_RTN_STR(ZDNN_INVALID_DIRECTION); CASE_RTN_STR(ZDNN_INVALID_CONCAT_INFO); CASE_RTN_STR(ZDNN_INVALID_STRIDE_PADDING); CASE_RTN_STR(ZDNN_INVALID_STRIDES); CASE_RTN_STR(ZDNN_MISALIGNED_PARMBLOCK); CASE_RTN_STR(ZDNN_INVALID_CLIPPING_VALUE); CASE_RTN_STR(ZDNN_ALLOCATION_FAILURE); CASE_RTN_STR(ZDNN_INVALID_BUFFER); CASE_RTN_STR(ZDNN_CONVERT_FAILURE); CASE_RTN_STR(ZDNN_INVALID_STATE); CASE_RTN_STR(ZDNN_UNSUPPORTED_AIU_EXCEPTION); CASE_RTN_STR(ZDNN_UNSUPPORTED_PARMBLOCK); CASE_RTN_STR(ZDNN_UNAVAILABLE_FUNCTION); CASE_RTN_STR(ZDNN_UNSUPPORTED_FORMAT); CASE_RTN_STR(ZDNN_UNSUPPORTED_TYPE); CASE_RTN_STR(ZDNN_EXCEEDS_MDIS); CASE_RTN_STR(ZDNN_EXCEEDS_MTS); CASE_RTN_STR(ZDNN_MISALIGNED_TENSOR); CASE_RTN_STR(ZDNN_MISALIGNED_SAVEAREA); CASE_RTN_STR(ZDNN_FUNC_RC_F000); CASE_RTN_STR(ZDNN_FUNC_RC_F001); CASE_RTN_STR(ZDNN_FUNC_RC_F002); CASE_RTN_STR(ZDNN_FUNC_RC_F003); CASE_RTN_STR(ZDNN_FUNC_RC_F004); CASE_RTN_STR(ZDNN_FUNC_RC_F005); CASE_RTN_STR(ZDNN_FUNC_RC_F006); CASE_RTN_STR(ZDNN_FUNC_RC_F007); CASE_RTN_STR(ZDNN_FUNC_RC_F008); CASE_RTN_STR(ZDNN_FUNC_RC_F009); default: // can't find the corresponding string LOG_WARN("Unknown status code: %08x", status); return STATUS_STR_UNKNOWN_STATUS; } #undef CASE_RTN_STR } // maximum size for the format string, including the prepended STATUS_STR_XXX #define MAX_STATUS_FMTSTR_SIZE 1024 zdnn_status set_zdnn_status(zdnn_status status, const char *func_name, const char *file_name, int line_no, const char *format, ...) { // when ZDNN_CONFIG_DEBUG is on, incoming status is either OK or not OK: // - ZDNN_OK: log as LOGLEVEL_INFO // - everything else: log as LOGLEVEL_ERROR // // when ZDNN_CONFIG_DEBUG is off, incoming status is always some sort of not // OK, use LOGLEVEL_ERROR so log_message() will send it to STDERR log_levels lvl_to_use = #ifdef ZDNN_CONFIG_DEBUG (status == ZDNN_OK) ? LOGLEVEL_INFO : #endif LOGLEVEL_ERROR; if (format) { va_list argptr; va_start(argptr, format); // prepend status string "ZDNN_XXX: " to the incoming "format" string char full_fmtstr[MAX_STATUS_FMTSTR_SIZE]; snprintf(full_fmtstr, MAX_STATUS_FMTSTR_SIZE, "%s: ", get_status_str(status)); strncat(full_fmtstr, format, MAX_STATUS_FMTSTR_SIZE - 1); // "full_fmtstr" is now concatenated log_message(lvl_to_use, func_name, file_name, line_no, full_fmtstr, argptr); va_end(argptr); } else { // use the default status string if caller doesn't give us one log_message(lvl_to_use, func_name, file_name, line_no, zdnn_get_status_message(status), NULL); } /* collect backtrace information if status diag is enabled. different approaches for gcc vs xlc - xlc: use ctrace() to request traceback (via CEE3DMP), usually to a CEEDUMP - gcc: print backtrace information messages are sent to STDOUT regardless of log level */ if (status == status_diag) { // assuming incoming status will never be // STATUS_DIAG_NOT_SET printf("zDNN Diagnostic\n"); printf("===================================================================" "===\n"); printf("status = 0x%08x, %s\n", status, zdnn_get_status_message(status)); #ifdef __MVS__ #define DUMP_TITLE_SIZE 64 printf("Invoking CEE3DMP Language Environment callable service...\n"); char dump_title[DUMP_TITLE_SIZE]; snprintf(dump_title, DUMP_TITLE_SIZE, "zDNN ctrace for status %08x", status); int rtn = ctrace(dump_title); // ctrace() returns 0 when successful. if (rtn == 0) { printf("Successfully invoked CEE3DMP.\n"); } else { printf("Failed to invoke CEE3DMP. Return Code: %d.\n", rtn); } #else #define MAX_STACK_ENTRIES 30 // max num of stack entries to print printf("Backtrace:\n"); void *array[MAX_STACK_ENTRIES]; size_t size; char **strings; size = backtrace(array, MAX_STACK_ENTRIES); strings = backtrace_symbols(array, size); if (strings != NULL) { for (int i = 0; i < size; i++) { printf("%s\n", strings[i]); } free(strings); } #endif // __MVS__ printf("===================================================================" "===\n"); } return status; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/stickify.c��������������������������������������������������������������������������0000664�0000000�0000000�00000207057�14364043643�0015306�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <fenv.h> #include <stdarg.h> #include <stdbool.h> #include <stddef.h> #include <stdio.h> #include <string.h> #include "convert.h" #include "zdnn.h" #include "zdnn_private.h" #ifdef __MVS__ #pragma export(zdnn_transform_ztensor) #pragma export(zdnn_transform_origtensor) #endif /// Return the byte offset of the field in the stick array, based on the input /// fields indexes, and the overall dimensions of the input tensor. The use of /// e4x,e3x, etc is to reflect the four dimensions in the NNPA control block /// E4,E3,E2,E1 /// /// \param[in] e4x outermost dimension /// \param[in] e3x e3 dimension /// \param[in] e2x e2 dimension /// \param[in] e1x innermost dimension /// \param[in] desc tensor descriptor that contains the original shape /// information /// /// /// \return Byte offset of the field in the stick array, or 0 if error /// size_t get_stick_offset(uint32_t e4x, uint32_t e3x, uint32_t e2x, uint32_t e1x, const zdnn_tensor_desc *pre_tfrmd_desc) { if (pre_tfrmd_desc->layout != ZDNN_HWCK) { // Stickified feature tensor elements follow the NHWC layout, // so use the n, h, w, c notation for easier read. uint32_t h = 1, w = 1, c = 1; // n = 1, uint32_t nx = e4x, hx = 1, wx = 1, cx = 1; switch (pre_tfrmd_desc->layout) { case (ZDNN_1D): case (ZDNN_2D): case (ZDNN_3D): case (ZDNN_4D): case (ZDNN_NHWC): { h = (get_data_layout_dims(pre_tfrmd_desc->layout) >= 3) ? pre_tfrmd_desc->dim3 : 1; w = (get_data_layout_dims(pre_tfrmd_desc->layout) >= 2) ? pre_tfrmd_desc->dim2 : 1; c = pre_tfrmd_desc->dim1; hx = e3x; wx = e2x; cx = e1x; break; } case (ZDNN_3DS): { w = pre_tfrmd_desc->dim2; c = pre_tfrmd_desc->dim1; hx = e3x; wx = e2x; cx = e1x; break; } case (ZDNN_2DS): { c = pre_tfrmd_desc->dim1; hx = e3x; wx = e2x; cx = e1x; break; } case (ZDNN_NCHW): { h = pre_tfrmd_desc->dim2; w = pre_tfrmd_desc->dim1; c = pre_tfrmd_desc->dim3; cx = e3x; hx = e2x; wx = e1x; break; } default: LOG_DEBUG("get_stick_offset: Unsupported layout (%s)", get_data_layout_str(pre_tfrmd_desc->layout)); return 0; } uint16_t pages_height_per_h = CEIL(w, AIU_STICKS_PER_PAGE); uint32_t pages_height_all_h = pages_height_per_h * h; uint64_t pages_per_n = pages_height_all_h * CEIL(c, AIU_2BYTE_CELLS_PER_STICK); // find out how many pages to traverse: traverse to n = nx section of the // stick area, then c = cx, and so forth uint64_t page = (pages_per_n * nx) + ((cx / AIU_2BYTE_CELLS_PER_STICK) * pages_height_all_h) + (hx * pages_height_per_h) + (wx / AIU_STICKS_PER_PAGE); // find out which stick within the page is the element at uint16_t stick = wx % AIU_STICKS_PER_PAGE; // traverse this number of cells to get to the element uint16_t cell = cx % AIU_2BYTE_CELLS_PER_STICK; BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { uint64_t e = (uint64_t)e4x * (pre_tfrmd_desc->dim3 * pre_tfrmd_desc->dim2 * pre_tfrmd_desc->dim1) + e3x * (pre_tfrmd_desc->dim2 * pre_tfrmd_desc->dim1) + e2x * (pre_tfrmd_desc->dim1) + e1x; printf("\ne4x %d e3x %d e2x %d e1x %d -> element #%" PRIu64 " ----------------------------------------------\n", e4x, e3x, e2x, e1x, e); printf("nx %u hx %u wx %u cx %u\n", nx, hx, wx, cx); printf("pages_height_per_h %u pages_height_all_h %u " "pages_per_n %" PRIu64 "\n", pages_height_per_h, pages_height_all_h, pages_per_n); printf("(nx * pages_per_n) %" PRIu64 "\n", (nx * pages_per_n)); printf("((cx / AIU_2BYTE_CELLS_PER_STICK) * pages_height_all_h) %u\n", ((cx / AIU_2BYTE_CELLS_PER_STICK) * pages_height_all_h)); printf("(hx * pages_height_per_h) %u\n", (hx * pages_height_per_h)); printf("(wx / AIU_STICKS_PER_PAGE) %u\n", (wx / AIU_STICKS_PER_PAGE)); printf("page %" PRIu64 " stick %d cell %d\n", page, stick, cell); } // quantify those values in number of bytes return page * AIU_PAGESIZE_IN_BYTES + stick * AIU_BYTES_PER_STICK + cell * AIU_2BYTE_CELL_SIZE; } else { // Stickified kernel tensor elements follow the HWCK layout, // so use the h, w, c, k notation for easier read. uint32_t h = pre_tfrmd_desc->dim4, w = pre_tfrmd_desc->dim3, c = pre_tfrmd_desc->dim2; uint32_t hx = e4x, wx = e3x, cx = e2x, kx = e1x; uint16_t pages_height_per_w = CEIL(c, AIU_STICKS_PER_PAGE); uint32_t pages_height_per_h = pages_height_per_w * w; uint64_t pages_height_all_h = pages_height_per_h * h; // traverse to k = kx section of the stick area, then h = hx, then w = wx // it's slightly different from NHWC due to the E1/E2 arrangement uint64_t page = pages_height_all_h * (kx / AIU_2BYTE_CELLS_PER_STICK) + hx * pages_height_per_h + wx * pages_height_per_w; // traverse this number of cells to get to the element uint16_t cell = kx % AIU_2BYTE_CELLS_PER_STICK; // quantify those values in number of bytes return page * AIU_PAGESIZE_IN_BYTES + cx * AIU_BYTES_PER_STICK + cell * AIU_2BYTE_CELL_SIZE; } } /// Main entry point for converting FP16/FP32/BFLOAT <-> ZDNN_DLFLOAT16 when /// the entries to fetch/set on FP16/FP32/BFLOAT side are not contiguous (e.g., /// fetching the c-entries in a NCHW stream). /// /// \param[in] input_data Pointer to input tensor data stream /// \param[in] in_data_fmt Input tensor stream data format /// \param[in] output_data Pointer to output tensor data stream /// \param[in] out_data_fmt Output tensor stream data format /// \param[in] num_fields Number of fields to convert /// \param[in] input_stride How many fields (not bytes) the input entries are /// apart /// /// \return Number of fields converted, or 0 if error /// uint32_t convert_data_format_in_stride(void *input_data, zdnn_data_types in_data_fmt, void *output_data, zdnn_data_types out_data_fmt, uint32_t num_fields, uint32_t input_stride) { uint64_t num_fields_converted = 0; // we only care convert to/from ZDNN_DLFLOAT16 if (out_data_fmt == ZDNN_DLFLOAT16) { switch (in_data_fmt) { case FP16: num_fields_converted = fp16_to_dlf16_in_stride((uint16_t *)input_data, (uint16_t *)output_data, num_fields, input_stride); break; case FP32: num_fields_converted = fp32_to_dlf16_in_stride((float *)input_data, (uint16_t *)output_data, num_fields, input_stride); break; case BFLOAT: num_fields_converted = bfloat_to_dlf16_in_stride( (uint16_t *)input_data, (uint16_t *)output_data, num_fields, input_stride); break; default: break; // something really wrong, get out and return 0 } } else if (in_data_fmt == ZDNN_DLFLOAT16) { switch (out_data_fmt) { case FP16: num_fields_converted = dlf16_to_fp16_in_stride((uint16_t *)input_data, (uint16_t *)output_data, num_fields, input_stride); break; case FP32: num_fields_converted = dlf16_to_fp32_in_stride((uint16_t *)input_data, (float *)output_data, num_fields, input_stride); break; case BFLOAT: num_fields_converted = dlf16_to_bfloat_in_stride( (uint16_t *)input_data, (uint16_t *)output_data, num_fields, input_stride); break; default: break; // something really wrong, get out and return 0 } } else { // something really wrong return 0; } return num_fields_converted; } /// Main entry point for converting FP16/FP32/BFLOAT <-> ZDNN_DLFLOAT16 when /// the entries to fetch/set on FP16/FP32/BFLOAT side are contiguous (e.g., /// fetching the c-entries in a NHWC stream). /// /// \param[in] input_data Pointer to input tensor data stream /// \param[in] in_data_fmt Input tensor stream data format /// \param[in] output_data Pointer to output tensor data stream /// \param[in] out_data_fmt Output tensor stream data format /// \param[in] num_fields Number of fields to convert /// /// \return Number of fields converted, or 0 if error /// uint32_t convert_data_format(void *input_data, zdnn_data_types in_data_fmt, void *output_data, zdnn_data_types out_data_fmt, uint32_t num_fields) { uint64_t num_fields_converted = 0; // we only care convert to/from ZDNN_DLFLOAT16 if (out_data_fmt == ZDNN_DLFLOAT16) { switch (in_data_fmt) { case FP16: num_fields_converted = fp16_to_dlf16((uint16_t *)input_data, (uint16_t *)output_data, num_fields); break; case FP32: num_fields_converted = fp32_to_dlf16((float *)input_data, (uint16_t *)output_data, num_fields); break; case BFLOAT: num_fields_converted = bfloat_to_dlf16( (uint16_t *)input_data, (uint16_t *)output_data, num_fields); break; default: break; // something really wrong, get out and return 0 return 0; } } else if (in_data_fmt == ZDNN_DLFLOAT16) { switch (out_data_fmt) { case FP16: num_fields_converted = dlf16_to_fp16((uint16_t *)input_data, (uint16_t *)output_data, num_fields); break; case FP32: num_fields_converted = dlf16_to_fp32((uint16_t *)input_data, (float *)output_data, num_fields); break; case BFLOAT: num_fields_converted = dlf16_to_bfloat( (uint16_t *)input_data, (uint16_t *)output_data, num_fields); break; default: break; // something really wrong, get out and return 0 return 0; } } else { // something really wrong return 0; } return num_fields_converted; } // End convert_data_format /// Handle FP Exceptions and map to ZDNN status code if necessary /// /// \param[in] fe FP Exceptions /// /// \return mapped ZDNN status code /// zdnn_status handle_fp_errors(int fe) { if (fe & FE_UNDERFLOW) { LOG_WARN("Some tensor elements too small and forced to zero in " "target.", NO_ARG); // underflow (bit 11) // no error externalized } if ((fe & FE_INVALID) || (fe & FE_OVERFLOW)) { return ZDNN_STATUS(ZDNN_CONVERT_FAILURE, "Some tensor elements too large. Consider model " "tuning.", NO_ARG); // invalid op (bit 8) or overflow (bit 10) } if (fe & FE_INEXACT) { return ZDNN_STATUS(ZDNN_CONVERT_FAILURE, "Internal error or Live migration happened" "(Target machine has different characteristics.)", NO_ARG); // inexact (bit 12) } return ZDNN_STATUS_OK; } /// The actual routine for stickification, only does the following: /// NHWC -> NHWC, NCHW -> NHWC, HWCK -> HWCK /// Does NOT handle concatenated types. /// /// \param[in] in_buf data buffer to be stickified /// \param[out] ztensor Pointer to zdnn_ztensor to contain stickified data /// /// \return ZDNN_OK /// ZDNN_CONVERT_FAILURE /// zdnn_status transform_ztensor(const void *in_buf, zdnn_ztensor *ztensor) { uint64_t input_offset = 0; // moving position as the input is processed, in BYTES uint64_t output_offset = 0; // moving position as the output is processed, in BYTES short input_cell_size = get_data_type_size(ztensor->pre_transformed_desc->type); short input_cell_shift = input_cell_size / 2; /* * Stores the vector operation output directly into the stick_area. This * reduces the number of inefficient loops. */ uint32_t fields_to_convert; // number of fields to actually convert uint32_t nbr_fields_converted; // number of fields converted feclearexcept( FE_ALL_EXCEPT); /* clear exception flags set during conversion */ if (ztensor->transformed_desc->layout == ZDNN_NHWC) { // Expected layout is NHWC, stickify normally. Requires a single data // buffer. // loop invariant values uint64_t bytes_all_h = (uint64_t)ztensor->transformed_desc->dim3 * CEIL(ztensor->transformed_desc->dim2, AIU_STICKS_PER_PAGE) * AIU_PAGESIZE_IN_BYTES; uint64_t bytes_per_n = bytes_all_h * CEIL(ztensor->transformed_desc->dim1, AIU_2BYTE_CELLS_PER_STICK); if (ztensor->pre_transformed_desc->layout != ZDNN_NCHW) { // N for (uint32_t e4x = 0; e4x < ztensor->transformed_desc->dim4; e4x++) { // used for pushing out_offset from n to n+1 (i.e., + bytes_per_n) uint64_t out_offset_n = output_offset; // H for (uint32_t e3x = 0; e3x < ztensor->transformed_desc->dim3; e3x++) { // W for (uint32_t e2x = 0; e2x < ztensor->transformed_desc->dim2; e2x++) { // Prefetch (read) the next input buffer to be used. The HW should // "notice" our sequential accesses and continue them, so we won't // need to aggressively prefetch here. #if defined(__MVS__) __dcbt((void *)((uintptr_t)in_buf + input_offset)); #else __builtin_prefetch((void *)((uintptr_t)in_buf + input_offset), 0); #endif // used for pushing out_offset from w to w+1 (i.e., + // AIU_BYTES_PER_STICK) uint64_t out_offset_w = output_offset; // process each C-stick (i.e., every 64 elements or whatever // left in dim1) for (uint32_t e1x = 0; e1x < ztensor->transformed_desc->dim1; e1x += AIU_2BYTE_CELLS_PER_STICK) { // Prefetch to L1 newest offset to write that HW wouldn't // know about #if defined(__MVS__) __dcbtst((void *)((uintptr_t)ztensor->buffer + output_offset)); #else __builtin_prefetch( (void *)((uintptr_t)ztensor->buffer + output_offset), 1); #endif fields_to_convert = MIN((ztensor->transformed_desc->dim1 - e1x), AIU_2BYTE_CELLS_PER_STICK); nbr_fields_converted = convert_data_format( (void *)((uintptr_t)in_buf + input_offset), ztensor->pre_transformed_desc->type, (void *)((uintptr_t)ztensor->buffer + output_offset), ztensor->transformed_desc->type, fields_to_convert); if (nbr_fields_converted == 0) return ZDNN_STATUS_NO_MSG(ZDNN_CONVERT_FAILURE); // Release L1 cacheline for stick. The next "touch" will be // from NNPA, and it doesn't need L1 caching. #if defined(__MVS__) __dcbf((void *)((uintptr_t)ztensor->buffer + output_offset)); #else // No known equivalent fn without dropping to ASM.... #endif // push input_offset the next c-stick, fake the multiply by // bit-shifting input_offset += (nbr_fields_converted << input_cell_shift); // push output_offset to the next c-stick of the same super // c-stick, which is bytes_all_h number of bytes away. output_offset += bytes_all_h; } // output_offset was pushed around in dim1 loops, so reset it to // the next w output_offset = out_offset_w + AIU_BYTES_PER_STICK; } // after processing all the w-entries, go to the next 4k-boundary // location (aka stick padding) output_offset = (output_offset + (AIU_PAGESIZE_IN_BYTES - 1)) & (-AIU_PAGESIZE_IN_BYTES); } // output_offset was pushed around in the dims[2-0] loops, so reset it // to the next n output_offset = out_offset_n + bytes_per_n; } } else { // NCHW uint8_t sizeof_dlf16 = get_data_type_size(ZDNN_DLFLOAT16); // process the entire W number of entries at every pass fields_to_convert = ztensor->transformed_desc->dim2; // convert_data_format() will dump the converted entries here uint16_t temp_buff[fields_to_convert]; // number of bytes to jump from the beginning of the last C-stick to the // next page-boundary uint64_t padding = (ztensor->transformed_desc->dim2 % AIU_STICKS_PER_PAGE) ? (AIU_STICKS_PER_PAGE - (ztensor->transformed_desc->dim2 % AIU_STICKS_PER_PAGE)) * AIU_BYTES_PER_STICK : 0; for (uint32_t e4x = 0; e4x < ztensor->transformed_desc->dim4; e4x++) { uint64_t out_offset_n = output_offset; for (uint32_t e1x = 0; e1x < ztensor->transformed_desc->dim1; e1x++) { uint64_t output_offset_c = output_offset; for (uint32_t e3x = 0; e3x < ztensor->transformed_desc->dim3; e3x++) { // Prefetch (read) the next input buffer to be used. The HW should // "notice" our sequential accesses and continue them, so we won't // need to aggressively prefetch here. #if defined(__MVS__) __dcbt((void *)((uintptr_t)in_buf + input_offset)); #else __builtin_prefetch((void *)((uintptr_t)in_buf + input_offset), 0); #endif nbr_fields_converted = convert_data_format( (void *)((uintptr_t)in_buf + input_offset), ztensor->pre_transformed_desc->type, temp_buff, ztensor->transformed_desc->type, fields_to_convert); if (nbr_fields_converted == 0) return ZDNN_STATUS_NO_MSG(ZDNN_CONVERT_FAILURE); // read each entry in temp_buff contiguously and scatter write them // to stick area locations AIU_BYTES_PER_STICK bytes apart, i.e., // the same C location of the consecutive C-sticks for (uint32_t w = 0; w < fields_to_convert; w++) { // Prefetch to L1 newest offset to write that HW wouldn't // know about #if defined(__MVS__) __dcbtst((void *)((uintptr_t)ztensor->buffer + output_offset)); #else __builtin_prefetch( (void *)((uintptr_t)ztensor->buffer + output_offset), 1); #endif *(uint16_t *)((uintptr_t)ztensor->buffer + output_offset) = temp_buff[w]; // go to same C location of the next stick output_offset += AIU_BYTES_PER_STICK; } // go to the next 4k-boundary location (aka stick padding) output_offset += padding; // push input_offset the entire W number of entries input_offset += (nbr_fields_converted << input_cell_shift); } // go to the next C location of H = 0, W = 0 output_offset = output_offset_c + sizeof_dlf16; if (!((e1x + 1) % AIU_2BYTE_CELLS_PER_STICK)) { // but if we're at the end of C-stick, roll back 1 stick worth of // bytes and jump to the the next c-stick of that super c-stick, // which is bytes_all_h number of bytes away. output_offset = output_offset - AIU_BYTES_PER_STICK + bytes_all_h; } } // done with all the C/H/W, go to the next n output_offset = out_offset_n + bytes_per_n; } } } else if (ztensor->transformed_desc->layout == ZDNN_HWCK) { uint64_t bytes_per_h = CEIL(ztensor->transformed_desc->dim2, AIU_STICKS_PER_PAGE) * ztensor->transformed_desc->dim3 * AIU_PAGESIZE_IN_BYTES; uint64_t bytes_all_h = bytes_per_h * ztensor->transformed_desc->dim4; // H for (uint32_t e4x = 0; e4x < ztensor->transformed_desc->dim4; e4x++) { uint64_t out_offset_h = output_offset; // W for (uint32_t e3x = 0; e3x < ztensor->transformed_desc->dim3; e3x++) { // C for (uint32_t e2x = 0; e2x < ztensor->transformed_desc->dim2; e2x++) { uint64_t out_offset_c = output_offset; // process each K-stick (i.e., every 64 elements or whatever // left in dim1) for (uint32_t e1x = 0; e1x < ztensor->transformed_desc->dim1; e1x += AIU_2BYTE_CELLS_PER_STICK) { // Prefetch (read) the next input buffer to be used. The HW should // "notice" our sequential accesses and continue them, so we won't // need to aggressively prefetch here. // Also, Prefetch the new output offset to write that HW wouldn't // know about. #if defined(__MVS__) __dcbt((void *)((uintptr_t)in_buf + input_offset)); __dcbtst((void *)((uintptr_t)ztensor->buffer + output_offset)); #else __builtin_prefetch((void *)((uintptr_t)in_buf + input_offset), 0); __builtin_prefetch( (void *)((uintptr_t)ztensor->buffer + output_offset), 1); #endif fields_to_convert = MIN((ztensor->transformed_desc->dim1 - e1x), AIU_2BYTE_CELLS_PER_STICK); nbr_fields_converted = convert_data_format( (void *)((uintptr_t)in_buf + input_offset), ztensor->pre_transformed_desc->type, (void *)((uintptr_t)ztensor->buffer + output_offset), ztensor->transformed_desc->type, fields_to_convert); if (nbr_fields_converted == 0) return ZDNN_STATUS_NO_MSG(ZDNN_CONVERT_FAILURE); // push input_offset the next c-stick, fake the multiply by // bit-shifting input_offset += (nbr_fields_converted << input_cell_shift); // push output_offset to the next c-stick of the same super // c-stick, which is bytes_all_h number of bytes away. output_offset += bytes_all_h; } // output_offset was pushed around in dim1 loops, so reset it to // the next c output_offset = out_offset_c + AIU_BYTES_PER_STICK; } // after processing all the c-entries, go to the next 4k-boundary // location (aka stick padding) output_offset = (output_offset + (AIU_PAGESIZE_IN_BYTES - 1)) & (-AIU_PAGESIZE_IN_BYTES); } // output_offset was pushed around in the dims[2-0] loops, so reset it // to the next h output_offset = out_offset_h + bytes_per_h; } } else { // caller messed up if we ever arrive here return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Invalid layout for transformation: %s", get_data_layout_str(ztensor->transformed_desc->layout)); } /* handle any FP errors or return success */ zdnn_status fp_error = handle_fp_errors( fetestexcept(FE_UNDERFLOW | FE_INVALID | FE_INEXACT | FE_OVERFLOW)); if (fp_error != ZDNN_OK) { return fp_error; } // Update the tensor's format to indicate it has been stickified ztensor->is_transformed = true; return ZDNN_STATUS_OK; } // End transform_ztensor /// Specialized/Simplified version of transform_ztensor() that transforms 2 * a /// * b elements to (1, 1, 2*PADDED(a), b) shape /// /// \param[in] in_buf data buffer to be stickified /// \param[in] real_dim2 actual, non-PADDED dim2 value /// \param[out] ztensor Pointer to zdnn_ztensor to contain stickified data /// /// \return ZDNN_OK /// ZDNN_CONVERT_FAILURE /// zdnn_status transform_bidir_weight_ztensor(const void *in_buf, uint32_t real_dim2, zdnn_ztensor *ztensor) { // in_buf technically has shape of (2, real_dim2, dim1), meaning there are // 2 * real_dim2 * dim1 elements in it. we want to transform it to a ZDNN_2D // ztensor of shape (2 * PADDED(real_dim2), dim1) // // conceptually, this is as if we're inserting (PADDED(real_dim2) - real_dim2) // * dim1 of zeros after every dim1 elements, and transform the whole thing as // if it's (2, PADDED(real_dim2), dim1) to start with // // we'll emulate that effect by using mostly the same flow as // transform_ztensor()'s, and manipulate the output offset appropriately uint64_t input_offset = 0; uint64_t output_offset = 0; short input_cell_size = get_data_type_size(ztensor->pre_transformed_desc->type); short input_cell_shift = input_cell_size / 2; uint32_t fields_to_convert; uint32_t nbr_fields_converted; feclearexcept(FE_ALL_EXCEPT); // dim2 is always PADDED (i.e., multiples of AIU_2BYTE_CELLS_PER_STICK) and // divisible by AIU_STICKS_PER_PAGE uint64_t bytes_all_w = ztensor->transformed_desc->dim2 / AIU_STICKS_PER_PAGE * AIU_PAGESIZE_IN_BYTES; // exactly 2 rounds, each round processes (real_dim2 * dim1) elements for (uint32_t i = 0; i < 2; i++) { for (uint32_t e2x = 0; e2x < real_dim2; e2x++) { #if defined(__MVS__) __dcbt((void *)((uintptr_t)in_buf + input_offset)); #else __builtin_prefetch((void *)((uintptr_t)in_buf + input_offset), 0); #endif uint64_t out_offset_w = output_offset; for (uint32_t e1x = 0; e1x < ztensor->transformed_desc->dim1; e1x += AIU_2BYTE_CELLS_PER_STICK) { #if defined(__MVS__) __dcbtst((void *)((uintptr_t)ztensor->buffer + output_offset)); #else __builtin_prefetch((void *)((uintptr_t)ztensor->buffer + output_offset), 1); #endif fields_to_convert = MIN((ztensor->transformed_desc->dim1 - e1x), AIU_2BYTE_CELLS_PER_STICK); nbr_fields_converted = convert_data_format( (void *)((uintptr_t)in_buf + input_offset), ztensor->pre_transformed_desc->type, (void *)((uintptr_t)ztensor->buffer + output_offset), ztensor->transformed_desc->type, fields_to_convert); if (nbr_fields_converted == 0) return ZDNN_STATUS_NO_MSG(ZDNN_CONVERT_FAILURE); #if defined(__MVS__) __dcbf((void *)((uintptr_t)ztensor->buffer + output_offset)); #else #endif input_offset += (nbr_fields_converted << input_cell_shift); output_offset += bytes_all_w; } output_offset = out_offset_w + AIU_BYTES_PER_STICK; } // start the 2nd (and last) i-loop at offset (bytes_all_w / 2) output_offset = bytes_all_w / 2; } zdnn_status fp_error = handle_fp_errors( fetestexcept(FE_UNDERFLOW | FE_INVALID | FE_INEXACT | FE_OVERFLOW)); if (fp_error != ZDNN_OK) { return fp_error; } ztensor->is_transformed = true; return ZDNN_STATUS_OK; } /// Stickification when dim1 is <= 2. Only handles NHWC -> NHWC. /// /// \param[in] in_buf data buffer to be stickified /// \param[out] ztensor Pointer to zdnn_ztensor to contain stickified data /// /// \return ZDNN_OK /// ZDNN_CONVERT_FAILURE /// ZDNN_INVALID_TYPE /// zdnn_status transform_ztensor_smalldim1(const void *in_buf, zdnn_ztensor *ztensor) { uint64_t output_offset = 0; // moving position as the output is processed, in BYTES // input pointer that always moves forward, will be casted as either // vec_int16 or vec_float32 depends on input type const void *cur_input_data = in_buf; uint32_t rows_in_vec = (ztensor->transformed_desc->dim1 == 2) ? 4 : 8; // # of remaining fields to convert in the last group (if any) uint32_t remaining_el = (ztensor->transformed_desc->dim2 % rows_in_vec) * ztensor->transformed_desc->dim1; uint32_t remaining_bytes_to_get = remaining_el * get_data_type_size(ztensor->pre_transformed_desc->type); vec_int16 in_vector_16 = {0}; vec_float32 in_vector_32[2] = {{0}, {0}}; vec_int16 tmp_vector_16[2] = {{0}, {0}}; vec_int16 tmp_out = {0}; vec_int16 zero_vector16 = {0}; // loop invariant values uint64_t bytes_all_h = (uint64_t)ztensor->transformed_desc->dim3 * CEIL(ztensor->transformed_desc->dim2, AIU_STICKS_PER_PAGE) * AIU_PAGESIZE_IN_BYTES; uint64_t bytes_per_n = bytes_all_h * CEIL(ztensor->transformed_desc->dim1, AIU_2BYTE_CELLS_PER_STICK); feclearexcept( FE_ALL_EXCEPT); /* clear exception flags set during conversion */ // N for (uint32_t e4x = 0; e4x < ztensor->transformed_desc->dim4; e4x++) { // used for pushing out_offset from n to n+1 (i.e., + bytes_per_n) uint64_t out_offset_n = output_offset; // H for (uint32_t e3x = 0; e3x < ztensor->transformed_desc->dim3; e3x++) { // If there's more than 8 to convert, convert groups of 8 for (uint32_t e2x = 0; e2x < ztensor->transformed_desc->dim2 / rows_in_vec; e2x++) { #if defined(__MVS__) __dcbt(cur_input_data); #else __builtin_prefetch(cur_input_data, 0); #endif // convert + put 8 DLFLOAT16s in tmp_out switch (ztensor->pre_transformed_desc->type) { case FP16: tmp_out = aiu_vec_convert_from_fp16(*(vec_int16 *)(cur_input_data)); // advance 1 vector worth of entries cur_input_data = (vec_int16 *)(cur_input_data) + 1; break; case FP32: tmp_out = aiu_vec_round_from_fp32(*(vec_float32 *)(cur_input_data), *((vec_float32 *)cur_input_data + 1)); // advance 2 vectors worth of entries cur_input_data = (vec_float32 *)(cur_input_data) + 2; break; case BFLOAT: tmp_vector_16[0] = vec_mergeh(*(vec_int16 *)(cur_input_data), zero_vector16); tmp_vector_16[1] = vec_mergel(*(vec_int16 *)(cur_input_data), zero_vector16); tmp_out = aiu_vec_round_from_fp32((vec_float32)tmp_vector_16[0], (vec_float32)tmp_vector_16[1]); // advance 1 vector worth of entries cur_input_data = (vec_int16 *)(cur_input_data) + 1; break; default: // this is for completeness but we should never get here, called // should have already checked it before calling this function return ZDNN_STATUS(ZDNN_INVALID_TYPE, "unknown/invalid pre-transformed data type: %d", ztensor->pre_transformed_desc->type); break; } // copy the 8 DLFLOAT16s to stick areas, it's either 8x1 or 4x2 for (uint32_t i = 0; i < 8; i++) { *(uint16_t *)((uintptr_t)ztensor->buffer + output_offset) = tmp_out[i]; if (ztensor->transformed_desc->dim1 == 2) { i++; *((uint16_t *)((uintptr_t)ztensor->buffer + output_offset) + 1) = tmp_out[i]; } output_offset += AIU_BYTES_PER_STICK; } } if (remaining_el > 0) { // If none, skip the rest // put remaining_el # of DLFLOAT16s in tmp_out switch (ztensor->pre_transformed_desc->type) { case FP16: in_vector_16 = vec_load_len((uint16_t *)cur_input_data, remaining_bytes_to_get - 1); tmp_out = aiu_vec_convert_from_fp16(in_vector_16); break; case FP32: in_vector_32[0] = vec_load_len((uint32_t *)cur_input_data, remaining_bytes_to_get - 1); // grab the other half if (remaining_el > 4) { in_vector_32[1] = vec_load_len((uint32_t *)((vec_float32 *)cur_input_data + 1), (remaining_bytes_to_get - 16) - 1); } tmp_out = aiu_vec_round_from_fp32(in_vector_32[0], in_vector_32[1]); break; case BFLOAT: in_vector_16 = vec_load_len((uint16_t *)cur_input_data, remaining_bytes_to_get - 1); tmp_vector_16[0] = vec_mergeh(in_vector_16, zero_vector16); tmp_vector_16[1] = vec_mergel(in_vector_16, zero_vector16); tmp_out = aiu_vec_round_from_fp32((vec_float32)tmp_vector_16[0], (vec_float32)tmp_vector_16[1]); break; default: // this is for completeness but we should never get here, called // should have already checked it before calling this function return ZDNN_STATUS(ZDNN_INVALID_TYPE, "unknown/invalid pre-transformed data type: %d", ztensor->pre_transformed_desc->type); break; } cur_input_data = (void *)((uintptr_t)(cur_input_data) + remaining_bytes_to_get); // copy those DLFLOAT16s to stick areas for (uint32_t i = 0; i < remaining_el; i++) { *(uint16_t *)((uintptr_t)ztensor->buffer + output_offset) = tmp_out[i]; if (ztensor->transformed_desc->dim1 == 2) { i++; *((uint16_t *)((uintptr_t)ztensor->buffer + output_offset) + 1) = tmp_out[i]; } output_offset += AIU_BYTES_PER_STICK; } } // after processing all the w-entries, go to the next 4k-boundary // location (aka stick padding) output_offset = (output_offset + (AIU_PAGESIZE_IN_BYTES - 1)) & (-AIU_PAGESIZE_IN_BYTES); } // output_offset was pushed around in the dims[2-0] loops, so reset it // to the next n output_offset = out_offset_n + bytes_per_n; } /* handle any FP errors or return success */ zdnn_status fp_error = handle_fp_errors( fetestexcept(FE_UNDERFLOW | FE_INVALID | FE_INEXACT | FE_OVERFLOW)); if (fp_error != ZDNN_OK) { return fp_error; } // Update the tensor's format to indicate it has been stickified ztensor->is_transformed = true; return ZDNN_STATUS_OK; } /// Converts the input tensor to the supported stick format for /// execution by zDNN operations. /// /// \param[out] tensor Pointer to zdnn_ztensor to contain stickified /// data \param[in] ... 1, 3, or 4 data buffers to be stickified. (1 for /// most, 3 for /// ZRH, 4 for FICO) /// /// \return ZDNN_OK /// ZDNN_INVALID_FORMAT /// ZDNN_INVALID_LAYOUT /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_BUFFER /// ZDNN_INVALID_STATE /// ZDNN_CONVERT_FAILURE /// zdnn_status zdnn_transform_ztensor(zdnn_ztensor *ztensor, ...) { zdnn_status status; LOG_DEBUG("zdnn_transform_ztensor layout %s -> %s", get_data_layout_str(ztensor->pre_transformed_desc->layout), get_data_layout_str(ztensor->transformed_desc->layout)); LOG_DEBUG("zdnn_transform_ztensor type %s -> %s", get_data_type_str(ztensor->pre_transformed_desc->type), get_data_type_str(ztensor->transformed_desc->type)); if ((status = verify_pre_transformed_descriptor( ztensor->pre_transformed_desc)) != ZDNN_OK) { return status; } if ((status = verify_transformed_descriptor(ztensor->transformed_desc)) != ZDNN_OK) { return status; } /* * Check for buffer issues. Return an error if: * * a) buffer is a NULL pointer * b) buffer does not start on a 4k boundary * c) buffer_size is smaller than what's needed */ if (!ztensor->buffer || (uintptr_t)ztensor->buffer & 0xFFF || ztensor->buffer_size < zdnn_getsize_ztensor(ztensor->transformed_desc)) { return ZDNN_STATUS_NO_MSG(ZDNN_INVALID_BUFFER); } // Make sure the buffer doesn't have stickified data if (ztensor->is_transformed) { return ZDNN_STATUS(ZDNN_INVALID_STATE, "Attempted to transform data into a tensor that is " "already transformed.", NO_ARG); } va_list argptr; va_start(argptr, ztensor); if (ztensor->pre_transformed_desc->layout != ZDNN_NCHW && ztensor->transformed_desc->layout == ZDNN_NHWC && ztensor->transformed_desc->dim1 <= 2) { const void *data = va_arg(argptr, void *); status = transform_ztensor_smalldim1(data, ztensor); } else if (ztensor->transformed_desc->layout == ZDNN_NHWC || ztensor->transformed_desc->layout == ZDNN_HWCK) { const void *data = va_arg(argptr, void *); status = transform_ztensor(data, ztensor); } else if (ztensor->transformed_desc->layout == ZDNN_FICO || ztensor->transformed_desc->layout == ZDNN_ZRH || ztensor->transformed_desc->layout == ZDNN_BIDIR_FICO || ztensor->transformed_desc->layout == ZDNN_BIDIR_ZRH) { do { // do not just return when error, use break instead. we need to // va_end() at the end uint32_t num_slices = ztensor->transformed_desc->dim4; uint64_t gate_num_elements = get_num_elements(ztensor, ELEMENTS_PRE_SINGLE_GATE); uint64_t gate_data_size = gate_num_elements * get_data_type_size(ztensor->pre_transformed_desc->type); uint64_t sliced_gate_data_size = gate_data_size / num_slices; // 4 gates for FICO otherwise 3 gates (ZRH) uint8_t num_gates = get_data_layout_num_gates(ztensor->transformed_desc->layout); zdnn_tensor_desc temp_pre_tfrmd_desc, temp_tfrmd_desc; // Copy the real pre_transformed_desc into temp so we can // manipulate it without changing the original. memcpy(&temp_pre_tfrmd_desc, ztensor->pre_transformed_desc, sizeof(zdnn_tensor_desc)); // Manipulate the temp pre_trfmd_desc. // // FICO/ZRH are concatenated horizontally. The BIDIR_* variants // are also concatenated vertically. // // To build such a concatenated ztensor, we process each "slice" // (the promoted dim4) of each gate individually. This way the // final ztensor can be built to be sliceable along dim4 and each // slice will have a complete set of concatenated gates. // // pre_trfmd --> slice shape // ------------------------------------------------------------------ // 3DS: (a, b, c) --> 2D: (1, b, c) (FICO/ZRH) // 2D: (1, 1, 2*PADDED(b/2), c) (BIDIR_FICO/ZRH) // 2DS: (b, c) --> 1D: (c) (FICO/ZRH) // --> (no case for BIDIR_*) // // The slices will be sent to transform_ztensor(), or // transform_bidir_weight_ztensor() if ZDNN_BIDIR_* layouts uint32_t pre_trfmd_slices; if (ztensor->pre_transformed_desc->layout == ZDNN_3DS) { pre_trfmd_slices = ztensor->pre_transformed_desc->dim3; if (ztensor->transformed_desc->layout == ZDNN_BIDIR_FICO || ztensor->transformed_desc->layout == ZDNN_BIDIR_ZRH) { // dim2 has to be some multiple of 2 because of concatenation if (ztensor->pre_transformed_desc->dim2 & 1) { status = ZDNN_STATUS(ZDNN_INVALID_SHAPE, "when PREV_LAYER_BIDIR and " "USAGE_WEIGHTS, pre-transformed dim2 " "must be multiples of 2 (found: %d)", ztensor->pre_transformed_desc->dim2); break; } temp_pre_tfrmd_desc.dim4 = 1; temp_pre_tfrmd_desc.dim3 = 1; temp_pre_tfrmd_desc.dim2 = 2 * PADDED(temp_pre_tfrmd_desc.dim2 / 2); } temp_pre_tfrmd_desc.layout = ZDNN_2D; } else if (ztensor->pre_transformed_desc->layout == ZDNN_2DS) { pre_trfmd_slices = ztensor->pre_transformed_desc->dim2; temp_pre_tfrmd_desc.layout = ZDNN_1D; } else { status = ZDNN_STATUS( ZDNN_INVALID_LAYOUT, "layout %s is not supported for concatenation", get_data_layout_str(ztensor->pre_transformed_desc->layout)); break; } // Check that the pre_tfrmd and tfrmd descriptors indicate the same // number of expected slices. if (pre_trfmd_slices != num_slices) { status = ZDNN_STATUS(ZDNN_INVALID_SHAPE, "the pre_transformed_desc's outermost " "dimension (%d) must be " "the same as transformed_desc's dim4 (%d)", pre_trfmd_slices, num_slices); break; } // Create a non-sliced, non-horizontally-concatenated trfmd_desc // by using the modified temp_pre_tfrmd_layout. if ((status = zdnn_generate_transformed_desc( &temp_pre_tfrmd_desc, &temp_tfrmd_desc)) != ZDNN_OK) { break; } uint64_t sliced_gate_buffer_size = zdnn_getsize_ztensor(&temp_tfrmd_desc); // Save the gate data for slicing later. // (e.g., LSTM) va_arg order: F (FWD,BWD), I (FWD,BWD), C...etc. void *gate_data[num_gates]; for (uint8_t i = 0; i < num_gates; i++) { gate_data[i] = va_arg(argptr, void *); } // Create a temporary ztensor to be used to call // transform_ztensor() multiple times with, as if it's not // horizontally-concatenated. zdnn_ztensor temp_ztensor; // Setup the temp ztensor, with a non-sliced, // non-horizontally-concatenated buffer_size zdnn_init_ztensor(&temp_pre_tfrmd_desc, &temp_tfrmd_desc, &temp_ztensor); temp_ztensor.buffer = ztensor->buffer; temp_ztensor.buffer_size = sliced_gate_buffer_size; // Concatenated tensors require zero padding between the // horizontal concatenations, while technically not required for // the verticals. However, zero out the entire concatened (not // temp) buffer for efficiency. size_t total_buffer_size = temp_ztensor.buffer_size * num_slices * num_gates; memset(ztensor->buffer, 0, total_buffer_size); /* Loop sliced_gate_data array to stickify the input data. Because * of how sliced_gate_data was built as a 2D array, we can jump * around various locations of the original inputs data and read * each value only once while building the output ztensor to be in * the final desired order. * * This converts the value order from the input arrays from: * slice 0 of gate 0 * slice 1 of gate 0 * slice 0 of gate 1 * slice 1 of gate 1 * ... * * to the following order in the final output ztensor: * slice 0 of gate 0 * slice 0 of gate 1 * ... * slice 1 of gate 0 * slice 1 of gate 1 * ... */ for (uint32_t slice = 0; slice < num_slices; slice++) { for (uint8_t gate = 0; gate < num_gates; gate++) { // Points to a single slice of a single gate data. const void *gate_data_slice = (void *)((uintptr_t)gate_data[gate] + (slice * sliced_gate_data_size)); // Transform the current slice of the current gate into final // ztensor if (ztensor->transformed_desc->layout != ZDNN_BIDIR_FICO && ztensor->transformed_desc->layout != ZDNN_BIDIR_ZRH) { status = transform_ztensor(gate_data_slice, &temp_ztensor); } else { // transform_bidir_weight_ztensor() wants the actual b/2, // not the PADDED one in temp_ztensor->dim2 status = transform_bidir_weight_ztensor( gate_data_slice, ztensor->pre_transformed_desc->dim2 / 2, &temp_ztensor); } if (status != ZDNN_OK) { LOG_ERROR("transform_ztensor() on slice %d of gate data %d " "failed, status = %08x (%s)\n", slice, gate, status, zdnn_get_status_message(status)); break; } // Increment the temp_ztensor buffer by one sliced gate size // so we write to the correct location in the final output // ztensor. temp_ztensor.buffer = (void *)((uintptr_t)(temp_ztensor.buffer) + sliced_gate_buffer_size); // Reset temp_ztensor is_transformed so we can recursively // call zdnn_transform_ztensor to process each slice of each // gate. temp_ztensor.is_transformed = false; } if (status != ZDNN_OK) { break; } } if (status == ZDNN_OK) { // Set that the output ztensor has completed transformation. ztensor->is_transformed = true; } } while (false); } else { status = ZDNN_STATUS( ZDNN_INVALID_LAYOUT, "Invalid layout for transformation: %s", get_data_layout_str(ztensor->transformed_desc->layout)); } va_end(argptr); return status; } // ------------------------------------------------------------------------------------------------ /// The actual routine for unstickification, only does the following: /// NHWC -> NHWC, NHWC -> NCHW /// Does NOT handle concatenated types nor HWCK /// /// \param[in] ztensor Pointer to zdnn_ztensor, containing data to be /// unstickified /// \param[out] out_buf data buffer to unstickify to /// /// \return ZDNN_OK /// ZDNN_CONVERT_FAILURE /// zdnn_status transform_origtensor(const zdnn_ztensor *ztensor, void *out_buf) { uint64_t output_offset = 0; // moving position as the output is processed, in BYTES uint64_t input_offset = 0; // moving position as the input is processed, in BYTES short output_cell_size = get_data_type_size(ztensor->pre_transformed_desc->type); short output_cell_shift = output_cell_size / 2; uint32_t fields_to_convert; // number of fields to actually convert uint32_t nbr_fields_converted; // number of fields converted // loop invariant values uint64_t bytes_per_h = CEIL(ztensor->transformed_desc->dim2, AIU_STICKS_PER_PAGE) * AIU_PAGESIZE_IN_BYTES; uint64_t bytes_all_h = (uint64_t)ztensor->transformed_desc->dim3 * bytes_per_h; uint64_t bytes_per_n = bytes_all_h * CEIL(ztensor->transformed_desc->dim1, AIU_2BYTE_CELLS_PER_STICK); feclearexcept( FE_ALL_EXCEPT); /* clear exception flags set during conversion */ if (ztensor->pre_transformed_desc->layout != ZDNN_NCHW) { for (uint32_t e4x = 0; e4x < ztensor->transformed_desc->dim4; e4x++) { // used for pushing input_offset from n to n+1 (i.e., + // bytes_per_n) uint64_t in_offset_n = input_offset; for (uint32_t e3x = 0; e3x < ztensor->transformed_desc->dim3; e3x++) { for (uint32_t e2x = 0; e2x < ztensor->transformed_desc->dim2; e2x++) { // used for pushing input from w to w+1 (i.e., + // AIU_BYTES_PER_STICK) uint64_t in_offset_w = input_offset; // process each c-stick (i.e., every 64 elements or whatever // left in dim1) for (uint32_t e1x = 0; e1x < ztensor->transformed_desc->dim1; e1x += AIU_2BYTE_CELLS_PER_STICK) { // Prefetch (read) the next input buffer to be used. The HW // should "notice" our sequential accesses and continue // them, so we won't need to aggressively prefetch here. // Also, Prefetch the new output offset to write that HW // wouldn't know about. #if defined(__MVS__) __dcbt((void *)((uintptr_t)ztensor->buffer + input_offset)); __dcbtst((void *)((uintptr_t)out_buf + output_offset)); #else __builtin_prefetch( (void *)((uintptr_t)ztensor->buffer + input_offset), 0); __builtin_prefetch((void *)((uintptr_t)out_buf + output_offset), 1); #endif fields_to_convert = MIN((ztensor->transformed_desc->dim1 - e1x), AIU_2BYTE_CELLS_PER_STICK); nbr_fields_converted = convert_data_format( (void *)((uintptr_t)ztensor->buffer + input_offset), ztensor->transformed_desc->type, (void *)((uintptr_t)out_buf + output_offset), ztensor->pre_transformed_desc->type, fields_to_convert); if (nbr_fields_converted == 0) return ZDNN_STATUS_NO_MSG(ZDNN_CONVERT_FAILURE); // push output_offset the next c-stick, fake the multiply by // bit-shifting output_offset += (nbr_fields_converted << output_cell_shift); // push input_offset to the next c-stick of the same super // c-stick, which is bytes_all_h number of bytes away. input_offset += bytes_all_h; } // input_offset was pushed around in dim1 loops, so reset it // to the next w input_offset = in_offset_w + AIU_BYTES_PER_STICK; } // after processing all the w-entries, go to the next // 4k-boundary location (aka stick padding) input_offset = (input_offset + (AIU_PAGESIZE_IN_BYTES - 1)) & (-AIU_PAGESIZE_IN_BYTES); } // input_offset was pushed around in the dims[2-0] loops, so reset // it to the next n input_offset = in_offset_n + bytes_per_n; } } else { // the loops are in N -> C -> H -> W order in order to write the W // entries contiguously // N for (uint32_t e4x = 0; e4x < ztensor->transformed_desc->dim4; e4x++) { // used for pushing input_offset from n to n+1 (i.e., + // bytes_per_n) uint64_t in_offset_n = input_offset; // C for (uint32_t e1x = 0; e1x < ztensor->transformed_desc->dim1; e1x++) { // used for pushing input from c to c+1 uint64_t in_offset_c = input_offset; // H for (uint32_t e3x = 0; e3x < ztensor->transformed_desc->dim3; e3x++) { // Prefetch (read) the next input buffer to be used. The HW // should "notice" our sequential accesses and continue them, // so we won't need to aggressively prefetch here. Also, // Prefetch the new output offset to write that HW wouldn't // know about. #if defined(__MVS__) __dcbt((void *)((uintptr_t)ztensor->buffer + input_offset)); __dcbtst((void *)((uintptr_t)out_buf + output_offset)); #else __builtin_prefetch( (void *)((uintptr_t)ztensor->buffer + input_offset), 0); __builtin_prefetch((void *)((uintptr_t)out_buf + output_offset), 1); #endif // send all the W entries of a given set of N/H/C to // convert_data_format_in_stride(), the entries are // AIU_BYTES_PER_STICK entries apart fields_to_convert = ztensor->transformed_desc->dim2; nbr_fields_converted = convert_data_format_in_stride( (void *)((uintptr_t)ztensor->buffer + input_offset), ztensor->transformed_desc->type, (void *)((uintptr_t)out_buf + output_offset), ztensor->pre_transformed_desc->type, fields_to_convert, AIU_2BYTE_CELLS_PER_STICK); if (nbr_fields_converted == 0) return ZDNN_STATUS_NO_MSG(ZDNN_CONVERT_FAILURE); // push input_offset to the next H input_offset += bytes_per_h; // push output_offset to the next H, fake the multiply by // bit-shifting output_offset += (nbr_fields_converted << output_cell_shift); } // push in_offset_c to the next C in_offset_c += get_data_type_size(ztensor->transformed_desc->type); // go to the next C-stick if we're at the end of the current // C-stick if (!((e1x + 1) % AIU_2BYTE_CELLS_PER_STICK)) { in_offset_c = in_offset_c - AIU_BYTES_PER_STICK + bytes_all_h; } input_offset = in_offset_c; } // reset input_offset to the next n input_offset = in_offset_n + bytes_per_n; } } // handle any FP errors or return success return handle_fp_errors( fetestexcept(FE_UNDERFLOW | FE_INVALID | FE_INEXACT | FE_OVERFLOW)); } // End transform_origtensor /// Unstickification when dim1 is <= 2. Only handles NHWC -> NHWC. /// /// \param[in] ztensor Pointer to zdnn_ztensor, containing data to be /// unstickified /// \param[out] out_buf data buffer to unstickify to /// /// \return ZDNN_OK /// ZDNN_CONVERT_FAILURE /// ZDNN_INVALID_TYPE /// zdnn_status transform_origtensor_smalldim1(const zdnn_ztensor *ztensor, void *out_buf) { uint64_t input_offset = 0; // moving position as the input is processed, in BYTES // Define a input vector. a Vector Register can fit 8 int16 fields vec_int16 input_data = {0}; // output pointer that always moves forward, will be casted as either // vec_int16 or vec_float32 depends on output type // ** Note: adding 1 to a vector pointer will move it ahead 16 bytes void *output_data = out_buf; // loop invariant values uint64_t bytes_per_h = CEIL(ztensor->transformed_desc->dim2, AIU_STICKS_PER_PAGE) * AIU_PAGESIZE_IN_BYTES; uint64_t bytes_all_h = (uint64_t)ztensor->transformed_desc->dim3 * bytes_per_h; uint64_t bytes_per_n = bytes_all_h * CEIL(ztensor->transformed_desc->dim1, AIU_2BYTE_CELLS_PER_STICK); // Set indicies from which values need to be collected for conversion vector unsigned int idx, idx_left, idx_right; /* load one vector worth of DLFLOAT16 entries (8). if dim1 == 2 that's 4 rows of entries (rows_in_vec) loop e2x = 0 --> e2x = 1 --LEFT-|-RIGHT-|----------- --LEFT-|-RIGHT-|----------- | 0 | 1 | ... | | 256 | 257 | ... | | 64 | 65 | ... | --> | 320 | 321 | ... | | 128 | 129 | ... | | 384 | 385 | ... | | 192 | 193 | ... | | 448 | 449 | ... | if dim1 == 1 then 8 rows --------------------------- --------------------------- | 0 | ... | | 512 | ... | LEFT | 64 | ... | | 576 | ... | LEFT | 128 | ... | | 640 | ... | LEFT | 192 | ... | --> | 704 | ... | LEFT | 256 | ... | | 768 | ... | RIGHT | 320 | ... | | 832 | ... | RIGHT | 384 | ... | | 896 | ... | RIGHT | 448 | ... | | 960 | ... | RIGHT */ // ** xlc requires vector shift right operand to be unsigned long vector unsigned int idx_left_incr = (ztensor->transformed_desc->dim1 == 2) ? (vector unsigned int){0, 1, 64, 65} : (vector unsigned int){0, 1, 2, 3} << 6ul; vector unsigned int idx_right_incr = (ztensor->transformed_desc->dim1 == 2) ? (vector unsigned int){128, 129, 192, 193} : (vector unsigned int){4, 5, 6, 7} << 6ul; uint32_t rows_in_vec; unsigned long vec_shift; if (ztensor->transformed_desc->dim1 == 2) { rows_in_vec = 4; // when rows_in_vec == 4, groups are 2^8 entries apart vec_shift = 8; } else { rows_in_vec = 8; // when rows_in_vec == 8, groups are 2^9 entries apart vec_shift = 9; } // # of remaining fields to convert in the last group (if any) uint32_t remaining_el = (ztensor->transformed_desc->dim2 % rows_in_vec) * ztensor->transformed_desc->dim1; uint32_t remaining_bytes_to_set = remaining_el * get_data_type_size(ztensor->pre_transformed_desc->type); vec_int16 tmp_out_16; vec_float32 tmp_out_left, tmp_out_right; vec_char8 selection_vector = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; feclearexcept( FE_ALL_EXCEPT); /* clear exception flags set during conversion */ for (uint32_t e4x = 0; e4x < ztensor->transformed_desc->dim4; e4x++) { // used for pushing input_offset from n to n+1 (i.e., + bytes_per_n) uint64_t in_offset_n = input_offset; for (uint32_t e3x = 0; e3x < ztensor->transformed_desc->dim3; e3x++) { uint16_t *in_data = (uint16_t *)((uintptr_t)ztensor->buffer + input_offset); uint32_t e2x; // If there's more than 8 to convert, convert groups of 8 // DLFLOAT16s for (e2x = 0; e2x < ztensor->transformed_desc->dim2 / rows_in_vec; e2x++) { idx = (vector unsigned int){e2x, e2x, e2x, e2x} << vec_shift; idx_left = idx + idx_left_incr; idx_right = idx + idx_right_incr; #if defined(__MVS__) __dcbtst((void *)output_data); #else __builtin_prefetch((void *)output_data, 1); #endif input_data = (vec_int16){in_data[idx_left[0]], in_data[idx_left[1]], in_data[idx_left[2]], in_data[idx_left[3]], in_data[idx_right[0]], in_data[idx_right[1]], in_data[idx_right[2]], in_data[idx_right[3]]}; switch (ztensor->pre_transformed_desc->type) { case FP16: *((vec_int16 *)(output_data)) = aiu_vec_convert_to_fp16(input_data); // bump ptr to start of next vector (8 float16s = 16 bytes = // +1) output_data = (vec_int16 *)output_data + 1; break; case FP32: aiu_vec_lengthen_to_fp32((vec_int16)input_data, (vec_float32 *)output_data, (vec_float32 *)output_data + 1); // bump ptr to start of next pair of vector (8 float32s = 32 // bytes = +2) output_data = (vec_float32 *)output_data + 2; break; case BFLOAT: aiu_vec_lengthen_to_fp32((vec_int16)input_data, &tmp_out_left, &tmp_out_right); *((vec_int16 *)(output_data)) = (vec_int16)vec_perm((vec_char8)(tmp_out_left), (vec_char8)(tmp_out_right), selection_vector); // bump ptr to start of next vector (8 bfloats = 16 bytes = // +1) output_data = (vec_int16 *)output_data + 1; break; default: // this is for completeness but we should never get here, called // should have already checked it before calling this function return ZDNN_STATUS(ZDNN_INVALID_TYPE, "unknown/invalid pre-transformed data type: %d", ztensor->pre_transformed_desc->type); break; } } // End of for loop // e2x at this point points to the group with remaining fields (if // any) if (remaining_el > 0) { // If none, skip the rest idx = (vector unsigned int){e2x, e2x, e2x, e2x} << vec_shift; idx_left = idx + idx_left_incr; idx_right = idx + idx_right_incr; // input_data[] should contain either 0s or residual values from the // previous loop, so no need to fill the entries that we don't need switch (remaining_el) { // remaining_el will never be 8 case 7: // fill input_data[6-0] input_data[6] = in_data[idx_right[2]]; case 6: // fill input_data[5-0] input_data[5] = in_data[idx_right[1]]; case 5: input_data[4] = in_data[idx_right[0]]; case 4: input_data[3] = in_data[idx_left[3]]; case 3: input_data[2] = in_data[idx_left[2]]; case 2: input_data[1] = in_data[idx_left[1]]; default: // all scenarios fill at least input_data[0] input_data[0] = in_data[idx_left[0]]; }; // 1) convert the remaining entries and store to tmp_out_x // 2) vec_store_len() from tmp_out_x to output_data // 3) advances output_data ptr switch (ztensor->pre_transformed_desc->type) { case FP16: tmp_out_16 = aiu_vec_convert_to_fp16(input_data); vec_store_len(tmp_out_16, (uint16_t *)output_data, remaining_bytes_to_set - 1); output_data = (void *)((uintptr_t)output_data + remaining_bytes_to_set); break; case FP32: aiu_vec_lengthen_to_fp32((vec_int16)input_data, &tmp_out_left, &tmp_out_right); // Store left FP32 to output (1 to 4 values), Length is offset // by 1. vec_store_len() stores 16 bytes at the most so it // won't matter if remaining_bytes_to_set > 16 vec_store_len(tmp_out_left, (uint32_t *)output_data, remaining_bytes_to_set - 1); // If there's more than 4 to convert (remaining_bytes_to_set > // 16), store values 5-8 if (remaining_el > 4) { vec_store_len(tmp_out_right, (uint32_t *)((vec_float32 *)output_data + 1), (remaining_bytes_to_set - 16) - 1); } output_data = (void *)((uintptr_t)output_data + remaining_bytes_to_set); break; case BFLOAT: aiu_vec_lengthen_to_fp32((vec_int16)input_data, &tmp_out_left, &tmp_out_right); tmp_out_16 = (vec_int16)vec_perm((vec_char8)tmp_out_left, (vec_char8)tmp_out_right, selection_vector); vec_store_len(tmp_out_16, (uint16_t *)output_data, remaining_bytes_to_set - 1); output_data = (void *)((uintptr_t)output_data + remaining_bytes_to_set); break; default: // this is for completeness but we should never get here, called // should have already checked it before calling this function return ZDNN_STATUS(ZDNN_INVALID_TYPE, "unknown/invalid pre-transformed data type: %d", ztensor->pre_transformed_desc->type); break; } } // add to input offset all the bytes in h (already aligned to page // size) input_offset += bytes_per_h; } // input_offset was pushed around in the dims[2-0] loops, so reset // it to the next n input_offset = in_offset_n + bytes_per_n; } // handle any FP errors or return success return handle_fp_errors( fetestexcept(FE_UNDERFLOW | FE_INVALID | FE_INEXACT | FE_OVERFLOW)); } // End transform_origtensor_smalldim1 /// Given a ztensor and target data buffer, fill the target data buffer /// with converted data from the sticks /// /// \param[out] ztensor Pointer to zdnn_ztensor, containing data to be /// unstickified /// \param[in] out_buf data buffer to store unstickified data /// /// \return ZDNN_OK /// ZDNN_INVALID_FORMAT /// ZDNN_INVALID_LAYOUT /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_BUFFER /// ZDNN_INVALID_STATE /// ZDNN_CONVERT_FAILURE /// zdnn_status zdnn_transform_origtensor(const zdnn_ztensor *ztensor, void *out_buf) { zdnn_status status = ZDNN_OK; // Assume success if ((status = verify_pre_transformed_descriptor( ztensor->pre_transformed_desc)) != ZDNN_OK) { return status; } // same check as in stickify except no need to check buffer_size if (!ztensor->buffer || (uintptr_t)ztensor->buffer & 0xFFF) { return ZDNN_STATUS_NO_MSG(ZDNN_INVALID_BUFFER); } // Make sure the buffer has stickified data if (ztensor->is_transformed == false) { return ZDNN_STATUS(ZDNN_INVALID_STATE, "Tensor not already transformed.", NO_ARG); } // we don't do 4DKERNEL unstickify if (ztensor->transformed_desc->format != ZDNN_FORMAT_4DFEATURE) { return ZDNN_STATUS(ZDNN_INVALID_FORMAT, "Only transforming feature tensor is supported", NO_ARG); } // We expect the type to be DLFLOAT16 if (ztensor->transformed_desc->type != ZDNN_DLFLOAT16) { return ZDNN_STATUS(ZDNN_INVALID_TYPE, "Only transforming from ZDNN_DLFLOAT16 type is " "supported", NO_ARG); } if (ztensor->transformed_desc->layout == ZDNN_NHWC) { if (ztensor->pre_transformed_desc->layout != ZDNN_NCHW && ztensor->transformed_desc->dim1 <= 2) { if ((status = transform_origtensor_smalldim1(ztensor, out_buf)) != ZDNN_OK) { LOG_ERROR("transform_origtensor_smalldim1() (ZDNN_NHWC) failed, " "status = %08x (%s)\n", status, zdnn_get_status_message(status)); } } else if ((ztensor->pre_transformed_desc->layout == ZDNN_4DS) && (ztensor->pre_transformed_desc->dim3 != 1)) { /* s = hidden state size e.g., all-timesteps bidir hn output: pre_transformed_desc shape of (ts, 2, b, s) (ZDNN_4DS) transformed desc shape of (ts, 1, b, out_pad) (ZDNN_NHWC) where out_pad = 2 * PADDED(s) (horizontally concatenated output with padding between directions) to unstickify, build a temp ztensor with equivalent: tensor | tfrmd (dim4, 3, 2, 1) | equivalent ---------------+------------------------------------- hn_output | (ts, 1, b, out_pad) | (ts * 2, 1, b, s) | (1, 1, b, out_pad) | (2, 1, b, s) cf_output | (1, 1, b, out_pad) | (2, 1, b, s) */ zdnn_ztensor temp_ztensor; zdnn_tensor_desc temp_trans_desc; // only pre-transformed dim3 of 2 (BI-directional) is supported if (ztensor->pre_transformed_desc->dim3 != 2) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "found ZDNN_4DS but pre-transformed dim3 is neither " "2 nor 1 (found: %d)", ztensor->pre_transformed_desc->dim3); } // make sure both pre-transformed and transformed agree with each // other wrt all timesteps vs final-only timestep if (ztensor->pre_transformed_desc->dim4 != ztensor->transformed_desc->dim4) { return ZDNN_STATUS( ZDNN_INVALID_SHAPE, "the pre_transformed_desc's dim4 (%d) not the same as " "transformed_desc's dim4 (%d)", ztensor->pre_transformed_desc->dim4, ztensor->transformed_desc->dim4); } memcpy(&temp_ztensor, ztensor, sizeof(zdnn_ztensor)); memcpy(&temp_trans_desc, ztensor->transformed_desc, sizeof(zdnn_tensor_desc)); temp_ztensor.transformed_desc = &temp_trans_desc; // old transformed: (ts, 1, b, out_pad) // new transformed: (ts * 2, 1, b, s) temp_trans_desc.dim4 *= 2; // pre_transformed_desc->dim1 is the only place we can obtain the // non-padded s value temp_trans_desc.dim1 = temp_ztensor.pre_transformed_desc->dim1; temp_trans_desc.layout = ZDNN_NHWC; if ((status = transform_origtensor(&temp_ztensor, out_buf)) != ZDNN_OK) { LOG_ERROR("transform_origtensor() failed (bidir output), status = " "%08x (%s)\n", status, zdnn_get_status_message(status)); } } else { if ((status = transform_origtensor(ztensor, out_buf)) != ZDNN_OK) { LOG_ERROR("transform_origtensor() (ZDNN_NHWC) failed, status = " "%08x (%s)\n", status, zdnn_get_status_message(status)); } } return status; } else { return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Invalid layout for transformation: %s", get_data_layout_str(ztensor->transformed_desc->layout)); } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/sym_checker.awk���������������������������������������������������������������������0000664�0000000�0000000�00000024741�14364043643�0016312�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # The sym_checker.awk file cross checks the symbols declared in zdnn.h, # zdnn.map and the exported symbols of the shared library. # # Usage: # awk [ -v debug=<DBG> ] -f <ZDNN_H_PREPROCESSED> <ZDNN_MAP> <ZDNN_DYNSYMS> # <ZDNN_H_PREPROCESSED>: gcc -E <src>/zdnn/zdnn.h -o zdnn.i # <ZDNN_MAP>: <src>/zdnn/zdnn.map # <ZDNN_DYNSYMS>: readelf -W --dyn-syms libzdnn.so # <DBG>: To get debug-output, run with debug > 0 # (increase number to get more verbose output) # # In case of errors, those are dumped and return-code is != 0 function dbg(level, msg) { if (debug >= level) print "#"fi"."FNR": "msg } function fail(msg) { fails++ print "ERROR #"fails" in "curr_file":"FNR": "msg } BEGIN { if (debug == "") debug=0 # The input lines are dumped starting at this debug level # see dbg(debug_line, ...) debug_line=3 # file-index: 1 is the first input-file fi=0 curr_file="BEGIN" use_argv_file=0 fi_hdr=1 hdr_file="zdnn.h" fi_map=2 map_file="zdnn.map" fi_dyn=3 dyn_file=".dynsym-symbol-table" dbg(0, "BEGIN of sym_checker.awk") hdr_line="" hdr_in_zdnn_h=0 map_version_node_reset() map_tasks_cnt=0 fails=0 } FNR == 1 { fi++ if (use_argv_file) { curr_file=ARGV[fi] if (fi == fi_hdr) hdr_file=curr_file else if (fi == fi_map) map_file=curr_file else if (fi == fi_dyn) dyn_file=curr_file } else { if (fi == fi_hdr) curr_file=hdr_file else if (fi == fi_map) curr_file=map_file else if (fi == fi_dyn) curr_file=dyn_file } dbg(0, "Processing file "ARGV[fi]" => "curr_file) } ################################################################################ # Processing <ZDNN_H_PREPROCESSED>: variable-, function-prefix=hdr ################################################################################ function hdr_process_line(line, _line_words, _sym) { # Skip typedefs if (substr(line, 1, length("typedef")) == "typedef") { dbg(1, "=> Skip typedef") return } # Remove "((*))", "(*)" and "[*]" sub(/\(\(.*\)\)/, "", line) sub(/\(.*\)/, "", line) sub(/\[.*\]/, "", line) # Remove trailing ";" and whitespaces before sub(/ *;$/, "", line) # Get the last word split(line, _line_words) _sym=_line_words[length(_line_words)] # Remove leading * sub(/^\*/, "", _sym) if (_sym in hdr_syms) { fail("Found a duplicate symbol "_sym" in "hdr_file) } else { dbg(1, "Add to hdr_syms: "_sym) # 0 / 1: if found as default symbol (@@ZDNN) in .dynsym hdr_syms[_sym]=0 } } fi == fi_hdr && /^#/ { dbg(debug_line, "hdr-comment: "$0) # Matching lines: # # 28 "/usr/include/inttypes.h" 2 3 4 # # 23 "../zdnn/zdnn.h" 2 hdr_basename=$3 # Strip all double quotes gsub("\"", "", hdr_basename) # '/PATH/TO/zdnn.h' => 'zdnn.h' sub(".*/", "", hdr_basename) if (hdr_basename == "zdnn.h") hdr_in_zdnn_h=1 else hdr_in_zdnn_h=0 dbg(debug_line, "Next lines come from: "hdr_basename" (hdr_in_zdnn_h="hdr_in_zdnn_h"; "$3")") next } fi == fi_hdr && NF > 0 { dbg(debug_line, "hdr(hdr_in_zdnn_h="hdr_in_zdnn_h"): "$0) if (hdr_in_zdnn_h != 0) { # unless hdr_line is empty, otherwise concat the next line with a space in between # so case like this will work: # # void # bar(char c); if (hdr_line != "") { hdr_line=hdr_line " " $0 } else { hdr_line=hdr_line $0 } if (index(hdr_line, ";") != 0) { dbg(debug_line, "zdnn.h: "hdr_line) # E.g. for structs, we need to ensure that we have the whole # declaration. Compare the number of '{' and '}'. # Note: structs use ";" for each member! hdr_nr_brace_begin = sub(/{/, "{", hdr_line) hdr_nr_brace_end = sub(/}/, "}", hdr_line) dbg(2, "hdr_nr_brace_begin="hdr_nr_brace_begin"; hdr_nr_brace_end="hdr_nr_brace_end) if (hdr_nr_brace_begin != hdr_nr_brace_end) next hdr_process_line(hdr_line) hdr_line="" } } } ################################################################################ # Processing <ZDNN_MAP>: variable-, function-prefix=map ################################################################################ function map_version_node_reset() { map_curr_version_node="" map_curr_version_node_scope="" map_curr_version_node_global_symbols=-1 } fi == fi_map && ( NF == 0 || /^#/ ) { dbg(debug_line, "map-empty-or-comment: "$0) if ($1 == "#" && $2 == "Task:") { map_tasks[map_tasks_cnt]=FNR": "$0 map_tasks_cnt++ } # Skip comments or empty lines next } fi == fi_map && /^ZDNN_.*{$/ { dbg(debug_line, "map-version-node-begin: "$0) # Matching lines: # ZDNN_1.0 { map_version_node_reset() map_curr_version_node=$1 next } fi == fi_map && map_curr_version_node != "" && $1 ~ /.*:$/ { dbg(debug_line, "map-version-node-scope: "$0) # Matching lines: # global: # local: *; map_curr_version_node_scope=$1 if ($1 == "global:") { if (map_curr_version_node_global_symbols != -1) fail("Found duplicate 'global:' scope in version-node "map_curr_version_node) else map_curr_version_node_global_symbols=0 } else if ($1 == "local:") { if ($2 != "*;") fail("As we list all global-scoped symbols in "map_file", only 'local: *;' is allowed!") } else { fail("Found invalid map-version-node-scope: "$1) map_version_node_reset() } next } fi == fi_map && map_curr_version_node != "" && /^};$/ { dbg(debug_line, "map-version-node-end: "$0) # Matching lines: # }; if (map_curr_version_node_global_symbols <= 0) fail("No global-scoped symbols found in version-node "map_curr_version_node" (Either remove the empty version-node or add a global-scoped symbol)") map_version_node_reset() next } fi == fi_map && map_curr_version_node != "" && map_curr_version_node_scope == "global:" { dbg(debug_line, "map-global-symbol: "$0) # Matching lines: # zdnn_init; map_name=$1 if (sub(/;$/, "", map_name) == 0) { fail("Failed to remove ';' at end of map-global-symbol: "map_name) } else { map_key=map_name"@"map_curr_version_node if (map_key in map_syms) { fail("Found a duplicate symbol "map_name" in version node "map_curr_version_node" in "map_file) } else { dbg(1, "Add to map_syms: "map_key) map_curr_version_node_global_symbols++ # 0 / 1: if found as symbol (@@ZDNN or @ZDNN) in .dynsym map_syms[map_key]=0 } } next } fi == fi_map { dbg(debug_line, "map-unhandled: "$0) fail("Found map-unhandled line (Perhaps a local-scope symbol?): "$0) } ################################################################################ # Processing <ZDNN_DYNSYMS>: variable-, function-prefix=dyn ################################################################################ fi == fi_dyn && NF >= 8 { # Process lines like: # Num: Value Size Type Bind Vis Ndx Name # 26: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND zdnn_get_status_str # 54: 00000000000083b0 56 FUNC GLOBAL DEFAULT 12 zdnn_sub@@ZDNN_1.0 # Note: Skip lines where Ndx is "Ndx" or e.g. "UND" or "ABS" dbg(debug_line, "dyn: "$0) dyn_name=$8 # e.g. zdnn_sub@@ZDNN_1.0 if ($7 == "UND") { if (dyn_name ~ /^zdnn/) fail("Found undefined symbol in "dyn_file": "dyn_name ". Better provide an implementation for this symbol in libzdnn.so?") else dbg(1, "Skipping UND symbol: "dyn_name) next } else if ($5 == "GLOBAL" && $7 ~ /[0-9]+/) { # 'zdnn_sub@@ZDNN_1.0' => 'zdnn_sub' and return > 0 if "@" was found dyn_sym=dyn_name if (sub("@.*", "", dyn_sym) == 0) { fail("Found unversioned symbol in "dyn_file": "dyn_name) } else { dyn_ver=substr(dyn_name, length(dyn_sym) + 1) if (substr(dyn_ver, 1, 2) == "@@") { if (dyn_sym in hdr_syms) { dbg(1, "Found default symbol "dyn_name" in "dyn_file", which is included in "hdr_file) hdr_syms[dyn_sym]=1 } else { fail("Default symbol "dyn_name" from "dyn_file" was not found in "hdr_file". All exported default symbols should belong to the zdnn.h header file!") } dyn_ver=substr(dyn_ver, 3) } else { dyn_ver=substr(dyn_ver, 2) } dyn_key=dyn_sym"@"dyn_ver if (dyn_key in map_syms) { dbg(1, "Found symbol "dyn_name" in "dyn_file" in version-node "dyn_ver" in "map_file) map_syms[dyn_key]=1 } else { fail("Symbol "dyn_name" from "dyn_file" was not found in "map_file". Please list the symbol in the corresponding version-node "dyn_ver) } } } } ################################################################################ # Perform checks at the end ################################################################################ END { curr_file="END" fi++ FNR=0 dbg(0, "Processing END of sym_checker.awk") if (fi != 4) fail("Please pass all files as seen in Usage of this awk file.") FNR++ dbg(1, "Symbols found in "hdr_file" (val=1 if found as default symbol (@@ZDNN) in .dynsym):") for (key in hdr_syms) { val=hdr_syms[key] dbg(1, "hdr_syms: key="key"; val="val) if (val == 0) { fail("For symbol "key" from "hdr_file", there is no default symbol in "dyn_file". A program/library can't link against this symbol! For new symbols, you have to add it to a new version-node in "map_file) } } FNR++ dbg(1, "Symbols found in "map_file" (val=1 if found as symbol (@@ZDNN or @ZDNN) in .dynsym):") for (key in map_syms) { val=map_syms[key] dbg(1, "map_syms: key="key"; val="val) if (val == 0) { fail("For symbol "key" from "map_file", there is no symbol in "dyn_file". Please provide an [old] implementation for this symbol!") } } FNR++ if (fails > 0) { print "" print "Please also have a look at the tasks described in "map_file":" for (i = 0; i < map_tasks_cnt; i++) print map_tasks[i] print "" dbg(0, "END of sym_checker.awk: "fails" ERRORs") exit 1 } else { dbg(0, "END of sym_checker.awk: SUCCESS") } } �������������������������������zDNN-1.0.1/zdnn/t-gccexpo���������������������������������������������������������������������������0000664�0000000�0000000�00000002326�14364043643�0015121�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Generate a variant of the shared library which exports all the symbols. # With the GNU toolchain on Linux this is achieved by using a version # script which marks all the symbols as global. We generate the # script from the actual version script (zdnn.map). zdnn_exportall.map: zdnn.map awk 'BEGIN { first=1; } /^ZDNN_*/ { print $0; if (first == 1) { print " global: *;"; first=0; } print "};" }' \ zdnn.map > zdnn_exportall.map $(SODIR)/$(LIBNAME_PRIVATE).so: $(INIT_OBJFILE) $(OBJFILES) $(H_FILES) zdnn_exportall.map $(LD) $(LDFLAGS_SHARED_EXPORTALL) -o $(SODIR)/$(LIBNAME_PRIVATE).so $(INIT_OBJFILE) $(OBJFILES) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/t-libsoname�������������������������������������������������������������������������0000664�0000000�0000000�00000002274�14364043643�0015444�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # The libsoname mechanism allows library versions providing different # API levels to co-exist in the system. # This is only supported on Linux right now. $(SODIR)/$(LIBSONAME): $(SODIR)/$(LIBNAME).so ln -f -s $(LIBNAME).so $@ $(SODIR)/$(LIBSONAME_PRIVATE): $(SODIR)/$(LIBNAME_PRIVATE).so ln -f -s $(LIBNAME_PRIVATE).so $@ .PHONY: libsoname libsoname: $(SODIR)/$(LIBSONAME) $(SODIR)/$(LIBSONAME_PRIVATE) .PHONY: install_libsoname install_libsoname: install_shared mv $(DESTDIR)$(libdir)/$(LIBNAME).so $(DESTDIR)$(libdir)/$(LIBSONAME) ln -f -s $(LIBSONAME) $(DESTDIR)$(libdir)/$(LIBNAME).so ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/t-listings��������������������������������������������������������������������������0000664�0000000�0000000�00000002271�14364043643�0015324�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Generate z/OS style assembler listings for each file compiled LISTINGS := $(patsubst %.o,%.lst,$(OBJFILES)) INIT_LISTING := $(patsubst %.o,%.lst,$(INIT_OBJFILE)) $(INIT_LISTING): $(INIT_SRCFILE) $(CC) $(CFLAGS_INIT) $(CFLAGS_SHARED) $(CFLAGS_ASM) -c $< -o /dev/null > $(OBJDIR)/$(LIBNAME).$(*F).lst $(OBJDIR)/%.lst: %.c $(CC) $(CFLAGS) $(CFLAGS_SHARED) $(CFLAGS_ASM) -c $< -o /dev/null > $(OBJDIR)/$(LIBNAME).$(*F).lst $(OBJDIR)/%.lst: %.cpp $(CXX) $(CXXFLAGS) $(CFLAGS_SHARED) $(CXXFLAGS_ASM) -c $< -o /dev/null > $(OBJDIR)/$(LIBNAME).$(*F).lst .PHONY: listings listings: $(LISTINGS) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/t-static����������������������������������������������������������������������������0000664�0000000�0000000�00000002572�14364043643�0014763�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Build a static version of the library. # Another variant of all the object files is getting built. For this # variant CFLAGS_SHARED and CXXFLAGS_SHARED will not be used to build # a statically linked library. OBJFILES_NONSHARED := $(patsubst %.o,%.nonshared.o,$(OBJFILES)) INIT_OBJFILE_NONSHARED := $(patsubst %.o,%.nonshared.o,$(INIT_OBJFILE)) $(INIT_OBJFILE_NONSHARED): $(INIT_SRCFILE) $(CC) $(CFLAGS_INIT) -c $< -o $@ $(OBJDIR)/%.nonshared.o: %.c $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/%.nonshared.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ $(SODIR)/$(LIBNAME).a: $(INIT_OBJFILE_NONSHARED) $(OBJFILES_NONSHARED) $(AR) $(ARFLAGS) $(SODIR)/$(LIBNAME).a $^ .PHONY: install_static install_static: install_shared $(INSTALL_DATA) -t $(DESTDIR)$(libdir) $(SODIR)/$(LIBNAME).a ��������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/t-symcheck��������������������������������������������������������������������������0000664�0000000�0000000�00000002324�14364043643�0015275�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Make sure that all symbols in zdnn.h are exported by the library # This compares the symboles exported in the header file with the # symbols actually visible in the resulting library. Although this # check depends on the way symbols are exported on Linux it is still # useful on z/OS to get notified when things are getting out of sync # between Linux and z/OS. zdnn.i: zdnn.h $(CC) $(CPP_SYMCHECK_FLAGS) $< symcheck: $(SODIR)/$(LIBNAME).so zdnn.i ifneq ($(READELF),) $(READELF) -W --dyn-syms $(SODIR)/$(LIBNAME).so > zdnn.dynsyms awk -f sym_checker.awk zdnn.i zdnn.map zdnn.dynsyms >symcheck cat symcheck endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/t-xlcexpo���������������������������������������������������������������������������0000664�0000000�0000000�00000002643�14364043643�0015155�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SPDX-License-Identifier: Apache-2.0 # # Copyright IBM Corp. 2021 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Generate a variant of the shared library which exports all the symbols. # With XLC this means building every file with a different # compile-time option. OBJFILES_EXPORTALL := $(patsubst %.o,%.expo.o,$(INIT_OBJFILE) $(OBJFILES)) EXPORTALL_FLAG := -Wc,EXPORTALL $(SODIR)/$(LIBNAME_PRIVATE).so: $(OBJFILES_EXPORTALL) $(H_FILES) $(LD) $(LDFLAGS_SHARED) -o $(SODIR)/$(LIBNAME_PRIVATE).so $(OBJFILES_EXPORTALL) mv $(LIBNAME_PRIVATE).x $(SODIR)/. $(OBJDIR)/%.expo.o: %.c $(CC) $(CFLAGS) $(CFLAGS_SHARED) $(EXPORTALL_FLAG) -c $< -o $@ $(OBJDIR)/%.expo.o: %.cpp $(CXX) $(CXXFLAGS) $(CFLAGS_SHARED) $(EXPORTALL_FLAG) -c $< -o $@ ${SODIR}/${LIBNAME}.x: $(SODIR)/$(LIBNAME).so # xlc generates the .x file while linking .so file, but outputs it to # current directory instead of SODIR. mv ${LIBNAME}.x ${SODIR}/${LIBNAME}.x ���������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/tensor_desc.c�����������������������������������������������������������������������0000664�0000000�0000000�00000046704�14364043643�0015771�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <stdarg.h> #include <string.h> #ifdef __MVS__ #pragma export(zdnn_init_pre_transformed_desc) #pragma export(zdnn_generate_transformed_desc) #pragma export(zdnn_generate_transformed_desc_concatenated) #endif /// Verify if the input zdnn_tensor_desc contains valid pre-transformed type and /// layout. dim variables are NOT checked. /// /// \param[in] input Pointer to the zdnn_tensor_desc being checked /// /// \return ZDNN_INVALID_LAYOUT /// ZDNN_INVALID_TYPE /// ZDNN_OK /// zdnn_status verify_pre_transformed_descriptor(const zdnn_tensor_desc *pre_tfrmd_desc) { // is the layout valid as pre-transformed? switch (pre_tfrmd_desc->layout) { case ZDNN_1D: case ZDNN_2D: case ZDNN_2DS: case ZDNN_3D: case ZDNN_3DS: case ZDNN_4D: case ZDNN_4DS: case ZDNN_NHWC: case ZDNN_NCHW: case ZDNN_HWCK: // all of these are good cases break; default: return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Invalid layout: %d (%s)", pre_tfrmd_desc->layout, get_data_layout_str(pre_tfrmd_desc->layout)); } // is data type valid as pre-transformed? switch (pre_tfrmd_desc->type) { case BFLOAT: case FP16: case FP32: // all of these are good cases break; default: return ZDNN_STATUS(ZDNN_INVALID_TYPE, "Invalid type: %d (%s)", pre_tfrmd_desc->type, get_data_type_str(pre_tfrmd_desc->type)); } return ZDNN_STATUS_OK; } /// Verify if the input zdnn_tensor_desc contains valid transformed information /// /// \param[in] input Pointer to the zdnn_tensor_desc being checked /// /// \return ZDNN_INVALID_FORMAT /// ZDNN_INVALID_LAYOUT /// ZDNN_INVALID_TYPE /// zdnn_status verify_transformed_descriptor(const zdnn_tensor_desc *tfrmd_desc) { // First, format must be valid (defined in the enum) // Then if format doesn't agree with layout, we declare format is correct and // layout is wrong (in reality, either can be wrong, but we have to pick one) switch (tfrmd_desc->format) { case ZDNN_FORMAT_4DFEATURE: switch (tfrmd_desc->layout) { case ZDNN_NHWC: case ZDNN_FICO: case ZDNN_ZRH: case ZDNN_BIDIR_FICO: case ZDNN_BIDIR_ZRH: break; default: return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Format is %s but layout is %s", get_data_format_str(tfrmd_desc->format), get_data_layout_str(tfrmd_desc->layout)); } break; case ZDNN_FORMAT_4DKERNEL: if (tfrmd_desc->layout != ZDNN_HWCK) { return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Format is %s but layout is %s", get_data_format_str(tfrmd_desc->format), get_data_layout_str(tfrmd_desc->layout)); } break; default: // unrecognized return ZDNN_STATUS(ZDNN_INVALID_FORMAT, "Invalid format: %d (%s)", tfrmd_desc->format, get_data_format_str(tfrmd_desc->format)); } // for right now only ZDNN_DLFLOAT16 is valid if (tfrmd_desc->type != ZDNN_DLFLOAT16) { return ZDNN_STATUS(ZDNN_INVALID_TYPE, "Invalid type: %d (%s)", tfrmd_desc->type, get_data_type_str(tfrmd_desc->type)); } const uint32_t *dims_ptr = &(tfrmd_desc->dim4); // is the dimension above the limit or zero? // transformed layout uses all dim* entries, so we'll check them all for (int i = 0; i < ZDNN_MAX_DIMS; i++) { LOG_DEBUG("dim%d: %d", ZDNN_MAX_DIMS - i, dims_ptr[i]); if (!dims_ptr[i] || dims_ptr[i] > zdnn_get_nnpa_max_dim_idx_size()) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "Invalid shape: %d (reason: exceeds %d or is 0)", dims_ptr[i], zdnn_get_nnpa_max_dim_idx_size()); } } // is stick area size above the limit? if (zdnn_getsize_ztensor(tfrmd_desc) > zdnn_get_nnpa_max_tensor_size()) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "Invalid shape (reasons: tensor size: %" PRIu64 ", maximum: %" PRIu64 " bytes", zdnn_getsize_ztensor(tfrmd_desc), zdnn_get_nnpa_max_tensor_size()); } return ZDNN_STATUS_OK; } /// Convenience function for populating zdnn_tensor_desc with pre-transformed /// shape information /// /// \param[in] layout data layout /// \param[in] type data type /// \param[out] pre_tfrmd_desc Pointer to zdnn_tensor_desc struct /// \param[in] ... Number of elements in each dimension, in outermost to /// innermost order /// /// \return None /// void zdnn_init_pre_transformed_desc(zdnn_data_layouts layout, zdnn_data_types type, zdnn_tensor_desc *pre_tfrmd_desc, ...) { // point to dim4/3/etc via pointer. they're guaranteed to be in the correct // order as written and contiguous and correctly aligned uint32_t *dims_ptr = &(pre_tfrmd_desc->dim4); va_list v_list; va_start(v_list, pre_tfrmd_desc); if (pre_tfrmd_desc) { // unused dim* vars in pre-transformed descriptor are left alone for (int i = ZDNN_MAX_DIMS - get_data_layout_dims(layout); i < ZDNN_MAX_DIMS; i++) { dims_ptr[i] = va_arg(v_list, uint32_t); } pre_tfrmd_desc->layout = layout; pre_tfrmd_desc->type = type; } va_end(v_list); } /// Convenience function for populating zdnn_tensor_desc with transformed /// information, for INTERNAL USE only. .format is NOT set in this routine. /// /// \param[in] layout data layout /// \param[in] type data type /// \param[in] format NNPA data format /// \param[out] pre_tfrmd_desc Pointer to zdnn_tensor_desc struct /// \param[in] dim4 number of elements in outermost /// \param[in] dim3 number of elements /// \param[in] dim2 number of elements /// \param[in] dim1 number of elements in innermost /// /// \return None /// void init_transformed_desc(zdnn_data_layouts layout, zdnn_data_types type, zdnn_data_formats format, zdnn_tensor_desc *tfrmd_desc, uint32_t dim4, uint32_t dim3, uint32_t dim2, uint32_t dim1) { // piggyback on zdnn_init_pre_transformed_desc() for now zdnn_init_pre_transformed_desc(layout, type, tfrmd_desc, dim4, dim3, dim2, dim1); tfrmd_desc->format = format; } /// Convenience function for slicing a ztensor along dim4. The contents of the /// input ztensor and its descriptors are copied into the output pointers. Then /// the output's structs are updated to reflect values for a single slice. The /// input buffer values are not copied. Instead the output's buffer pointer is /// adjusted so it points the the correct address of the existing data. /// /// \param[in] input_ztensor pointer to original unsliced ztensor /// \param[in] slice_idx dim4 index to use as output slice /// \param[in] slice_buffer_size size of a sliced buffer. If 0, method will /// calculate based on number of elements and data type /// \param[out] output_pre_tfrmd_desc pointer to pre_tfrmd_desc to edit for /// output (skipped if NULL) /// \param[out] output_tfrmd_desc pointer to tfrmd_desc to edit for output. /// \param[out] output_ztensor pointer ztensor to edit for output slice. /// /// \return ZDNN_INVALID_LAYOUT (where applicable when output_pre_tfrmd_desc is /// not NULL) /// ZDNN_STATUS_OK /// zdnn_status ztensor_slice_dim4(const zdnn_ztensor *input_ztensor, uint32_t slice_idx, size_t slice_buffer_size, zdnn_tensor_desc *output_pre_tfrmd_desc, zdnn_tensor_desc *output_tfrmd_desc, zdnn_ztensor *output_ztensor) { // Copy the input ztensor info into output and set output descriptor pointers memcpy(output_ztensor, input_ztensor, sizeof(zdnn_ztensor)); output_ztensor->pre_transformed_desc = output_pre_tfrmd_desc; output_ztensor->transformed_desc = output_tfrmd_desc; // Copy the input ztensor descriptors into output descriptors memcpy(output_tfrmd_desc, input_ztensor->transformed_desc, sizeof(zdnn_tensor_desc)); // set up pre-transformed desctprors for the sliced output only if caller // cares about it and gave us a space for it if (output_pre_tfrmd_desc) { memcpy(output_pre_tfrmd_desc, input_ztensor->pre_transformed_desc, sizeof(zdnn_tensor_desc)); // Set the output ztensor dim values to reflect the slicing switch (input_ztensor->pre_transformed_desc->layout) { case ZDNN_2DS: output_ztensor->pre_transformed_desc->dim2 = 1; break; case ZDNN_3DS: output_ztensor->pre_transformed_desc->dim3 = 1; break; case ZDNN_4D: case ZDNN_NHWC: case ZDNN_NCHW: output_ztensor->pre_transformed_desc->dim4 = 1; break; default: return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Invalid layout for slicing: %d", input_ztensor->transformed_desc->layout); break; } } output_ztensor->transformed_desc->dim4 = 1; // Check these after we check the layout so we issue better error messages. // Otherwise 1D, 2D, 3D, etc would emit ZDNN_INVALID_SHAPE for dim4 == 1 if (input_ztensor->transformed_desc->dim4 < 2) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "Invalid shape for slicing: transformed_desc->dim4 must " "be greater than one", NO_ARG); } else if (slice_idx + 1 > input_ztensor->transformed_desc->dim4) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "Invalid shape for slicing: transformed_desc->dim4 (%d) " "does not support a slice index of %d", input_ztensor->transformed_desc->dim4, slice_idx); } // We need the exact buffer_size so we slice the buffer correctly. If given, // use the specified size, otherwise calculate it now. if (slice_buffer_size) { output_ztensor->buffer_size = slice_buffer_size; LOG_DEBUG("slice buffer_size set to %" PRIu64 " by specified slice_buffer_size", output_ztensor->buffer_size); } else { output_ztensor->buffer_size = zdnn_getsize_ztensor(output_ztensor->transformed_desc); LOG_DEBUG("slice buffer_size set to %" PRIu64 " by zdnn_getsize_ztensor()", output_ztensor->buffer_size); } // Set output ztensor buffer address to where the slice starts from input output_ztensor->buffer = (void *)((uintptr_t)input_ztensor->buffer + (slice_idx * output_ztensor->buffer_size)); return ZDNN_STATUS_OK; } /// Generate transformed tensor descriptor based on supplied pre-transformed /// tensor descriptor /// /// \param[in] pre_tfrmd_desc Pointer to zdnn_tensor_desc struct with /// pre-transformed information /// \param[out] tfrmd_desc /// Pointer to zdnn_tensor_desc struct where transformed /// information will be stored /// /// \return ZDNN_OK /// ZDNN_INVALID_LAYOUT /// /// zdnn_status zdnn_generate_transformed_desc(const zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc) { zdnn_status status; // modify tfrmd_desc only if layout is supported, else leave it untouched switch (pre_tfrmd_desc->layout) { case (ZDNN_1D): // shape (a) -> dims4-1 (1, 1, 1, a) tfrmd_desc->dim4 = 1; tfrmd_desc->dim3 = 1; tfrmd_desc->dim2 = 1; tfrmd_desc->dim1 = pre_tfrmd_desc->dim1; tfrmd_desc->layout = ZDNN_NHWC; tfrmd_desc->format = ZDNN_FORMAT_4DFEATURE; status = ZDNN_OK; break; case (ZDNN_2D): // shape (a, b) -> dims4-1 (1, 1, a, b) tfrmd_desc->dim4 = 1; tfrmd_desc->dim3 = 1; tfrmd_desc->dim2 = pre_tfrmd_desc->dim2; tfrmd_desc->dim1 = pre_tfrmd_desc->dim1; tfrmd_desc->layout = ZDNN_NHWC; tfrmd_desc->format = ZDNN_FORMAT_4DFEATURE; status = ZDNN_OK; break; case (ZDNN_2DS): // shape (a, b) -> dims4-1 (a, 1, 1, b) tfrmd_desc->dim4 = pre_tfrmd_desc->dim2; tfrmd_desc->dim3 = 1; tfrmd_desc->dim2 = 1; tfrmd_desc->dim1 = pre_tfrmd_desc->dim1; tfrmd_desc->layout = ZDNN_NHWC; tfrmd_desc->format = ZDNN_FORMAT_4DFEATURE; status = ZDNN_OK; break; case (ZDNN_3D): // shape (a, b, c) -> dims4-1 (1, a, b, c) tfrmd_desc->dim4 = 1; tfrmd_desc->dim3 = pre_tfrmd_desc->dim3; tfrmd_desc->dim2 = pre_tfrmd_desc->dim2; tfrmd_desc->dim1 = pre_tfrmd_desc->dim1; tfrmd_desc->layout = ZDNN_NHWC; tfrmd_desc->format = ZDNN_FORMAT_4DFEATURE; status = ZDNN_OK; break; case (ZDNN_3DS): // shape (a, b, c) -> dims4-1 (a, 1, b, c) tfrmd_desc->dim4 = pre_tfrmd_desc->dim3; tfrmd_desc->dim3 = 1; tfrmd_desc->dim2 = pre_tfrmd_desc->dim2; tfrmd_desc->dim1 = pre_tfrmd_desc->dim1; tfrmd_desc->layout = ZDNN_NHWC; tfrmd_desc->format = ZDNN_FORMAT_4DFEATURE; status = ZDNN_OK; break; case (ZDNN_4D): case (ZDNN_NHWC): // shape (a, b, c, d) -> dims4-1 (a, b, c, d) // shape (n, h, w, c) -> dims4-1 (n, h, w, c) tfrmd_desc->dim4 = pre_tfrmd_desc->dim4; tfrmd_desc->dim3 = pre_tfrmd_desc->dim3; tfrmd_desc->dim2 = pre_tfrmd_desc->dim2; tfrmd_desc->dim1 = pre_tfrmd_desc->dim1; tfrmd_desc->layout = ZDNN_NHWC; tfrmd_desc->format = ZDNN_FORMAT_4DFEATURE; status = ZDNN_OK; break; case (ZDNN_4DS): // ZDNN_4DS is used exclusively as RNN output // shape (a, b, c, d) -> ZDNN_NHWC // when b = 1 (uni-dir) -> dims4-1 (a, 1, c, d) // otherwise (bi-dir, etc.) -> dims4-1 (a, 1, c, b * PADDED(d)) tfrmd_desc->dim4 = pre_tfrmd_desc->dim4; tfrmd_desc->dim3 = 1; tfrmd_desc->dim2 = pre_tfrmd_desc->dim2; if (pre_tfrmd_desc->dim3 == 1) { tfrmd_desc->dim1 = pre_tfrmd_desc->dim1; } else { // so when dim3 is 0 for whatever reason, tfrmd_desc->dim1 will become 0 // and will fail transform-desc check later tfrmd_desc->dim1 = pre_tfrmd_desc->dim3 * PADDED(pre_tfrmd_desc->dim1); } tfrmd_desc->layout = ZDNN_NHWC; tfrmd_desc->format = ZDNN_FORMAT_4DFEATURE; status = ZDNN_OK; break; case (ZDNN_NCHW): // shape (n, c, h, w) -> dims4-1 (n, h, w, c) tfrmd_desc->dim4 = pre_tfrmd_desc->dim4; tfrmd_desc->dim3 = pre_tfrmd_desc->dim2; tfrmd_desc->dim2 = pre_tfrmd_desc->dim1; tfrmd_desc->dim1 = pre_tfrmd_desc->dim3; tfrmd_desc->layout = ZDNN_NHWC; tfrmd_desc->format = ZDNN_FORMAT_4DFEATURE; status = ZDNN_OK; break; case ZDNN_HWCK: tfrmd_desc->dim4 = pre_tfrmd_desc->dim4; tfrmd_desc->dim3 = pre_tfrmd_desc->dim3; tfrmd_desc->dim2 = pre_tfrmd_desc->dim2; tfrmd_desc->dim1 = pre_tfrmd_desc->dim1; tfrmd_desc->layout = ZDNN_HWCK; tfrmd_desc->format = ZDNN_FORMAT_4DKERNEL; status = ZDNN_OK; break; default: return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Invalid layout: %d (%s)", pre_tfrmd_desc->layout, get_data_layout_str(pre_tfrmd_desc->layout)); break; } if (status == ZDNN_OK) { tfrmd_desc->type = ZDNN_DLFLOAT16; } return status; } /// Generate concatenated transformed tensor descriptor based on supplied /// pre-transformed tensor descriptor /// /// \param[in] pre_tfrmd_desc /// Pointer to zdnn_tensor_desc struct with pre-transformed /// information /// \param[in] info /// Concatenation information /// \param[out] tfrmd_desc /// Pointer to zdnn_tensor_desc struct where transformed /// information will be stored /// /// \return ZDNN_OK /// ZDNN_INVALID_LAYOUT /// ZDNN_INVALID_CONCAT_INFO /// ZDNN_INVALID_SHAPE /// zdnn_status zdnn_generate_transformed_desc_concatenated( const zdnn_tensor_desc *pre_tfrmd_desc, zdnn_concat_info info, zdnn_tensor_desc *tfrmd_desc) { if ((CONCAT_USAGE(info) == USAGE_WEIGHTS) && (CONCAT_PREV_LAYER(info) == PREV_LAYER_BIDIR)) { // dim2 can't be odd number if (pre_tfrmd_desc->dim2 & 1) { return ZDNN_STATUS( ZDNN_INVALID_SHAPE, "when PREV_LAYER_BIDIR and USAGE_WEIGHTS, pre-transformed " "dim2 must be multiples of 2 (found: %d)", pre_tfrmd_desc->dim2); } } // Two kinds of concatenations we need to deal with: // // - (Hidden-)Weights, (hidden)-biases need to be concatenated horizontally, // new dim1 is calculated via get_rnn_concatenated_dim1() // // - Weights may need to be concatenated vertically also (when output // from the previous bidir layer is the input), new dim2 is calculated via // get_rnn_concatenated_dim2() if ((CONCAT_USAGE(info) == USAGE_BIASES) || (CONCAT_USAGE(info) == USAGE_HIDDEN_BIASES)) { if (pre_tfrmd_desc->layout == ZDNN_2DS) { tfrmd_desc->dim4 = pre_tfrmd_desc->dim2; tfrmd_desc->dim3 = 1; tfrmd_desc->dim2 = 1; tfrmd_desc->dim1 = get_rnn_concatenated_dim1(pre_tfrmd_desc->dim1, info); } else { return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Pre-transformed layout not ZDNN_2DS (found: %s)", get_data_layout_str(pre_tfrmd_desc->layout)); } } else if ((CONCAT_USAGE(info) == USAGE_WEIGHTS) || (CONCAT_USAGE(info) == USAGE_HIDDEN_WEIGHTS)) { if (pre_tfrmd_desc->layout == ZDNN_3DS) { tfrmd_desc->dim4 = pre_tfrmd_desc->dim3; tfrmd_desc->dim3 = 1; tfrmd_desc->dim2 = get_rnn_concatenated_dim2(pre_tfrmd_desc->dim2, info); tfrmd_desc->dim1 = get_rnn_concatenated_dim1(pre_tfrmd_desc->dim1, info); } else { return ZDNN_STATUS(ZDNN_INVALID_LAYOUT, "Pre-transformed layout not ZDNN_3DS (found: %s)", get_data_layout_str(pre_tfrmd_desc->layout)); } } else { return ZDNN_STATUS(ZDNN_INVALID_CONCAT_INFO, "Invalid usage in concatenation info: %08x", info); } // if USAGE is WEIGHTS and PREV_LAYER is BIDIR then // ZDNN_BIDIR_FICO/ZDNN_BIDIR_ZRH // // everything else ZDNN_FICO/ZDNN_ZRH if ((CONCAT_USAGE(info) == USAGE_WEIGHTS) && (CONCAT_PREV_LAYER(info) == PREV_LAYER_BIDIR)) { if (CONCAT_RNN_TYPE(info) == RNN_TYPE_LSTM) { tfrmd_desc->layout = ZDNN_BIDIR_FICO; } else if (CONCAT_RNN_TYPE(info) == RNN_TYPE_GRU) { tfrmd_desc->layout = ZDNN_BIDIR_ZRH; } else { return ZDNN_STATUS(ZDNN_INVALID_CONCAT_INFO, "Invalid RNN type in concatenation info: %08x", info); } } else { if (CONCAT_RNN_TYPE(info) == RNN_TYPE_LSTM) { tfrmd_desc->layout = ZDNN_FICO; } else if (CONCAT_RNN_TYPE(info) == RNN_TYPE_GRU) { tfrmd_desc->layout = ZDNN_ZRH; } else { return ZDNN_STATUS(ZDNN_INVALID_CONCAT_INFO, "Invalid RNN type in concatenation info: %08x", info); } } tfrmd_desc->type = ZDNN_DLFLOAT16; tfrmd_desc->format = ZDNN_FORMAT_4DFEATURE; return ZDNN_STATUS_OK; } ������������������������������������������������������������zDNN-1.0.1/zdnn/tensor_dump.c�����������������������������������������������������������������������0000664�0000000�0000000�00000032540�14364043643�0016011�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <inttypes.h> #include <stddef.h> #include <stdio.h> #include "convert.h" #include "zdnn.h" #include "zdnn_private.h" #define FLOAT_DECIMAL_PLACES "3" /// Dump raw tensor data with N/H/W/C or H/W/C/K seperation /// /// \param[in] desc Pointer to pre-transformed descriptor /// \param[in] data Pointer to raw tensor data /// \param[in] mode AS_HEX or AS_FLOAT /// /// \return None /// void dumpdata_origtensor(const zdnn_tensor_desc *pre_tfrmd_desc, void *tensor_data, dump_mode mode) { uint32_t dim4 = (get_data_layout_dims(pre_tfrmd_desc->layout) >= 4) ? pre_tfrmd_desc->dim4 : 1; uint32_t dim3 = (get_data_layout_dims(pre_tfrmd_desc->layout) >= 3) ? pre_tfrmd_desc->dim3 : 1; uint32_t dim2 = (get_data_layout_dims(pre_tfrmd_desc->layout) >= 2) ? pre_tfrmd_desc->dim2 : 1; uint32_t dim1 = pre_tfrmd_desc->dim1; // ZDNN_*DS layouts promote one dim to dim4. This sets the dump's dim* // variables match so the dump's NHWC labels line up with the layout. switch (pre_tfrmd_desc->layout) { case ZDNN_2DS: dim4 = pre_tfrmd_desc->dim2; dim2 = 1; break; case ZDNN_3DS: dim4 = pre_tfrmd_desc->dim3; dim3 = 1; break; default: // Nothing to do here. This is just to avoid compiler warnings break; } int cell_size; if (mode == AS_HEX) { cell_size = MAX(get_data_type_size(pre_tfrmd_desc->type) * 2, 5) + 2; } else { cell_size = 10; // xxxxx.yy + 2 spaces } uint64_t element_idx = 0; char dim3_char, dim2_char, dim1_char, dim0_char; switch (pre_tfrmd_desc->layout) { case ZDNN_NCHW: dim3_char = 'N'; dim2_char = 'C'; dim1_char = 'H'; dim0_char = 'W'; break; case ZDNN_HWCK: dim3_char = 'H'; dim2_char = 'W'; dim1_char = 'C'; dim0_char = 'K'; break; default: // everything else (1D/3D/etc etc treat as NHWC) dim3_char = 'N'; dim2_char = 'H'; dim1_char = 'W'; dim0_char = 'C'; } printf("raw tensor layout = %s -> %c%c%c%c %ux%ux%ux%u\n", get_data_layout_str(pre_tfrmd_desc->layout), dim3_char, dim2_char, dim1_char, dim0_char, dim4, dim3, dim2, dim1); printf("data type = %s\n", get_data_type_str(pre_tfrmd_desc->type)); for (uint32_t e4 = 0; e4 < dim4; e4++) { printf(" %c = %-*u\n", dim3_char, 5, e4); for (uint32_t e3 = 0; e3 < dim3; e3++) { printf(" | %c = %-*u\n", dim2_char, 5, e3); printf(" | | %c -> ", dim0_char); for (uint32_t i = 0; i < dim1; i++) { printf("%-*u", cell_size, i); } printf("\n"); printf(" | | %c +--", dim1_char); for (uint32_t i = 0; i < dim1; i++) { printf("%.*s", cell_size, "-----------------------"); } printf("\n"); for (uint32_t e2 = 0; e2 < dim2; e2++) { printf(" | | %*u | ", 5, e2); for (uint32_t e1 = 0; e1 < dim1; e1++) { if (mode == AS_HEX) { switch (pre_tfrmd_desc->type) { case BFLOAT: case FP16: printf("%04x%*s", ((uint16_t *)tensor_data)[element_idx], cell_size - 4, ""); break; case FP32: printf("%08x%*s", ((uint32_t *)tensor_data)[element_idx], cell_size - 8, ""); break; default: break; } } else { switch (pre_tfrmd_desc->type) { case BFLOAT: printf("%-*." FLOAT_DECIMAL_PLACES "f", cell_size, cnvt_1_bfloat_to_fp32( ((uint16_t *)tensor_data)[element_idx])); break; case FP16: printf( "%-*." FLOAT_DECIMAL_PLACES "f", cell_size, cnvt_1_fp16_to_fp32(((uint16_t *)tensor_data)[element_idx])); break; case FP32: printf("%-*." FLOAT_DECIMAL_PLACES "f", cell_size, ((float *)tensor_data)[element_idx]); break; default: break; } } element_idx++; } printf("\n"); } } } } /// Dump zTensor buffer data with N/H/W/C or H/W/C/K seperation /// /// \param[in] ztensor Pointer to zdnn_ztensor struct /// \param[in] mode AS_HEX or AS_FLOAT /// \param[in] print_all prints unused page-padding sticks if true /// /// \return None /// void dumpdata_ztensor(const zdnn_ztensor *ztensor, dump_mode mode, bool print_all) { int cell_size; if (mode == AS_HEX) { cell_size = 7; // XXXXX + 2 spaces } else { cell_size = 10; // xxxxx.yy + 2 spaces } zdnn_tensor_desc *pre_desc = ztensor->pre_transformed_desc; zdnn_tensor_desc *tfrmd_desc = ztensor->transformed_desc; // Print buffer info printf("ztensor->buffer = %" PRIXPTR ", ztensor->buffer_size = %" PRIu64 "\n", (uintptr_t)ztensor->buffer, ztensor->buffer_size); // Print pre_tfrmd_desc layout and shape printf("ztensor->pre_transformed_desc->layout = "); if (pre_desc) { printf("%s ", get_data_layout_str(pre_desc->layout)); if (get_data_layout_dims(pre_desc->layout) >= 4) { printf("%ux", pre_desc->dim4); } if (get_data_layout_dims(pre_desc->layout) >= 3) { printf("%ux", pre_desc->dim3); } if (get_data_layout_dims(pre_desc->layout) >= 2) { printf("%ux", pre_desc->dim2); } printf("%u\n", pre_desc->dim1); } else { printf("NULL\n"); } // Print tfrmd_desc layout and shape printf("ztensor->transformed_desc->layout = "); if (tfrmd_desc) { printf("%s %ux%ux%ux%u\n", get_data_layout_str(tfrmd_desc->layout), tfrmd_desc->dim4, tfrmd_desc->dim3, tfrmd_desc->dim2, tfrmd_desc->dim1); if (tfrmd_desc->layout != ZDNN_HWCK) { uint32_t current_n = 0, current_h = 0, current_w = 0, current_c = 0; // cumulative number of sticks processed, for printing overall offsets uint32_t accum_w = 0; // bump up h and etc when current_w reaches this value uint32_t stop_w = CEIL(tfrmd_desc->dim2, AIU_STICKS_PER_PAGE) * AIU_STICKS_PER_PAGE; // each element in the stick area is 2-bytes (assuming there's only // DLFLOAT16) for (uint64_t i = 0; i < ztensor->buffer_size / 2; i += AIU_2BYTE_CELLS_PER_STICK) { // print a "page break" at every AIU_PAGESIZE_IN_BYTES/2-th element if (i && !(i % (AIU_PAGESIZE_IN_BYTES / 2))) { printf(" +--"); for (uint32_t j = 0; j < AIU_2BYTE_CELLS_PER_STICK; j++) { printf("%.*s", cell_size, "-----------------------"); } printf("\n"); } // print the "N = " and "H = " banner when W = 0 and C = 0 or 64 or 128 // or etc if (current_w == 0 && !(current_c % AIU_2BYTE_CELLS_PER_STICK)) { printf(" N = %-*u\n", 5, current_n); printf(" | H = %-*u\n", 5, current_h); } if (current_w == 0) { // print the horizontal c indices. if c is not used then print a // blank instead. printf(" | | C -> "); for (uint32_t c_idx = current_c; c_idx < current_c + AIU_2BYTE_CELLS_PER_STICK; c_idx++) { if (c_idx < tfrmd_desc->dim1) { printf("%-*u", cell_size, c_idx); } else { printf("%-*s", cell_size, " "); } } printf("\n"); // print the "W = " banner printf("%016" PRIXPTR " | | W +--", (uintptr_t)ztensor->buffer + accum_w * AIU_2BYTE_CELLS_PER_STICK * AIU_2BYTE_CELL_SIZE); for (uint32_t j = 0; j < AIU_2BYTE_CELLS_PER_STICK; j++) { printf("%.*s", cell_size, "-----------------------"); } printf("\n"); } // print a whole stick if w is within valid range, otherwise print out // a bunch of blanks if (current_w < tfrmd_desc->dim2 || print_all) { printf(" (+%08x) | | %*u | ", accum_w * AIU_2BYTE_CELLS_PER_STICK * AIU_2BYTE_CELL_SIZE, 5, current_w); for (int j = 0; j < AIU_2BYTE_CELLS_PER_STICK; j++) { if (mode == AS_HEX) { printf("%04x%*s", ((uint16_t *)ztensor->buffer)[i + j], cell_size - 4, ""); } else { printf( "%-*." FLOAT_DECIMAL_PLACES "f", cell_size, cnvt_1_dlf16_to_fp32(((uint16_t *)ztensor->buffer)[i + j])); } } } else { printf(" (+%08x) | | | ", accum_w * AIU_2BYTE_CELLS_PER_STICK * AIU_2BYTE_CELL_SIZE); } printf("\n"); // manipulate the indices current_w++; accum_w++; if (current_w == stop_w) { current_w = 0; current_h++; if (current_h == tfrmd_desc->dim3) { current_h = 0; current_c += AIU_2BYTE_CELLS_PER_STICK; if (current_c >= tfrmd_desc->dim1) { current_c = 0; } } } if (!current_c && !current_w && !current_h) { current_n++; } } } else { uint32_t current_h = 0, current_w = 0, current_c = 0, current_k = 0; // cumulative number of sticks processed, for printing overall offsets uint32_t accum_c = 0; // bump up c and etc when current_c reaches this value uint32_t stop_c = CEIL(tfrmd_desc->dim2, AIU_STICKS_PER_PAGE) * AIU_STICKS_PER_PAGE; // each element in the stick area is 2-bytes (assuming there's only // DLFLOAT16) for (uint64_t i = 0; i < ztensor->buffer_size / 2; i += AIU_2BYTE_CELLS_PER_STICK) { // print a "page break" at every AIU_PAGESIZE_IN_BYTES/2-th element if (i && !(i % (AIU_PAGESIZE_IN_BYTES / 2))) { printf(" +--"); for (uint32_t j = 0; j < AIU_2BYTE_CELLS_PER_STICK; j++) { printf("%.*s", cell_size, "-----------------------"); } printf("\n"); } // print the "H = " and "W = " banner when C = 0 and K = 0 or 64 or 128 // or etc if (current_c == 0 && !(current_k % AIU_2BYTE_CELLS_PER_STICK)) { printf(" H = %-*u\n", 5, current_h); printf(" | W = %-*u\n", 5, current_w); } if (current_c == 0) { // print the horizontal k indices. if k is not used then print a // blank instead. printf(" | | K -> "); for (uint32_t k_idx = current_k; k_idx < current_k + AIU_2BYTE_CELLS_PER_STICK; k_idx++) { if (k_idx < tfrmd_desc->dim1) { printf("%-*u", cell_size, k_idx); } else { printf("%-*s", cell_size, " "); } } printf("\n"); // print the "C = " banner printf("%016" PRIXPTR " | | C +--", (uintptr_t)ztensor->buffer + accum_c * AIU_2BYTE_CELLS_PER_STICK * AIU_2BYTE_CELL_SIZE); for (uint32_t j = 0; j < AIU_2BYTE_CELLS_PER_STICK; j++) { printf("%.*s", cell_size, "-----------------------"); } printf("\n"); } // print a whole stick if k is within valid range, otherwise print out // a bunch of blanks if (current_c < tfrmd_desc->dim2 || print_all) { printf(" (+%08x) | | %*u | ", accum_c * AIU_2BYTE_CELLS_PER_STICK * AIU_2BYTE_CELL_SIZE, 5, current_c); for (int j = 0; j < AIU_2BYTE_CELLS_PER_STICK; j++) { if (mode == AS_HEX) { printf("%04x%*s", ((uint16_t *)ztensor->buffer)[i + j], cell_size - 4, ""); } else { printf( "%-*." FLOAT_DECIMAL_PLACES "f", cell_size, cnvt_1_dlf16_to_fp32(((uint16_t *)ztensor->buffer)[i + j])); } } } else { printf(" (+%08x) | | | ", accum_c * AIU_2BYTE_CELLS_PER_STICK * AIU_2BYTE_CELL_SIZE); } printf("\n"); // manipulate the indices current_c++; accum_c++; if (current_c == stop_c) { current_c = 0; current_w++; if (current_w == tfrmd_desc->dim3) { current_w = 0; current_h++; if (current_h == tfrmd_desc->dim4) { current_h = 0; current_k += AIU_2BYTE_CELLS_PER_STICK; } } } } } } else { printf("NULL\n"); } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/tensor_verify.c���������������������������������������������������������������������0000664�0000000�0000000�00000115756�14364043643�0016363�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <stdarg.h> #include <stdbool.h> #include <stddef.h> #include <stdio.h> /// Verify multiple zTensors against specific type/format values. /// Variadic parameter list MUST be NULL-TERMINATED. /// /// \param[in] type required data type /// \param[in] format required format /// \param[in] ... list of (zdnn_ztensor*, char* name) pairs, NULL-TERMINATED at /// the end /// /// \return ZDNN_OK /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_FORMAT /// static zdnn_status verify_fields(zdnn_data_types type, zdnn_data_formats format, ...) { zdnn_status status = ZDNN_OK; va_list v; va_start(v, format); zdnn_ztensor *tsr_ptr; uint8_t i = 0; while ((tsr_ptr = va_arg(v, zdnn_ztensor *)) != NULL) { char *tsr_name = va_arg(v, char *); if (tsr_ptr->transformed_desc->type != type) { status = ZDNN_STATUS( ZDNN_INVALID_TYPE, "%s tensor type is invalid (found %s (%d), expects %s (%d))", tsr_name, get_data_type_str(tsr_ptr->transformed_desc->type), tsr_ptr->transformed_desc->type, get_data_type_str(type), type); break; } if (tsr_ptr->transformed_desc->format != format) { status = ZDNN_STATUS( ZDNN_INVALID_FORMAT, "%s tensor format is invalid (found %s (%d), expects %s (%d))", tsr_name, get_data_format_str(tsr_ptr->transformed_desc->format), tsr_ptr->transformed_desc->format, get_data_format_str(format), format); break; } i++; } va_end(v); return status; } /// Verify multiple zTensors against specific shape value /// Variadic parameter list MUST be NULL-TERMINATED /// /// \param[in] dim_idx dimX index /// \param[in] val required value /// \param[in] ... list of (zdnn_ztensor*, char* name) pairs, NULL-TERMINATED at /// the end /// /// \return ZDNN_OK /// ZDNN_INVALID_SHAPE /// static zdnn_status verify_dim(uint8_t dim_idx, uint32_t val, ...) { zdnn_status status = ZDNN_OK; va_list v; va_start(v, val); zdnn_ztensor *tsr_ptr; uint8_t i = 0; while ((tsr_ptr = va_arg(v, zdnn_ztensor *)) != NULL) { char *tsr_name = va_arg(v, char *); uint32_t *dims_ptr = &(tsr_ptr->transformed_desc->dim4); if (dims_ptr[ZDNN_MAX_DIMS - dim_idx] != val) { status = ZDNN_STATUS( ZDNN_INVALID_SHAPE, "%s dim%d tensor shape is invalid (found %d, expects %d)", tsr_name, dim_idx, dims_ptr[ZDNN_MAX_DIMS - dim_idx], val); break; } i++; } va_end(v); return status; } #define CAT(x, y) x##y #define TENSOR_PARMS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) \ CAT(TENSOR_PARM_, N) #define TENSOR_PARMS(...) \ TENSOR_PARMS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) // stringify the tensors to x, "x" #define TENSOR_PARM_1(x) x, #x #define TENSOR_PARM_2(x, x2) x, #x, x2, #x2 #define TENSOR_PARM_3(x, x2, x3) x, #x, x2, #x2, x3, #x3 #define TENSOR_PARM_4(x, x2, x3, x4) x, #x, x2, #x2, x3, #x3, x4, #x4 #define TENSOR_PARM_5(x, x2, x3, x4, x5) \ x, #x, x2, #x2, x3, #x3, x4, #x4, x5, #x5 #define TENSOR_PARM_6(x, x2, x3, x4, x5, x6) \ x, #x, x2, #x2, x3, #x3, x4, #x4, x5, #x5, x6, #x6 #define TENSOR_PARM_7(x, x2, x3, x4, x5, x6, x7) \ x, #x, x2, #x2, x3, #x3, x4, #x4, x5, #x5, x6, #x6, x7, #x7 #define TENSOR_PARM_8(x, x2, x3, x4, x5, x6, x7, x8) \ x, #x, x2, #x2, x3, #x3, x4, #x4, x5, #x5, x6, #x6, x7, #x7, x8, #x8 #define TENSOR_PARM_9(x, x2, x3, x4, x5, x6, x7, x8, x9) \ x, #x, x2, #x2, x3, #x3, x4, #x4, x5, #x5, x6, #x6, x7, #x7, x8, #x8, x9, #x9 // Convenience macros with auto NULL-terminated variadic list #define VERIFY_FIELDS(type, format, ...) \ verify_fields(type, format, TENSOR_PARMS(__VA_ARGS__)(__VA_ARGS__), NO_ARG) #define VERIFY_DIM4(val, ...) \ verify_dim(4, val, TENSOR_PARMS(__VA_ARGS__)(__VA_ARGS__), NO_ARG) #define VERIFY_DIM3(val, ...) \ verify_dim(3, val, TENSOR_PARMS(__VA_ARGS__)(__VA_ARGS__), NO_ARG) #define VERIFY_DIM2(val, ...) \ verify_dim(2, val, TENSOR_PARMS(__VA_ARGS__)(__VA_ARGS__), NO_ARG) #define VERIFY_DIM1(val, ...) \ verify_dim(1, val, TENSOR_PARMS(__VA_ARGS__)(__VA_ARGS__), NO_ARG) #define VERIFY_HEIGHT VERIFY_DIM3 #define VERIFY_WIDTH VERIFY_DIM2 #define VERIFY_ALL_DIMS(val_dim4, val_dim3, val_dim2, val_dim1, ...) \ (verify_dim(4, val_dim4, TENSOR_PARMS(__VA_ARGS__)(__VA_ARGS__), NO_ARG) | \ verify_dim(3, val_dim3, TENSOR_PARMS(__VA_ARGS__)(__VA_ARGS__), NO_ARG) | \ verify_dim(2, val_dim2, TENSOR_PARMS(__VA_ARGS__)(__VA_ARGS__), NO_ARG) | \ verify_dim(1, val_dim1, TENSOR_PARMS(__VA_ARGS__)(__VA_ARGS__), NO_ARG)) #define IS_SHAPE_BIAS(tensor) \ (verify_dim(4, 1, TENSOR_PARMS(tensor)(tensor), NO_ARG) | \ verify_dim(3, 1, TENSOR_PARMS(tensor)(tensor), NO_ARG) | \ verify_dim(2, 1, TENSOR_PARMS(tensor)(tensor), NO_ARG)) /// Verifies if all tensors have exact same shape and data type and format /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[in] input_c The third input tensor /// \param[in] output output tensor /// /// \return ZDNN_OK /// ZDNN_INVALID_SHAPE /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_FORMAT /// zdnn_status verify_tensors(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, const zdnn_ztensor *output) { zdnn_status status; zdnn_tensor_desc *input_a_tfrmd_desc = input_a->transformed_desc; /* Parameter patterns: input_a | input_b | input_c | output --------+---------+---------+------- X | NULL | NULL | X X | X | NULL | X X | X | X | X Use input_a's as the "correct" value input_b and input_c are NULL when not being used */ // check shapes first if ((status = VERIFY_ALL_DIMS(input_a_tfrmd_desc->dim4, input_a_tfrmd_desc->dim3, input_a_tfrmd_desc->dim2, input_a_tfrmd_desc->dim1, output, input_b, input_c)) != ZDNN_OK) { return status; } // then check type and format if ((status = VERIFY_FIELDS(input_a_tfrmd_desc->type, input_a_tfrmd_desc->format, output, input_b, input_c)) != ZDNN_OK) { return status; } return status; } /// Verifies the condition of lstm/gru activation tensors, wrt AIU's /// LSTM_ACT/GRU_ACT ops /// /// \param[in] mode LSTM or GRU /// \param[in] ts_fused timestep fused for RNN activation call /// \param[in] bias_add_rnn_op bias tensor /// \param[in] prev_state previous state tensor (prev_c LSTM, prev_h GRU) /// \param[in] h_output h_output tensor /// \param[in] c_output c_output tensor (LSTM only, NULL if GRU) /// /// \return ZDNN_OK /// ZDNN_INVALID_SHAPE /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_FORMAT /// zdnn_status verify_lstm_or_gru_act_tensors(uint8_t function_code, const zdnn_ztensor *ts_fused, const zdnn_ztensor *bias_add_rnn_op, const zdnn_ztensor *prev_state, const zdnn_ztensor *h_output, const zdnn_ztensor *c_output) { /* DIMENSION REQUIREMENTS (NHWC, DLFLOAT16) Legend: g = number of gates (4 LSTM or 3 GRU) b = number of batches s = hidden state size | shape (dim4, dim3, dim2, dim1) ----------------+------------------------------------- ts_fused | (g,1,b,s) bias_add_rnn_op | (g,1,b,s) prev_state | (1,1,b,s) (LSTM prev_c, GRU prev_h) h_output | (1,1,b,s) c_output | (1,1,b,s) (LSTM only, GRU ignores) */ zdnn_status status; uint32_t num_gates = get_func_code_num_gates(function_code); // These should match in for all tensors so set the expected to one of them. uint32_t exp_dim2 = ts_fused->transformed_desc->dim2; uint32_t exp_dim1 = ts_fused->transformed_desc->dim1; zdnn_data_types exp_type = ts_fused->transformed_desc->type; zdnn_data_formats exp_format = ts_fused->transformed_desc->format; // check shapes if ((status = VERIFY_DIM4(1, prev_state, h_output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM4(num_gates, ts_fused, bias_add_rnn_op)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM3(1, ts_fused, bias_add_rnn_op, prev_state, h_output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM2(exp_dim2, ts_fused, bias_add_rnn_op, prev_state, h_output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM1(exp_dim1, ts_fused, bias_add_rnn_op, prev_state, h_output)) != ZDNN_OK) { return status; } if (function_code == NNPA_LSTMACT) { if ((status = VERIFY_DIM4(1, c_output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM3(1, c_output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM2(exp_dim2, c_output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM1(exp_dim1, c_output)) != ZDNN_OK) { return status; } } // then check type and format if ((status = VERIFY_FIELDS(exp_type, exp_format, ts_fused, bias_add_rnn_op, prev_state, h_output)) != ZDNN_OK) { return status; } if (function_code == NNPA_LSTMACT) { if ((status = VERIFY_FIELDS(exp_type, exp_format, c_output)) != ZDNN_OK) { return status; } } // If we reach this, all checks passed. Return OK return ZDNN_OK; } /// Verifies the condition of lstm/gru activation tensors, wrt ZDNN's /// zdnn_lstm()/zdnn_gru() functions /// /// \param[in] input The input tensor /// \param[in] h0 The initial hidden state tensor /// \param[in] c0 The initial cell state tensor /// \param[in] weights The concatenated weights tensor /// \param[in] biases The concatenated biases tensor /// \param[in] hidden_weights The concatenated hidden weights tensor /// \param[in] hidden_biases The concatenated hidden biases tensor /// \param[in] direction Direction (FWD, BWD, BIDIR) /// \param[out] hn_output The output hidden_state tensor /// \param[out] cf_output The output cell_state tensor /// /// \return ZDNN_OK if all checks pass or a failure based on why it failed. /// zdnn_status verify_zdnn_lstm_or_gru_tensors( uint8_t function_code, const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *c0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, const zdnn_ztensor *hn_output, const zdnn_ztensor *cf_output) { /* DIMENSION REQUIREMENTS (stickified, i.e., NHWC) Legend: b = number of batches d = number of directions (2 if BIDIR or otherwise 1) f = number of features g = number of gates (4 LSTM or 3 GRU) s = hidden state size s_pad = ceil(s/64) * 64 (s with padding to nearest multiple of 64) in_pad = g * s_pad (horizontally concatenated gate input with padding between gates) out_pad = d * s_pad (horizontally concatenated output with padding between directions) ts = number of timesteps Note: The *_output expected shape differs based on unidirectional versus bidirectional. For hn_output, the user specified shape also controls whether all timestep results are returned or just the final result processed. tensor | tfrmd (dim4, 3, 2, 1) | Note ---------------+------------------------------------- input | (ts, 1, b, f) | h0 | (d, 1, b, s) | c0 | (d, 1, b, s) | (LSTM only, GRU NULL) weights | (d, 1, f, in_pad) | biases | (d, 1, 1, in_pad) | hidden_weights | (d, 1, s, in_pad) | hidden_biases | (d, 1, 1, in_pad) | ----------------------------+----------+----------------| hn_output | (ts, 1, b, s) | (uni all timesteps) | (1, 1, b, s) | (uni final only) | (ts, 1, b, out_pad) | (bidir all out_pad) | (1, 1, b, out_pad) | (bidir final only) cf_output | (1, 1, b, s) | (uni LSTM only, GRU NULL) | (1, 1, b, out_pad) | (bidir LSTM only, GRU NULL) */ zdnn_status status; uint32_t exp_val; // consider input and h0 are the "correct" value for comparsions zdnn_tensor_desc *input_tfrmd_desc = input->transformed_desc; zdnn_tensor_desc *h0_tfrmd_desc = h0->transformed_desc; // order of checks: // dims: // - entries related to input dim4 (num_timesteps) // - entries related to input dim2 (num_batches) // - entries related to input dim1 (num_features) // - dim3 of all tensors must be 1 // - dim2 of biases/hidden_biases must be 1 // - entries related to h0 dim4 (num_dirs) // - entries related to h0 dim1 (num_hidden) // data-type and format // // layouts aren't checked as it doesn't impact the actual aiu_lstm_gru() // operation // input_tfrmd_desc dim4 (ts) must not be 0 as it is used for division and // will result in ABEND. if (input_tfrmd_desc->dim4 == 0) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "input dim4 tensor shape is invalid (found %d)", input_tfrmd_desc->dim4); } // hn_output dim4 (ts) must be either 1 or same as input's // not using VERIFY_DIM4 macro because we have 2 valid values if ((hn_output->transformed_desc->dim4 != input_tfrmd_desc->dim4) && (hn_output->transformed_desc->dim4 != 1)) { return ZDNN_STATUS( ZDNN_INVALID_SHAPE, "hn_output dim4 tensor shape is invalid (found %d, expects %d or 1)", hn_output->transformed_desc->dim4, input_tfrmd_desc->dim4); } // check input dim2 (num_batches) exp_val = input_tfrmd_desc->dim2; if ((status = VERIFY_DIM2(exp_val, h0, hn_output)) != ZDNN_OK) { return status; } if (function_code == NNPA_LSTMACT && ((status = VERIFY_DIM2(exp_val, c0, cf_output)) != ZDNN_OK)) { return status; } // weight's dim2 must be same as input's dim1 (num_features) exp_val = input_tfrmd_desc->dim1; if ((status = VERIFY_DIM2(exp_val, weights)) != ZDNN_OK) { return status; } // dim3 of all tensors should be 1 if ((status = VERIFY_DIM3(1, input, h0, weights, biases, hidden_weights, hidden_biases, hn_output)) != ZDNN_OK) { return status; } if (function_code == NNPA_LSTMACT && ((status = VERIFY_DIM3(1, c0, cf_output)) != ZDNN_OK)) { return status; } // check biases/hidden_biases dim2 = 1 if ((status = VERIFY_DIM2(1, biases, hidden_biases)) != ZDNN_OK) { return status; } // all num_dirs must have the same value exp_val = h0_tfrmd_desc->dim4; if ((status = VERIFY_DIM4(exp_val, weights, biases, hidden_weights, hidden_biases)) != ZDNN_OK) { return status; } if (function_code == NNPA_LSTMACT && (status = VERIFY_DIM4(exp_val, c0)) != ZDNN_OK) { return status; } // num_dirs must agree with "direction" exp_val = (direction == BIDIR) ? 2 : 1; if ((status = VERIFY_DIM4(exp_val, h0)) != ZDNN_OK) { return status; } // hn_output/cf_output dim1 = num_hidden (un-bir) // 2 * PADDED(num_hidden) (bi-dir) exp_val = (h0->transformed_desc->dim4 == 2) ? 2 * PADDED(h0->transformed_desc->dim1) : h0->transformed_desc->dim1; if ((status = VERIFY_DIM1(exp_val, hn_output)) != ZDNN_OK) { return status; } if (function_code == NNPA_LSTMACT) { if ((status = VERIFY_DIM1(exp_val, cf_output)) != ZDNN_OK) { return status; } } // weight/biases/etc = num_gates * num_hidden exp_val = get_func_code_num_gates(function_code) * PADDED(h0->transformed_desc->dim1); if ((status = VERIFY_DIM1(exp_val, weights, biases, hidden_weights, hidden_biases)) != ZDNN_OK) { return status; } // h0/c0 dim1 agree with each other exp_val = h0->transformed_desc->dim1; if (function_code == NNPA_LSTMACT) { if ((status = VERIFY_DIM1(exp_val, c0)) != ZDNN_OK) { return status; } } // hidden_weights dim2 = num_hidden if ((status = VERIFY_DIM2(exp_val, hidden_weights)) != ZDNN_OK) { return status; } // check type and format if ((status = VERIFY_FIELDS(input_tfrmd_desc->type, input_tfrmd_desc->format, h0, weights, biases, hidden_weights, hidden_biases, hn_output)) != ZDNN_OK) { return status; } if (function_code == NNPA_LSTMACT) { if ((status = VERIFY_FIELDS(input_tfrmd_desc->type, input_tfrmd_desc->format, c0, cf_output)) != ZDNN_OK) { return status; } } // If we reach this, all checks passed. Return OK return ZDNN_OK; } /// Verifies the condition of fused matmul bias add (broadcast) tensors. /// /// The following conditions are checked: /// /// Matmul Op: /// - The dimension-4-index-size of all input tensors and the output /// tensor are not all equal. /// /// Matmul Bcast Op: /// - The dimension-4-index-size of input tensor 1 and output /// tensor are not equal. /// - The dimension-4-index-size of input tensor 2 and input 3 are not /// equal to 1. /// /// Common: /// - The dimension-3-index-size of all input tensors and the output /// tensor are not equal to 1. /// - The dimension-2-index-size of input tensor 3 is not equal to 1. /// - The dimension-2-index-size of input tensor 1 and output tensor /// are not equal. /// - The dimension-1-index-size of input tensor 1 is not equal to the /// dimensions-2-index-size of input tensor 2. /// - The dimension-1-index-size of input tensor 2, input tensor 3, and /// output tensor are not equal. /// - The format of the input tensor differs from the format of the output /// tensor. /// - The data type of the input tensors differs from the data type of /// the output tensor. /// /// \param[in] uint8_t function_code, /// NNPA_MATMUL_OP or NNPA_MATMUL_OP_BCAST23 /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[in] input_c The third input tensor /// \param[in] output output tensor /// /// \return ZDNN_OK /// ZDNN_INVALID_SHAPE /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_FORMAT /// static zdnn_status verify_matmul_op_common(uint8_t function_code, const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, const zdnn_ztensor *output) { zdnn_status status; zdnn_tensor_desc *input_a_tfrmd_desc = input_a->transformed_desc; // check shapes first // For matmul_op, all tensors must have the same number of stacks (dim4) if (function_code == NNPA_MATMUL_OP) { if ((status = VERIFY_DIM4(input_a_tfrmd_desc->dim4, input_b, input_c, output)) != ZDNN_OK) { return status; } // For matmul_bcast_op, input_a and output tensors must have the same // number of stacks (dim4) but input_b and input_c tensors must have a stack // dimension of 1 as they are broadcasted over each stack of the input. } else { if ((status = VERIFY_DIM4(input_a_tfrmd_desc->dim4, output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM4(1, input_b, input_c)) != ZDNN_OK) { return status; } } if ((status = VERIFY_DIM3(1, input_a, input_b, input_c, output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM2(1, input_c)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM2(input_a_tfrmd_desc->dim2, output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM2(input_a_tfrmd_desc->dim1, input_b)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM1(input_b->transformed_desc->dim1, input_c, output)) != ZDNN_OK) { return status; } // then check type and format if ((status = VERIFY_FIELDS(input_a_tfrmd_desc->type, input_a_tfrmd_desc->format, input_b, input_c, output)) != ZDNN_OK) { return status; } return status; } zdnn_status verify_matmul_op_tensors(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, const zdnn_ztensor *output) { return verify_matmul_op_common(NNPA_MATMUL_OP, input_a, input_b, input_c, output); } zdnn_status verify_matmul_bcast_op_tensors(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, const zdnn_ztensor *output) { return verify_matmul_op_common(NNPA_MATMUL_OP_BCAST23, input_a, input_b, input_c, output); } /// Verifies the condition of input and output tensors for batchnorm operation. /// /// The following conditions are checked: /// /// - The shape of input tensor 1 differs from the shape of the output /// tensor. /// - The format of the input tensor differs from the format of the output /// tensor. /// - The data type of the input tensors differs from the data type of the /// output tensor. /// - Input tensors 1, 2, 3 and the output tensor do not have the same /// dimension-1-index-size. /// - The dimension 2,3 and 4 index sizes of input tensors 2 and 3 are not 1 /// /// \param[in] input_a The first input tensor /// \param[in] input_b The second input tensor /// \param[in] input_c The third input tensor /// \param[in] output output tensor /// /// \return ZDNN_OK /// ZDNN_INVALID_SHAPE /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_FORMAT /// zdnn_status verify_batchnorm_tensors(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, const zdnn_ztensor *output) { zdnn_status status; zdnn_tensor_desc *input_tfrmd_desc = input_a->transformed_desc; // check shapes first if ((status = VERIFY_ALL_DIMS(input_tfrmd_desc->dim4, input_tfrmd_desc->dim3, input_tfrmd_desc->dim2, input_tfrmd_desc->dim1, output)) != ZDNN_OK) { return status; } if ((status = VERIFY_DIM1(input_a->transformed_desc->dim1, input_b, input_c, output)) != ZDNN_OK) { return status; } if ((status = (IS_SHAPE_BIAS(input_b) | IS_SHAPE_BIAS(input_c))) != ZDNN_OK) { return status; } // then check type and format if ((status = VERIFY_FIELDS(input_a->transformed_desc->type, input_a->transformed_desc->format, output)) != ZDNN_OK) { return status; } return status; } /// Verifies the condition of input and output tensors for average pool /// operation. /// /// \param[in] input input tensor /// \param[in] padding_type /// \param[in] kernel_height /// \param[in] kernel_width /// \param[in] stride_height /// \param[in] stride_width /// \param[in] output output tensor /// /// \return ZDNN_OK /// ZDNN_INVALID_SHAPE /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_FORMAT /// ZDNN_INVALID_STRIDE_PADDING /// ZDNN_INVALID_STRIDES /// zdnn_status verify_pool_avg_max_tensors( const zdnn_ztensor *input, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, const zdnn_ztensor *output) { // Convenience variables used later zdnn_status status; uint32_t input_c_size = input->transformed_desc->dim1; uint32_t input_w_size = input->transformed_desc->dim2; uint32_t input_h_size = input->transformed_desc->dim3; uint32_t input_n_size = input->transformed_desc->dim4; uint32_t output_w_size = output->transformed_desc->dim2; uint32_t output_h_size = output->transformed_desc->dim3; uint32_t expected_output_w_size, expected_output_h_size; LOG_DEBUG( "%s() - padding_type: %d, input_ztensor->transformed_desc shape: (%d, " "%d, %d, %d) (NHWC order), kernel_height: %d, kernel_width: %d, " "stride_height: %d, stride_width %d, output_ztensor->transformed_desc " "shape: (%d, %d, %d, %d) (NHWC order)", __func__, padding_type, input->transformed_desc->dim4, input_h_size, input_w_size, input->transformed_desc->dim1, kernel_height, kernel_width, stride_height, stride_width, output->transformed_desc->dim4, output_h_size, output_w_size, output->transformed_desc->dim1); // check tensor shapes first if ((status = (VERIFY_DIM4(input_n_size, output) | VERIFY_DIM1(input_c_size, output))) != ZDNN_OK) { return status; } // Check that input and output have the same type and format // Note: If the output data type is invalid, the AIU may raise a // condition code before we'd reach this exception condition. if ((status = VERIFY_FIELDS(input->transformed_desc->type, input->transformed_desc->format, output)) != ZDNN_OK) { return status; } // Checks for when strides are 0 if (stride_width == 0 && stride_height == 0) { if (input_w_size != kernel_width) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "When strides are 0, the input tensor's width " "(%d) and kernel_width (%d) must be equal.", input_w_size, kernel_width); } if (input_h_size != kernel_height) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "When strides are 0, the input tensor's height " "(%d) and kernel_height (%d) must be equal.", input_h_size, kernel_height); } if (output_w_size != 1 || output_h_size != 1) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "When strides are 0, the output tensor's height " "(%d) and width (%d) must both be 1", output_h_size, output_w_size); } if (padding_type != VALID_PADDING) { return ZDNN_STATUS( ZDNN_INVALID_STRIDE_PADDING, "When strides are 0, the padding_type must be VALID_PADDING", NO_ARG); } // Checks that if one stride is nonzero then both must be nonzero. // We're following order as described in doc to make future comparing easier // so we can't just make this the final "else" condition. This boolean is an // XOR and will only be true if one (and only one) of these are nonzero. } else if (!stride_width != !stride_height) { return ZDNN_STATUS(ZDNN_INVALID_STRIDES, "When either stride is non-zero, then both strides " "must be non-zero. Stride width (%d), Stride height " "(%d)", output_h_size, output_w_size); // Checks for when strides are both nonzero } else { bool check_output_size = true; switch (padding_type) { case VALID_PADDING: if (kernel_width > input_w_size) { return ZDNN_STATUS( ZDNN_INVALID_SHAPE, "When VALID_PADDING is used, the the kernel_width (%d) " "must not be larger than the input tensor's width (%d) ", kernel_width, input_w_size); } if (kernel_height > input_h_size) { return ZDNN_STATUS( ZDNN_INVALID_SHAPE, "When VALID_PADDING is used, the the kernel_height (%d) " "must not be larger than the input tensor's height (%d) ", kernel_height, input_h_size); } expected_output_w_size = CEIL(input_w_size - kernel_width + 1, stride_width); expected_output_h_size = CEIL(input_h_size - kernel_height + 1, stride_height); break; case SAME_PADDING: expected_output_w_size = CEIL(input_w_size, stride_width); expected_output_h_size = CEIL(input_h_size, stride_height); break; default: // An invalid padding type raises a condition code from the hardware // so it isn't something we need to raise an error for here. However // without a type we can't know what to expect for the later output size // check. Instead we log a warning and will skip that check. LOG_WARN("Not valid padding type (%d)", padding_type); check_output_size = false; break; } if (check_output_size) { if (output_w_size != expected_output_w_size || output_h_size != expected_output_h_size) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "Expected the output tensor's height (%d) to " "be %d and width (%d) to be %d", output_h_size, expected_output_h_size, output_w_size, expected_output_h_size); } } } return ZDNN_STATUS_OK; } /// Verifies the condition of input and output tensors for convolution /// operation. /// /// \param[in] input input tensor /// \param[in] kernel input kernel tensor /// \param[in] bias input bias tensor /// \param[in] pad_n_act padding type and act function in AIU's /// function-specific-parameter-1 format /// \param[in] stride_height /// \param[in] stride_width /// \param[in] output output tensor /// /// \return ZDNN_OK /// ZDNN_INVALID_SHAPE /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_FORMAT /// ZDNN_INVALID_STRIDE_PADDING /// ZDNN_INVALID_STRIDES /// zdnn_status verify_conv2d_tensors(const zdnn_ztensor *input, const zdnn_ztensor *kernel, const zdnn_ztensor *bias, uint32_t pad_n_act, uint32_t stride_height, uint32_t stride_width, uint32_t reserved_n_clipping, const zdnn_ztensor *output) { zdnn_status status; // hw doc calls input => input1, kernel => input2, bias => input3 // stride_height => dim3_stride, stride_width => dim2_stride zdnn_tensor_desc *input_desc = input->transformed_desc, *input_kernel_desc = kernel->transformed_desc, *output_desc = output->transformed_desc; func_sp_parm1_conv2d conv2d_parm1; conv2d_parm1.val = pad_n_act; // The dimension-2, dimension-3, and dimension-4 index sizes of the input3 // must be 1. if ((status = (IS_SHAPE_BIAS(bias))) != ZDNN_OK) { return status; } // The dimension-4-index-size of the output must be equal to the // dimension-4-index-size of the input1. if ((status = VERIFY_DIM4(input_desc->dim4, output)) != ZDNN_OK) { return status; } // The dimension-1 index size of the output must be equal to the dimension-1 // index size of the input2 and the dimension-1-index size of the input3. if ((status = VERIFY_DIM1(output_desc->dim1, kernel, bias)) != ZDNN_OK) { return status; } // The dimension-1 index size of the input1 must be equal to the dimension-2 // index size of the input2. if ((status = VERIFY_DIM1(input_kernel_desc->dim2, input)) != ZDNN_OK) { return status; } if (!stride_height && !stride_width) { // both zero // The input1 dimension-2-index-size must be equal to the // dimension-3-index-size of input2. if (input_desc->dim2 != input_kernel_desc->dim3) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "input_desc->dim2" " (%d) must be equal to " "input_kernel_desc->dim3" " (%d)\n", input_desc->dim2, input_kernel_desc->dim3); } // The input1 dimension-3-index-size must be equal to the // dimension-4-index-size of input2. if (input_desc->dim3 != input_kernel_desc->dim4) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "input_desc->dim3" " (%d) must be equal to " "input_kernel_desc->dim4" " (%d)\n", input_desc->dim3, input_kernel_desc->dim4); } // The dimension-2-index-size and the dimension-3-index-size of the output // must be one. if (output_desc->dim2 != 1) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "output_desc->dim2" " (%d) must be 1\n", output_desc->dim2); } if (output_desc->dim3 != 1) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "output_desc->dim3" " (%d) must be 1\n", output_desc->dim3); } // The specified padding must be VALID if (conv2d_parm1.bits.pad != VALID_PADDING) { return ZDNN_STATUS(ZDNN_INVALID_STRIDE_PADDING, "padding must be VALID_PADDING when both " "stride_height (%d) and stride_width (%d) are zero", stride_height, stride_width); } } else if (stride_height && stride_width) { // both > 0 switch (conv2d_parm1.bits.pad) { case VALID_PADDING: // the dimension-2-index-size of the input1 must be greater than or equal // to the dimension-3-index-size of input2. if (input_desc->dim2 < input_kernel_desc->dim3) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "input_desc->dim2" " (%d) must be greater than or equal to " "input_kernel_desc->dim3" " (%d)\n", input_desc->dim2, input_kernel_desc->dim3); } // the dimension-3-index-size of the input1 must be greater than or equal // to the dimension-4-index-size of the input2 if (input_desc->dim3 < input_kernel_desc->dim4) { return ZDNN_STATUS(ZDNN_INVALID_SHAPE, "input_desc->dim3" " (%d) must be greater than or equal to " "input_kernel_desc->dim4" " (%d)\n", input_desc->dim3, input_kernel_desc->dim4); } if ((status = VERIFY_DIM2(CEIL(input_desc->dim2 - input_kernel_desc->dim3 + 1, stride_width), output) | VERIFY_DIM3(CEIL(input_desc->dim3 - input_kernel_desc->dim4 + 1, stride_height), output)) != ZDNN_OK) { return status; } break; case SAME_PADDING: if ((status = VERIFY_DIM2(CEIL(input_desc->dim2, stride_width), output) | VERIFY_DIM3(CEIL(input_desc->dim3, stride_height), output)) != ZDNN_OK) { return status; } break; default: // keep going to the next check, the hardware will handle it with function // specific RC later LOG_WARN("Not valid padding type (%d)", conv2d_parm1.bits.pad); break; } } else { // only either is zero return ZDNN_STATUS(ZDNN_INVALID_STRIDES, "either both stride_height (%d) and stride_width (%d) " "must be non-zero or both be must be zero\n", stride_height, stride_width); } // data type/format of input3 and output should match input1's if ((status = VERIFY_FIELDS(input_desc->type, input_desc->format, bias, output)) != ZDNN_OK) { return status; } // data type of input2 should match input1's // not checking input2's format (should be ZDNN_FORMAT_4DKERNEL), let hardware // handle it with reponse code if not if ((status = VERIFY_FIELDS(input_desc->type, input_kernel_desc->format, kernel)) != ZDNN_OK) { return status; } // If activation is set to RELU, check clipping value. if (conv2d_parm1.bits.act == CONV2D_ACT_RELU) { func_sp_parm4_conv2d conv2d_parm4; conv2d_parm4.val = reserved_n_clipping; // Clipping value cannot be negative. if (conv2d_parm4.bits.clipping_value & 0x8000) { return ZDNN_STATUS(ZDNN_INVALID_CLIPPING_VALUE, "Clipping value cannot be negative.", NO_ARG); } // Clipping value cannot be NINF+ if (conv2d_parm4.bits.clipping_value == 0x7FFF) { return ZDNN_STATUS(ZDNN_INVALID_CLIPPING_VALUE, "Conversion of clipping value unsuccessful.", NO_ARG); } } return ZDNN_STATUS_OK; } /// Verifies the condition of input and output tensors for relu operation. /// /// \param[in] input input tensor /// \param[in] reserved_n_clipping reserved and clipping value in AIU's /// function-specific-parameter-1 format /// \param[in] output output tensor /// /// \return ZDNN_OK /// ZDNN_INVALID_SHAPE /// ZDNN_INVALID_TYPE /// ZDNN_INVALID_FORMAT /// ZDNN_INVALID_CLIPPING_VALUE /// zdnn_status verify_relu_tensors(const zdnn_ztensor *input, uint32_t reserved_n_clipping, const zdnn_ztensor *output) { zdnn_status status; if ((status = verify_tensors(input, NULL, NULL, output)) != ZDNN_OK) { return status; } func_sp_parm1_relu relu_parm1; relu_parm1.val = reserved_n_clipping; // Clipping value cannot be negative. if (relu_parm1.bits.clipping_value & 0x8000) { return ZDNN_STATUS(ZDNN_INVALID_CLIPPING_VALUE, "Clipping value cannot be negative.", NO_ARG); } // Clipping value cannot be NINF+ if (relu_parm1.bits.clipping_value == 0x7FFF) { return ZDNN_STATUS(ZDNN_INVALID_CLIPPING_VALUE, "Conversion of clipping value unsuccessful.", NO_ARG); } return ZDNN_STATUS_OK; } ������������������zDNN-1.0.1/zdnn/utils.c�����������������������������������������������������������������������������0000664�0000000�0000000�00000026272�14364043643�0014617�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <inttypes.h> #include <stddef.h> #include <stdio.h> /// Print value at ptr, up to size number of bytes, in binary bits /// /// \param[in] size Number of bytes to be printed /// \param[in] ptr Pointer to values /// /// \return None /// // cppcheck-suppress unusedFunction void print_bits(size_t const size, void const *const ptr) { unsigned char *b = (unsigned char *)ptr; unsigned char byte; int i, j; for (i = 0; i < size; i++) { for (j = 7; j >= 0; j--) { byte = (b[i] >> j) & 1; printf("%u", byte); } printf(" "); } printf("\n"); } /// Print value at ptr, up to size number of bytes, in hex, with seperations /// /// \param[in] size Number of bytes to be printed /// \param[in] ptr Pointer to values /// /// \return None /// void print_hex(size_t const size, void const *const ptr) { unsigned char *b = (unsigned char *)ptr; for (int i = 0; i < size; i++) { // every 64-bytes: print line-break and offset if ((i % 64) == 0) { if (i) { printf("\n"); } printf("%08x: ", i); } // every 4-bytes: print a space if ((i % 4) == 0) { printf(" "); } printf("%02X", *(b + i)); } printf("\n"); } /// Set bit at bit_pos to 1 in a bit128_t struct /// Bit position is determined from left to right of uint64_t field /// /// \param[in] field Pointer to bit128_t struct /// \param[in] bit_pos 0-based bit position /// /// \return None /// void setbit_128(bit128_t *field, uint8_t bit_pos) { if (bit_pos < 64) { field->bits_0to63 |= (uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - bit_pos); } else if (bit_pos < 128) { field->bits_64to127 |= (uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - (bit_pos - 64)); } } /// Test if bit at bit_pos is 1 in a bit128_t struct /// Bit position is assumed to be left to right of uint64_t field /// /// \param[in] field Pointer to bit128_t struct /// \param[in] bit_pos 0-based bit position /// /// \return true or false /// bool is_bitset_128(bit128_t field, uint8_t bit_pos) { if (bit_pos < 64) { return field.bits_0to63 & ((uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - bit_pos)); } else if (bit_pos < 128) { return field.bits_64to127 & ((uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - (bit_pos - 64))); } else { return false; } } /// Set bit at bit_pos to 1 in a bit256_t struct /// Bit position is determined from left to right of uint64_t field /// /// \param[in] field Pointer to bit256_t struct /// \param[in] bit_pos 0-based bit position /// /// \return None /// void setbit_256(bit256_t *field, uint16_t bit_pos) { if (bit_pos < 64) { field->bits_0to63 |= (uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - bit_pos); } else if (bit_pos < 128) { field->bits_64to127 |= (uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - (bit_pos - 64)); } else if (bit_pos < 192) { field->bits_128to191 |= (uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - (bit_pos - 128)); } else if (bit_pos < 256) { field->bits_192to255 |= (uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - (bit_pos - 192)); } } /// Test if bit at bit_pos is 1 in a bit256_t struct /// Bit position is assumed to be left to right of uint64_t field /// /// \param[in] field Pointer to bit256_t struct /// \param[in] bit_pos 0-based bit position /// /// \return true or false /// bool is_bitset_256(bit256_t field, uint16_t bit_pos) { if (bit_pos < 64) { return field.bits_0to63 & ((uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - bit_pos)); } else if (bit_pos < 128) { return field.bits_64to127 & ((uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - (bit_pos - 64))); } else if (bit_pos < 192) { return field.bits_128to191 & ((uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - (bit_pos - 128))); } else if (bit_pos < 256) { return field.bits_192to255 & ((uint64_t)1 << ((BIT_SIZEOF(uint64_t) - 1) - (bit_pos - 192))); } else { return false; } } /// Get the number of elements based on a tensor's dimensions. /// /// \param[in] ztensor zDNN tensor to get element count from /// \param[in] elements_mode controls how to count elements. /// /// ELEMENTS_AIU - /// All elements wrt the AIU (ie the tfrmd shape) /// For concatenated and RNN output tensors, this includes horizontal /// and vertical paddings /// /// ELEMENTS_PRE / ELEMENTS_PRE_SINGLE_GATE - /// For non-concatenated tensor, this represents the number of elements /// wrt the pre-transformed shape /// For concatenated tensor, this represents the number of elements of /// a single gate without padding (ie the pre_tfrmd shape) /// /// ELEMENTS_PRE_ALL_GATES - /// Total number of elements (all gates) but do not include the zero /// padding elements (ie ELEMENTS_PRE_SINGLE_GATE * num_gates) /// *** THIS MODE RETURNS ZERO ON NON-CONCATENATED TENSOR! *** /// /// \return number of elements based on desired mode /// uint64_t get_num_elements(const zdnn_ztensor *ztensor, elements_mode mode) { uint64_t num_elements = 1; uint32_t *dims_ptr; int i; // For tensors that have no horizontal/vertical paddings or concatenation etc, // ELEMENTS_PRE, ELEMENTS_PRE_SINGLE_GATE, ELEMENTS_AIU would yield the same // result so they're somewhat interchangeable. // // But for readability should not, for example, use ELEMENTS_PRE_SINGLE_GATE // on (e.g.) a non-concatenated (even though the result is "correct"). // Setup how to loop over the shape based on the mode. switch (mode) { case ELEMENTS_AIU: // tfrmd_desc shape accounts for all elements including both concat // horizontal and vertical paddings. dims_ptr = &(ztensor->transformed_desc->dim4); // Loop over all dims since tfrmd_dec sets any "unused" dimensions to 1. i = 0; break; case ELEMENTS_PRE: // = ELEMENTS_PRE_SINGLE_GATE case ELEMENTS_PRE_ALL_GATES: // Use pre_tfrmd_desc as we document that should be the shape of a single // horizontal-concat (or gate) and not the combined shape. dims_ptr = &(ztensor->pre_transformed_desc->dim4); // Loop will start at outermost dimension we expect for the layout. // For example: 2D gets dim2 and dim1. 3D gets dim3, dim2, and dim1. i = ZDNN_MAX_DIMS - get_data_layout_dims(ztensor->pre_transformed_desc->layout); break; default: LOG_WARN("%d is not a supported elements_mode", mode); return 0; break; } // Multiply by the size of each expected dimension for (; i < ZDNN_MAX_DIMS; i++) { num_elements *= (uint64_t)dims_ptr[i]; } if (mode == ELEMENTS_PRE_ALL_GATES) { // this will cause the function to return 0 if there's no gates to speak of num_elements *= get_data_layout_num_gates(ztensor->transformed_desc->layout); } return num_elements; } /// Prints out DLFLOAT16 buffer data. /// /// Example Output: /// Buffer: /// Size: 16384 /// Data: /// INDEX HEX /// 0 0041 /// 1 4100 /// 128 0042 /// 129 4200 /// 256 0043 /// . . /// 12544 004F /// 12545 4F00 /// 12672 0050 /// 12673 5000 /// ========================================= /// /// \param[in] buffer a pointer to a data buffer /// \param[in] buffer_size the size of the buffer /// /// \return None /// void print_dlf16_buffer(void *buffer, uint64_t buffer_size) { printf("Buffer:\n"); printf("\tSize:%" PRIu64 "\n", buffer_size); printf("\tData:\n\t\tINDEX\t\tHEX\n"); for (uint64_t i = 0; i < (buffer_size / 2); i++) { printf("\t\t%" PRIu64 "\t\t%04x\n", i, ((uint16_t *)buffer)[i]); } } /// Prints out tensor descriptor /// /// Example Output: /// Descriptor: /// Outermost Innermost /// Dimensions: 1 64 64 1 /// Layout: ZDNN_NHWC Format: ZDNN_FORMAT_4DFEATURE Type: FP16 /// /// \param[in] desc A tensor descriptor /// /// \return None /// void print_desc(zdnn_tensor_desc *desc) { printf("Descriptor:\n" "\t\t\tOutermost\t\t\t\tInnermost\n" "\tDimensions:\t%u\t\t%u\t\t%u\t\t%u\n" "\tLayout:\t%s\tFormat:\t%s\tType:\t%s\n", desc->dim4, desc->dim3, desc->dim2, desc->dim1, get_data_layout_str(desc->layout), get_data_format_str(desc->format), get_data_type_str(desc->type)); } /// Prints out ztensor information. /// /// Example Output: /// ========================================= /// Contents of zdnn_ztensor: input /// Pre-transformed Descriptor: /// Outermost Innermost /// Dimensions: 1 64 64 1 /// Layout: ZDNN_NHWC Format: ZDNN_FORMAT_4DFEATURE Type: FP16 /// Transformed Descriptor: /// Outermost Innermost /// Dimensions: 1 64 64 1 /// Layout: ZDNN_NHWC Format: ZDNN_FORMAT_4DFEATURE Type: /// ZDNN_DLFLOAT16 /// Buffer Addr: 5011007000 Size: 524288 /// Transformed: True /// /// Pool padding: SAME_PADDING /// /// Parameter kernel_height (uint32_t): 64 /// /// Parameter kernel_width (uint32_t): 64 /// /// Parameter stride_height (uint32_t): 1 /// /// Parameter stride_width (uint32_t): 1 /// Buffer: /// Size: 16384 /// Data: /// INDEX HEX /// 0 0041 /// 1 4100 /// 128 0042 /// 129 4200 /// 256 0043 /// . . /// 12544 004F /// 12545 4F00 /// 12672 0050 /// 12673 5000 /// ========================================= /// /// \param[in] ztensor Pointer to zdnn_ztensor to print /// \param[in] name Name of the zdnn_ztensor (e.g., variable name) /// \param[in] print_data Print data buffer or not /// /// \return None /// void print_ztensor(const zdnn_ztensor *ztensor, char *name, bool print_data) { printf("\n=========================================\n" "Contents of zdnn_ztensor: %s\n", name); printf("Pre-transformed "); print_desc(ztensor->pre_transformed_desc); printf("Transformed "); print_desc(ztensor->transformed_desc); printf("Buffer Addr:\t%" PRIxPTR "\tSize:\t%" PRIu64 "\n", (uintptr_t)ztensor->buffer, ztensor->buffer_size); printf("Transformed:\t"); if (ztensor->is_transformed) { printf("True"); } else { printf("False"); } printf("\n"); if (print_data) { print_dlf16_buffer(ztensor->buffer, ztensor->buffer_size); } printf("=========================================\n"); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/version.c���������������������������������������������������������������������������0000664�0000000�0000000�00000012471�14364043643�0015140�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "version.h" #include <string.h> #ifdef __MVS__ #pragma export(zdnn_is_version_runnable) #pragma export(zdnn_get_max_runnable_version) #endif // the latest "AIU hardware version" that this library can identify. // // conceptually, this is latest zDNN library version number that the current hw // is capable of driving, based on all hw version/revision information this // version of the library knows about. uint32_t aiu_lib_vernum; // ----------------------------------------------------------------------------- // nnpa signature // ----------------------------------------------------------------------------- aiu_hwinfo aiu_hwinfo_nnpa = { {0x80, 0x00, 0xfc, 0x00, 0xc0, 0x00, 0x78, 0x00, 0x80, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00}, {0xc0, 0x00, 0x00, 0x00}, 0x00008000, 0x0000000100000000, {0x60, 0x00}, "nnpa", LIB_VERNUM(1, 0, 0)}; // array of all known hw // ** put NEWER hw versions first !!! *** // ** MUST NULL TERMINATE !!! *** aiu_hwinfo *aiu_hwinfo_list[HWINFO_LIST_MAXSIZE] = {&aiu_hwinfo_nnpa, NULL}; /// Check if the bits specified in "bitmask" are all 1s in the memory block /// "memblk" of size "size" /// /// \param[in] bitmask pointer to the bitmask /// \param[in] memblk pointer to the memory block /// \param[in] size size of memory block /// /// \return true/false /// bool mem_check_bitmask(void *bitmask, void *memblk, size_t size) { bool is_match = true; // size of the memory block to check is always multiples of 2 for (uint64_t i = 0; i < size / 2 && is_match == true; i++) { uint16_t mask = ((uint16_t *)bitmask)[i]; uint16_t content = ((uint16_t *)memblk)[i]; is_match &= ((mask & content) == mask); } return is_match; } /// Refresh aiu_lib_vernum value by interpreting the NNPA-QAF result /// /// \param[in] None /// /// \return None /// void refresh_aiu_lib_vernum() { aiu_hwinfo **info = &aiu_hwinfo_list[0]; uint32_t c = 0; aiu_lib_vernum = AIU_UNKNOWN; while (*info && c < HWINFO_LIST_MAXSIZE) { // each aiu_hwinfo struct contains NNPA-QAF bitmasks and uint values of a // known AIU hw. so lets say we have x3 (newest), x2 and x1 (oldest) // // basically we look at the current NNPA-QAF result, and see if it: // - meets the bitmask requirements (so it can, e.g., do all the NNPA ops hw // x3 can do), via mem_check_bitmask() // - meets or exceeds the value requirements (e.g., it has equal or higher // MDIS value than hw x3), via >= // and if so then we know the hw is at least x3 capable. if not then try // the next older hw in the array. // // with this we can use an older minor version library on a newer hw (say, // x4) that the library doesn't know about and use it as x3, since it meets // x3's capabilities requirements if (mem_check_bitmask((*info)->blk1, QAF_BLK1_PTR, HWINFO_BLK1_LEN) && mem_check_bitmask((*info)->blk2, QAF_BLK2_PTR, HWINFO_BLK2_LEN) && (QAF_VAL1 >= (*info)->val1) && (QAF_VAL2 >= (*info)->val2) && mem_check_bitmask((*info)->blk3, QAF_BLK3_PTR, HWINFO_BLK3_LEN)) { // the latest and greatest that we know of. we're done aiu_lib_vernum = (*info)->lib_vernum; return; } info++; c++; } } /// Check if application built for zDNN version "ver_num" can be run on the /// current hardware with the installed zDNN library /// /// \param[in] ver_num zDNN version number from application /// /// \return true/false /// bool zdnn_is_version_runnable(uint32_t ver_num) { // 3 version numbers to deal with // - incoming ver_num // - this library's (ZDNN_VER_*) // - the hw's (aiu_lib_vernum) // major: all 3 must match if ((MAJOR(ver_num) != ZDNN_VER_MAJOR) || (MAJOR(ver_num) != MAJOR(aiu_lib_vernum))) { return false; } // minor: incoming ver_num must not be newer than library's // incoming ver_num must not be newer than hw's if (MINOR(ver_num) > ZDNN_VER_MINOR || MINOR(ver_num) > MINOR(aiu_lib_vernum)) { return false; } // patch: don't care return true; } /// Returns the maximum zDNN version number that the current hardware and /// installed zDNN library can run together /// /// \param[in] None /// /// \return version number /// uint32_t zdnn_get_max_runnable_version() { if (MAJOR(aiu_lib_vernum) != ZDNN_VER_MAJOR) { return AIU_UNKNOWN; } else { // return minimum ver_num between the library's and the hw's // set the patch byte to 0xFF so that it's at "max" return MIN(ZDNN_VERNUM, aiu_lib_vernum) | 0xFF; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/version.h���������������������������������������������������������������������������0000664�0000000�0000000�00000005727�14364043643�0015153�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ZDNN_VERSION_H_ #define ZDNN_VERSION_H_ #include <inttypes.h> #include <stdbool.h> #include "zdnn.h" #include "zdnn_private.h" // custom values for tests. #ifdef VERSION_C_TEST #undef ZDNN_VERNUM #undef ZDNN_VER_MAJOR #undef ZDNN_VER_MINOR #undef ZDNN_VER_PATCH #define ZDNN_VERNUM 0x050505 #define ZDNN_VER_MAJOR 0x05 #define ZDNN_VER_MINOR 0x05 #define ZDNN_VER_PATCH 0x05 #endif #define AIU_UNKNOWN 0x00000000 #define QAF_SIZEOF(x) sizeof((&nnpa_query_result)->x) #define HWINFO_BLK1_QAF_MEMBER installed_functions_vector #define HWINFO_BLK2_QAF_MEMBER installed_data_layout_formats #define HWINFO_BLK3_QAF_MEMBER installed_dt1_conversions_vector #define HWINFO_VAL1_QAF_MEMBER maximum_dimension_index_size #define HWINFO_VAL2_QAF_MEMBER maximum_tensor_size // 3 fields next to each other in nnpa_qaf_parameter_block #define HWINFO_BLK1_LEN \ (QAF_SIZEOF(HWINFO_BLK1_QAF_MEMBER) + \ QAF_SIZEOF(installed_parameter_block_formats) + \ QAF_SIZEOF(installed_data_types)) // installed_data_layout_formats #define HWINFO_BLK2_LEN (QAF_SIZEOF(HWINFO_BLK2_QAF_MEMBER)) // installed_dt1_conversions_vector alone #define HWINFO_BLK3_LEN (QAF_SIZEOF(HWINFO_BLK3_QAF_MEMBER)) #define QAF_BLK1_PTR (&nnpa_query_result.HWINFO_BLK1_QAF_MEMBER) #define QAF_BLK2_PTR (&nnpa_query_result.HWINFO_BLK2_QAF_MEMBER) #define QAF_BLK3_PTR (&nnpa_query_result.HWINFO_BLK3_QAF_MEMBER) #define QAF_VAL1 (nnpa_query_result.HWINFO_VAL1_QAF_MEMBER) #define QAF_VAL2 (nnpa_query_result.HWINFO_VAL2_QAF_MEMBER) #define HWINFO_DESC_STR_MAXSIZE 128 typedef struct aiu_hwinfo { // each member represent a contiguous segment or standalone value to check // within the nnpa_qaf_parameter_block char blk1[HWINFO_BLK1_LEN]; char blk2[HWINFO_BLK2_LEN]; uint32_t val1; // mdis uint64_t val2; // mts char blk3[HWINFO_BLK3_LEN]; char desc_str[HWINFO_DESC_STR_MAXSIZE]; // descriptive string uint32_t lib_vernum; // lib vernum to assign } aiu_hwinfo; #define LIB_VERNUM(major, minor, patch) ((major << 16) + (minor << 8) + patch) #define MAJOR(v) ((v >> 16) & 0xFF) #define MINOR(v) ((v >> 8) & 0xFF) #define PATCH(v) (v & 0xFF) #define HWINFO_LIST_MAXSIZE 256 extern aiu_hwinfo *aiu_hwinfo_list[HWINFO_LIST_MAXSIZE]; #endif /* ZDNN_VERSION_H_ */ �����������������������������������������zDNN-1.0.1/zdnn/zdnn.c������������������������������������������������������������������������������0000664�0000000�0000000�00000030163�14364043643�0014422�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zdnn.h" #include "zdnn_private.h" #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #if defined(__MVS__) #include <cvt.h> #include <ihaecvt.h> #include <ihafacl.h> #include <ihapsa.h> #endif /// Fill in NNPA tensor descriptor /// /// \param[out] descriptor pointer to an nnpa_parameter_block's descriptor /// \param[in] ztensor pointer to a zTensor /// /// \return None /// void populate_descriptor(nnpa_tensor_descriptor *descriptor, const zdnn_ztensor *ztensor) { descriptor->data_layout_format = ztensor->transformed_desc->format; descriptor->data_type = ztensor->transformed_desc->type; descriptor->dim4_index_size = ztensor->transformed_desc->dim4; descriptor->dim3_index_size = ztensor->transformed_desc->dim3; descriptor->dim2_index_size = ztensor->transformed_desc->dim2; descriptor->dim1_index_size = ztensor->transformed_desc->dim1; descriptor->tensor_data_addr = ztensor->buffer; } /// Fill in NNPA parameter block /// /// \param[out] parm_block pointer to a nnpa_parameter_block /// \param[in] input_ztensor1 /// \param[in] input_ztensor2 /// \param[in] input_ztensor3 /// \param[in] output_ztensor1 /// \param[in] output_ztensor2 /// \param[in] func_sp_savearea_addr Function-specific-save-area-address /// \param[in] func_sp_parm1 Function-specific-parameter-1 /// \param[in] func_sp_parm2 Function-specific-parameter-2 /// \param[in] func_sp_parm3 Function-specific-parameter-3 /// \param[in] func_sp_parm4 Function-specific-parameter-4 /// \param[in] func_sp_parm5 Function-specific-parameter-5 /// /// \return None /// void populate_nnpa_parm_block( nnpa_parameter_block *parm_block, const zdnn_ztensor *input_ztensor1, const zdnn_ztensor *input_ztensor2, const zdnn_ztensor *input_ztensor3, zdnn_ztensor *output_ztensor1, zdnn_ztensor *output_ztensor2, void *func_sp_savearea_addr, uint32_t func_sp_parm1, uint32_t func_sp_parm2, uint32_t func_sp_parm3, uint32_t func_sp_parm4, uint32_t func_sp_parm5) { // clear the block up to CSB memset(parm_block, 0, sizeof(nnpa_parameter_block) - offsetof(nnpa_parameter_block, continuation_state_buffer)); parm_block->parm_block_version_number = NNPA_PARM_BLOCK_VERSION; nnpa_tensor_descriptor *cur_desc_ptr; cur_desc_ptr = &(parm_block->input_tensor1); // there will be at least 1 input populate_descriptor(cur_desc_ptr, input_ztensor1); if (input_ztensor2) { cur_desc_ptr++; populate_descriptor(cur_desc_ptr, input_ztensor2); if (input_ztensor3) { cur_desc_ptr++; populate_descriptor(cur_desc_ptr, input_ztensor3); } } cur_desc_ptr = &(parm_block->output_tensor1); // there will be at least 1 output populate_descriptor(cur_desc_ptr, output_ztensor1); if (output_ztensor2) { cur_desc_ptr++; populate_descriptor(cur_desc_ptr, output_ztensor2); } parm_block->function_specific_save_area_address = (uintptr_t)func_sp_savearea_addr; parm_block->function_specific_parm1 = func_sp_parm1; parm_block->function_specific_parm2 = func_sp_parm2; parm_block->function_specific_parm3 = func_sp_parm3; parm_block->function_specific_parm4 = func_sp_parm4; parm_block->function_specific_parm5 = func_sp_parm5; } /// Invoke the NNPA instruction to drive a request to the AIU /// /// \param[in] function_code 1 byte AIU function code /// \param[in] parm_block pointer to a nnpa_parameter_block /// \param[out] exception_flags 1 byte output exception flags /// /// \return ZDNN_OK /// ZDNN_UNAVAILABLE_FUNCTION /// ZDNN_MISALIGNED_PARMBLOCK /// ZDNN_HW_ERROR + hardware response code /// zdnn_status invoke_nnpa(uint8_t function_code, char *parm_block, uint8_t *exception_flags) { uint32_t cc = 0; nnpa_return rtn; // nnpa_return size set by NNPA architecture rtn.r0 = 0; if (precheck_enabled) { // When not on performance path add extra check to ensure NNPA parm block is // on a doubleword boundary. if ((uint64_t)parm_block & 7) { return ZDNN_STATUS_NO_MSG(ZDNN_MISALIGNED_PARMBLOCK); } } BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { if (function_code != NNPA_QAF) { printf("invoke_nnpa func_code %d\n", function_code); printf("invoke_nnpa input_tensor1:\n"); print_hex(sizeof(nnpa_tensor_descriptor), &((nnpa_parameter_block *)parm_block)->input_tensor1); printf("\n"); printf(" input_tensor2:\n"); print_hex(sizeof(nnpa_tensor_descriptor), &((nnpa_parameter_block *)parm_block)->input_tensor2); printf("\n"); printf(" input_tensor3:\n"); print_hex(sizeof(nnpa_tensor_descriptor), &((nnpa_parameter_block *)parm_block)->input_tensor3); printf("\n"); printf(" output_tensor1:\n"); print_hex(sizeof(nnpa_tensor_descriptor), &((nnpa_parameter_block *)parm_block)->output_tensor1); printf("\n"); printf(" output_tensor2:\n"); print_hex(sizeof(nnpa_tensor_descriptor), &((nnpa_parameter_block *)parm_block)->output_tensor2); printf("\n"); printf(" function_specific_parm1:\n"); print_hex(sizeof(uint32_t), &((nnpa_parameter_block *)parm_block)->function_specific_parm1); printf("\n"); printf(" function_specific_parm2:\n"); print_hex(sizeof(uint32_t), &((nnpa_parameter_block *)parm_block)->function_specific_parm2); printf("\n"); printf(" function_specific_parm3:\n"); print_hex(sizeof(uint32_t), &((nnpa_parameter_block *)parm_block)->function_specific_parm3); printf("\n"); printf(" function_specific_parm4:\n"); print_hex(sizeof(uint32_t), &((nnpa_parameter_block *)parm_block)->function_specific_parm4); printf("\n"); printf(" function_specific_parm5:\n"); print_hex(sizeof(uint32_t), &((nnpa_parameter_block *)parm_block)->function_specific_parm5); printf("\n"); printf(" function_specific_save_area_address:\n"); print_hex(sizeof(void *), &((nnpa_parameter_block *)parm_block) ->function_specific_save_area_address); printf("\n"); } } // clang-format off #if defined(__MVS__) struct psa *psaptr = (struct psa *)0; // set _cvt to x10, the pointer to the CVT on z/OS // cppcheck-suppress nullPointer struct cvtmap *cvtptr = (struct cvtmap *)psaptr->flccvt; struct ecvt *ecvtptr = (struct ecvt *)cvtptr->cvtecvt; struct facl *faclptr = (struct facl *)ecvtptr->ecvtfacl; #ifndef ZDNN_CONFIG_NO_NNPA // If NNPA build, do NNPA with hardcoded opcode if (faclptr->faclnnpaf) { __asm volatile( " LLGC 0,%[valfunctionCode] \n\t" // Insert function in R0 " LG 1,%[parm_block] \n\t" // R1=parm_block, which is a pointer " DC XL4'B93B0000' \n\t" // NNPA " JO -2 \n\t" // jump back for CC3 " IPM %[cc] \n\t" // fetch cc to cc reg " SRL %[cc],28 \n\t" // shift " LGR %[areannpa_return],0 \n\t" : [cc] "+d" (cc), // ASM outputs [areannpa_return] "=d" (rtn.r0) : [valfunctionCode] "m" (function_code), // ASM inputs [parm_block] "m" (parm_block) : "r0", "r1", "cc"); /* Clobbers - R0, R1, cond code */ } else { return ZDNN_STATUS(ZDNN_UNAVAILABLE_FUNCTION, "NNPA facility unavailable", NO_ARG); } #else __asm volatile( " LLGC 0,%[valfunctionCode] \n\t" // Insert function in R0 " LG 1,%[parm_block] \n\t" // R1=parm_block, which is a pointer " LGHI %[areannpa_return],0 \n\t" // simulate goodness " LGHI %[cc],0 \n\t" : [cc] "+d" (cc), // ASM outputs [areannpa_return] "=d" (rtn.r0) : [valfunctionCode] "m" (function_code), // ASM inputs [parm_block] "m" (parm_block) : "r0", "r1", "cc"); /* Clobbers - R0, R1, cond code */ #endif // ifndef ZDNN_CONFIG_NO_NNPA #endif // defined(__MVS__) #ifndef __MVS__ register uint64_t r0 __asm__("%r0") = function_code; register uint64_t r1 __asm__("%r1") = (uint64_t)parm_block; __asm__ __volatile__ ( #ifndef ZDNN_CONFIG_NO_NNPA // If NNPA build, do NNPA with hardcoded opcode "1: .long 0xb93b0000" "\n\t" // NNPA " jo 1b" "\n\t" // on CC=3, jump to label '1' " ipm %[cc]" "\n\t" // fetch cc to cc reg " srl %[cc],28" "\n\t" // shift #else "1: lghi %[r0],0" "\n\t" // clear reg 0 " lghi %[cc],0" "\n\t" // this clears 'cc' #endif //! defined(ZDNN_CONFIG_NO_NNPA) : [r0] "+d" (r0), [cc] "+d" (cc) // ASM outputs : "d" (r1) // ASM inputs : "memory", "cc"); // ASM clobbers rtn.r0 = r0; #endif // !defined(__MVS__) // clang-format on BEGIN_BLOCK_IF_LOGLEVEL_DEBUG { printf("invoke_nnpa CC %u:\n", cc); printf(" nnpa_return:\n"); print_hex(8, &rtn.r0); printf("\n"); } if (exception_flags) *exception_flags = rtn.fields.ef; if (cc == 0) { return ZDNN_STATUS_OK; } else { return ZDNN_STATUS_NO_MSG(ZDNN_HW_ERROR + rtn.fields.rc); } } /// Invoke the NNPA routine to drive a query request to the AIU /// /// \param[in] parm_block pointer to a nnpa_parameter_block /// /// \return ZDNN_OK /// ZDNN_UNAVAILABLE_FUNCTION /// ZDNN_MISALIGNED_PARMBLOCK /// /// \note invoke_nnpa could normally also send a condition code which would /// lead to a ZDNN_HW_ERROR however documentation states that only CC 0 is /// possible on NNPA_QAF. /// zdnn_status invoke_nnpa_query(nnpa_qaf_parameter_block *qpb) { #ifndef ZDNN_CONFIG_NO_NNPA #if defined(__MVS__) /*********************************************************************** * On z/OS, use system copy of STFLE output ("faclnnpaf"). (LoZ has to * worry about dynamic changes to STFLE. z/OS does not support that so * using the static system copy is fine.) ***********************************************************************/ struct psa *psaptr = (struct psa *)0; // set _cvt to x10, the pointer to the CVT on z/OS // cppcheck-suppress nullPointer struct cvtmap *cvtptr = (struct cvtmap *)psaptr->flccvt; struct ecvt *ecvtptr = (struct ecvt *)cvtptr->cvtecvt; struct facl *faclptr = (struct facl *)ecvtptr->ecvtfacl; if (faclptr->faclnnpaf) { return invoke_nnpa(NNPA_QAF, (char *)qpb, NULL); } else { return ZDNN_STATUS(ZDNN_UNAVAILABLE_FUNCTION, "NNPA_QAF unavailable", NO_ARG); } #else /*********************************************************************** * On Linux, invoke the function that uses STFLE to interrogate the * hardware. ***********************************************************************/ if (zdnn_is_nnpa_installed() == true) { return invoke_nnpa(NNPA_QAF, (char *)qpb, NULL); } else { return ZDNN_STATUS(ZDNN_UNAVAILABLE_FUNCTION, "NNPA_QAF unavailable", NO_ARG); } #endif #else { // Non-NNPA build: invoke NNPA and it will return scaffolded data return invoke_nnpa(NNPA_QAF, (char *)qpb, NULL); } #endif } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/zdnn.h������������������������������������������������������������������������������0000664�0000000�0000000�00000053471�14364043643�0014436�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ZDNN_ZDNN_H_ #define ZDNN_ZDNN_H_ #include <inttypes.h> #include <stdbool.h> #include <stddef.h> #include <stdint.h> // ----------------------------------------------------------------------------- // NOTE: // Ensure that symbols in zdnn.h and zdnn.map are in sync! // Please also have a look at zdnn.map how to add, update or remove a symbol. // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Initializer and global variables // ----------------------------------------------------------------------------- void zdnn_init(); // ----------------------------------------------------------------------------- // zDNN Status // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // NOTE: // Update status.c and zdnn_private.h after any status modification! // ----------------------------------------------------------------------------- // Status categories #define ZDNN_WARNING 0x00020000 #define ZDNN_PARAMETER_ERROR 0x00040000 #define ZDNN_DATA_ERROR 0x00100000 #define ZDNN_HW_ERROR 0x000c0000 // clang-format off typedef enum zdnn_status { // ---------------------------------------------------------------- ZDNN_OK = 0x00000000, // Success. // ---------------------------------------------------------------- ZDNN_ELEMENT_RANGE_VIOLATION = ZDNN_WARNING + 0x0001, // AIU operation resulted in data that was out of the normal range. // ---------------------------------------------------------------- ZDNN_INVALID_SHAPE = ZDNN_PARAMETER_ERROR + 0x0001, // Invalid shape information in one (or more) of the input/output tensor(s). ZDNN_INVALID_LAYOUT, // Invalid layout information in one (or more) of the input/output tensor(s). ZDNN_INVALID_TYPE, // Invalid type information in one (or more) of the input/output tensor(s). ZDNN_INVALID_FORMAT, // Invalid format information in one (or more) of the input/output tensor(s). ZDNN_INVALID_DIRECTION, // Invalid RNN direction. ZDNN_INVALID_CONCAT_INFO, // Invalid concatenation info. ZDNN_INVALID_STRIDE_PADDING, // Invalid padding type parameter for current strides ZDNN_INVALID_STRIDES, // Invalid stride height or width parameter. ZDNN_MISALIGNED_PARMBLOCK, // NNPA parameter block is not on double word boundary. ZDNN_INVALID_CLIPPING_VALUE, // Invalid clipping for the specified operation. // ---------------------------------------------------------------- ZDNN_ALLOCATION_FAILURE = ZDNN_DATA_ERROR + 0x0001, // Can not allocate storage. ZDNN_INVALID_BUFFER, // Buffer address is NULL or not on 4K-byte boundary, or insufficient buffer size. ZDNN_CONVERT_FAILURE, // Floating point data conversion failure. ZDNN_INVALID_STATE, // Invalid zTensor state. ZDNN_UNSUPPORTED_AIU_EXCEPTION, // AIU operation returned an unexpected exception. // ---------------------------------------------------------------- ZDNN_UNSUPPORTED_PARMBLOCK = ZDNN_HW_ERROR + 0x0001, // NNPA parameter block format is not supported by the model. ZDNN_UNAVAILABLE_FUNCTION, // Specified NNPA function is not defined or installed on the machine. ZDNN_UNSUPPORTED_FORMAT = ZDNN_HW_ERROR + 0x0010, // Specified tensor data layout format is not supported. ZDNN_UNSUPPORTED_TYPE, // Specified tensor data type is not supported. ZDNN_EXCEEDS_MDIS, // Tensor dimension exceeds maximum dimension index size (MDIS). ZDNN_EXCEEDS_MTS, // Total number of elements in tensor exceeds maximum tensor size. (MTS). ZDNN_MISALIGNED_TENSOR, // Tensor address is not on 4K-byte boundary. ZDNN_MISALIGNED_SAVEAREA, // Function specific save area address is not on 4K-byte boundary. // ---------------------------------------------------------------- // Function specific response code (F00x) ZDNN_FUNC_RC_F000 = ZDNN_HW_ERROR + 0xF000, // Function specific response code (F000). ZDNN_FUNC_RC_F001, // Function specific response code (F001). ZDNN_FUNC_RC_F002, // Function specific response code (F002). ZDNN_FUNC_RC_F003, // Function specific response code (F003). ZDNN_FUNC_RC_F004, // Function specific response code (F004). ZDNN_FUNC_RC_F005, // Function specific response code (F005). ZDNN_FUNC_RC_F006, // Function specific response code (F006). ZDNN_FUNC_RC_F007, // Function specific response code (F007). ZDNN_FUNC_RC_F008, // Function specific response code (F008). ZDNN_FUNC_RC_F009, // Function specific response code (F009). // ---------------------------------------------------------------- } zdnn_status; // clang-format on // ----------------------------------------------------------------------------- // NNPA hardware defined values as described in // z/Architecture - Principles of Operation // ----------------------------------------------------------------------------- typedef enum nnpa_function_code { NNPA_QAF = 0, NNPA_ADD = 16, NNPA_SUB = 17, NNPA_MUL = 18, NNPA_DIV = 19, NNPA_MIN = 20, NNPA_MAX = 21, NNPA_LOG = 32, NNPA_EXP = 33, // reserved = 48 NNPA_RELU = 49, NNPA_TANH = 50, NNPA_SIGMOID = 51, NNPA_SOFTMAX = 52, NNPA_BATCHNORMALIZATION = 64, NNPA_MAXPOOL2D = 80, NNPA_AVGPOOL2D = 81, NNPA_LSTMACT = 96, NNPA_GRUACT = 97, NNPA_CONVOLUTION = 112, NNPA_MATMUL_OP = 113, NNPA_MATMUL_OP_BCAST23 = 114 } nnpa_function_code; typedef enum nnpa_parmblk_format { NNPA_PARMBLKFORMAT_0 = 0, } nnpa_parmblk_format; typedef enum nnpa_data_type { NNPA_DATATYPE_1 = 0 } nnpa_data_type; typedef enum nnpa_layout_format { NNPA_LAYOUTFMT_4DFEATURE = 0, NNPA_LAYOUTFMT_4DKERNEL = 1 } nnpa_layout_format; typedef enum nnpa_bfp_format { // 0 is reversed NNPA_BFPFMT_TINY = 1, NNPA_BFPFMT_SHORT = 2, } nnpa_bfp_format; // NNPA_SOFTMAX work area sizes required by the NNPA hardware #define ZDNN_SOFTMAX_SAVEAREA_SIZE 8 * 1024 // NNPA Hardware defined values for Function Specific Parameters typedef enum nnpa_matmul_operations { NNPA_MATMUL_OP_ADDITION = 0, NNPA_MATMUL_OP_COMP_HIGH = 1, NNPA_MATMUL_OP_COMP_NOT_LOW = 2, NNPA_MATMUL_OP_COMP_EQUAL = 3, NNPA_MATMUL_OP_COMP_NOT_EQUAL = 4, NNPA_MATMUL_OP_COMP_NOT_HIGH = 5, NNPA_MATMUL_OP_COMP_LOW = 6, } nnpa_matmul_operations; typedef enum nnpa_matmul_bcast_operations { NNPA_MATMUL_BCAST_OP_ADDITION = 0 } nnpa_matmul_bcast_operations; typedef enum nnpa_softmax_act { NNPA_SOFTMAX_NONE = 0, NNPA_SOFTMAX_LOG = 1 } nnpa_softmax_act; // ----------------------------------------------------------------------------- // zdnn_query_*() bit-field enums // ----------------------------------------------------------------------------- // pos is counting from left to right #define MSB_BITMASK(field_size, pos) 1u << ((field_size - 1) - pos) typedef enum zdnn_query_datatypes { QUERY_DATATYPE_INTERNAL1 = MSB_BITMASK(16, NNPA_DATATYPE_1) } zdnn_query_datatypes; typedef enum zdnn_query_layoutfmts { QUERY_LAYOUTFMT_4DFEATURE = MSB_BITMASK(32, NNPA_LAYOUTFMT_4DFEATURE), QUERY_LAYOUTFMT_4DKERNEL = MSB_BITMASK(32, NNPA_LAYOUTFMT_4DKERNEL) } zdnn_query_layoutfmts; typedef enum zdnn_query_bfpfmts { QUERY_BFPFMT_TINY = MSB_BITMASK(16, NNPA_BFPFMT_TINY), QUERY_BFPFMT_SHORT = MSB_BITMASK(16, NNPA_BFPFMT_SHORT) } zdnn_query_bfpfmts; // ----------------------------------------------------------------------------- // ZDNN enums // ----------------------------------------------------------------------------- typedef enum zdnn_data_types { ZDNN_DLFLOAT16 = NNPA_DATATYPE_1, // 16-bit deep learning format BFLOAT = 253, // Brain floating point format FP16 = 254, // 16-bit IEEE-754 floating point format FP32 = 255, // 32-bit IEEE-754 floating point format } zdnn_data_types; typedef enum zdnn_data_layouts { ZDNN_1D, // 1d tensor ZDNN_2D, // 2d tensor ZDNN_2DS, // represents special 2D tensors required by LSTM/GRU ZDNN_3D, // 3d tensor ZDNN_3DS, // represents special 3D tensors required by // LSTM/GRU/Softmax/Matmul ZDNN_ZRH, // represents (update, reset, hidden) used by GRU ZDNN_4D, // 4d tensor ZDNN_4DS, // represents special 4D tensors required by LSTM/GRU output ZDNN_NHWC, // 4d feature tensor in NHWC ZDNN_NCHW, // 4d feature tensor in NCHW ZDNN_FICO, // represents (forget, input, cell, output) used by LSTM ZDNN_HWCK, // 4d kernel CNN tensor ZDNN_BIDIR_ZRH, // ZRH variant to work with bidirectional LSTM/GRU output ZDNN_BIDIR_FICO // FICO variant to work with bidirectional LSTM/GRU output } zdnn_data_layouts; typedef enum zdnn_data_formats { ZDNN_FORMAT_4DFEATURE = NNPA_LAYOUTFMT_4DFEATURE, // tensor in AIU data layout format 0 ZDNN_FORMAT_4DKERNEL = NNPA_LAYOUTFMT_4DKERNEL, // tensor in AIU data layout format 1 } zdnn_data_formats; // Supported padding types for use in pooling functions typedef enum zdnn_pool_padding { VALID_PADDING = 0, SAME_PADDING = 1 } zdnn_pool_padding; // Support operations for use in matmul functions typedef enum zdnn_matmul_ops { MATMUL_OP_ADDITION = NNPA_MATMUL_OP_ADDITION, MATMUL_OP_GREATER = NNPA_MATMUL_OP_COMP_HIGH, MATMUL_OP_GREATER_EQUAL = NNPA_MATMUL_OP_COMP_NOT_LOW, MATMUL_OP_EQUAL = NNPA_MATMUL_OP_COMP_EQUAL, MATMUL_OP_NOT_EQUAL = NNPA_MATMUL_OP_COMP_NOT_EQUAL, MATMUL_OP_LESSER_EQUAL = NNPA_MATMUL_OP_COMP_NOT_HIGH, MATMUL_OP_LESSER = NNPA_MATMUL_OP_COMP_LOW } zdnn_matmul_ops; // Support operations for use in matmul function typedef enum zdnn_matmul_bcast_ops { MATMUL_BCAST_OP_ADDITION = NNPA_MATMUL_BCAST_OP_ADDITION } zdnn_matmul_bcast_ops; typedef enum zdnn_softmax_act { SOFTMAX_ACT_NONE = NNPA_SOFTMAX_NONE, SOFTMAX_ACT_LOG = NNPA_SOFTMAX_LOG } zdnn_softmax_act; typedef enum zdnn_conv2d_act { CONV2D_ACT_NONE, CONV2D_ACT_RELU } zdnn_conv2d_act; // ----------------------------------------------------------------------------- // Structs // ---------------------------------------------------------------------------- // describes general pre-transformed or transformed information (e.g. shape) of // a tensor typedef struct zdnn_tensor_desc { zdnn_data_layouts layout; // data layout zdnn_data_formats format; // internal use only zdnn_data_types type; // data type uint32_t dim4; // number of elements in outermost dimension uint32_t dim3; // ... outer dimension uint32_t dim2; // ... inner dimension uint32_t dim1; // number of elements in innermost dimension } zdnn_tensor_desc; // struct for describing a ztensor typedef struct zdnn_ztensor { zdnn_tensor_desc *pre_transformed_desc; // tensor's shape information before transformation zdnn_tensor_desc *transformed_desc; // transformed tensor's shape information uint64_t buffer_size; // tensor size in bytes void *buffer; // pointer to the tensor in memory bool is_transformed; // indicator if data in buffer has been transformed char reserved[31]; // not currently used, should contain zeros. } zdnn_ztensor; #define ZDNN_VERSION "1.0.1" #define ZDNN_VERNUM 0x010001 // 0x[major][minor][patch] #define ZDNN_VER_MAJOR 1 #define ZDNN_VER_MINOR 0 #define ZDNN_VER_PATCH 1 // ----------------------------------------------------------------------------- // External Tensor Functions // ----------------------------------------------------------------------------- // Concatenation information is encoded into a 32-bit word: // [RNN_TYPE: 8][PREV_LAYER_TYPE: 8][USAGE: 8][8] typedef uint32_t zdnn_concat_info; #define BITSHIFT_RNN_TYPE 24 #define BITSHIFT_PREV_LAYER 16 #define BITSHIFT_USAGE 8 #define RNN_TYPE_LSTM (0 << BITSHIFT_RNN_TYPE) #define RNN_TYPE_GRU (1 << BITSHIFT_RNN_TYPE) #define PREV_LAYER_UNI (0 << BITSHIFT_PREV_LAYER) #define PREV_LAYER_NONE PREV_LAYER_UNI #define PREV_LAYER_BIDIR (1 << BITSHIFT_PREV_LAYER) #define USAGE_WEIGHTS (0 << BITSHIFT_USAGE) #define USAGE_HIDDEN_WEIGHTS (1 << BITSHIFT_USAGE) #define USAGE_BIASES (2 << BITSHIFT_USAGE) #define USAGE_HIDDEN_BIASES (3 << BITSHIFT_USAGE) #define CONCAT_RNN_TYPE(info) (info & (0xFFu << BITSHIFT_RNN_TYPE)) #define CONCAT_PREV_LAYER(info) (info & (0xFFu << BITSHIFT_PREV_LAYER)) #define CONCAT_USAGE(info) (info & (0xFFu << BITSHIFT_USAGE)) void zdnn_init_pre_transformed_desc(zdnn_data_layouts layout, zdnn_data_types type, zdnn_tensor_desc *pre_tfrmd_desc, ...); zdnn_status zdnn_generate_transformed_desc(const zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc); zdnn_status zdnn_generate_transformed_desc_concatenated( const zdnn_tensor_desc *pre_tfrmd_desc, zdnn_concat_info info, zdnn_tensor_desc *tfrmd_desc); zdnn_status zdnn_allochelper_ztensor(zdnn_ztensor *ztensor); zdnn_status zdnn_free_ztensor_buffer(const zdnn_ztensor *ztensor); void zdnn_init_ztensor(zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc, zdnn_ztensor *output); zdnn_status zdnn_init_ztensor_with_malloc(zdnn_tensor_desc *pre_tfrmd_desc, zdnn_tensor_desc *tfrmd_desc, zdnn_ztensor *output); void zdnn_reset_ztensor(zdnn_ztensor *ztensor); uint64_t zdnn_getsize_ztensor(const zdnn_tensor_desc *tfrmd_desc); // ----------------------------------------------------------------------------- // External Query Functions // ----------------------------------------------------------------------------- bool zdnn_is_nnpa_installed(); bool zdnn_is_nnpa_function_installed(int count, ...); bool zdnn_is_nnpa_parmblk_fmt_installed(int count, ...); bool zdnn_is_nnpa_datatype_installed(uint16_t types_bitmask); bool zdnn_is_nnpa_layout_fmt_installed(uint32_t layout_bitmask); bool zdnn_is_nnpa_conversion_installed(nnpa_data_type type, uint16_t format_bitmask); uint32_t zdnn_get_nnpa_max_dim_idx_size(); uint64_t zdnn_get_nnpa_max_tensor_size(); zdnn_status zdnn_refresh_nnpa_query_result(); // ----------------------------------------------------------------------------- // Versioning Functions // ----------------------------------------------------------------------------- bool zdnn_is_version_runnable(uint32_t ver_num); uint32_t zdnn_get_max_runnable_version(); // ----------------------------------------------------------------------------- // External Elementwise Operations // ----------------------------------------------------------------------------- zdnn_status zdnn_add(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); zdnn_status zdnn_sub(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); zdnn_status zdnn_mul(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); zdnn_status zdnn_div(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); zdnn_status zdnn_min(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); zdnn_status zdnn_max(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, zdnn_ztensor *output); zdnn_status zdnn_log(const zdnn_ztensor *input, zdnn_ztensor *output); zdnn_status zdnn_exp(const zdnn_ztensor *input, zdnn_ztensor *output); // ----------------------------------------------------------------------------- // External Activation Operations // ----------------------------------------------------------------------------- zdnn_status zdnn_relu(const zdnn_ztensor *input, const void *clipping_value, zdnn_ztensor *output); zdnn_status zdnn_tanh(const zdnn_ztensor *input, zdnn_ztensor *output); zdnn_status zdnn_sigmoid(const zdnn_ztensor *input, zdnn_ztensor *output); zdnn_status zdnn_softmax(const zdnn_ztensor *input, void *save_area, zdnn_softmax_act act_func, zdnn_ztensor *output); // ----------------------------------------------------------------------------- // Recurrent Neural Network (RNN) Operations // ----------------------------------------------------------------------------- typedef enum lstm_gru_direction { FWD, BWD, BIDIR } lstm_gru_direction; zdnn_status zdnn_lstm(const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *c0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, void *work_area, zdnn_ztensor *hn_output, zdnn_ztensor *cf_output); zdnn_status zdnn_gru(const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, void *work_area, zdnn_ztensor *hn_output); // ----------------------------------------------------------------------------- // Matrix Multiplication Operations // ----------------------------------------------------------------------------- zdnn_status zdnn_matmul_op(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, zdnn_matmul_ops op_type, zdnn_ztensor *output); zdnn_status zdnn_matmul_bcast_op(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, zdnn_matmul_bcast_ops op_type, zdnn_ztensor *output); // ----------------------------------------------------------------------------- // External Norm Operations // ----------------------------------------------------------------------------- zdnn_status zdnn_batchnorm(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, zdnn_ztensor *output); zdnn_status zdnn_meanreduce2d(const zdnn_ztensor *input, zdnn_ztensor *output); // ----------------------------------------------------------------------------- // External Pool Operations // ----------------------------------------------------------------------------- zdnn_status zdnn_avgpool2d(const zdnn_ztensor *input, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, zdnn_ztensor *output); zdnn_status zdnn_maxpool2d(const zdnn_ztensor *input, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, zdnn_ztensor *output); // ----------------------------------------------------------------------------- // External Convolution Operations // ----------------------------------------------------------------------------- zdnn_status zdnn_conv2d(const zdnn_ztensor *input, const zdnn_ztensor *kernel, const zdnn_ztensor *bias, zdnn_pool_padding padding_type, uint32_t stride_height, uint32_t stride_width, zdnn_conv2d_act act_func, const void *clipping_value, zdnn_ztensor *output); // ----------------------------------------------------------------------------- // External Tensor Transform Operations // ----------------------------------------------------------------------------- zdnn_status zdnn_transform_ztensor(zdnn_ztensor *ztensor, ...); zdnn_status zdnn_transform_origtensor(const zdnn_ztensor *ztensor, void *out_buf); zdnn_status zdnn_reshape_ztensor(const zdnn_ztensor *src, zdnn_ztensor *dest); // ----------------------------------------------------------------------------- // External Version Related Functions // ----------------------------------------------------------------------------- char *zdnn_get_library_version_str(); uint32_t zdnn_get_library_version(); // ----------------------------------------------------------------------------- // zDNN Status Related Functions // ----------------------------------------------------------------------------- const char *zdnn_get_status_message(zdnn_status status); #endif /* ZDNN_ZDNN_H_ */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/zdnn.map����������������������������������������������������������������������������0000664�0000000�0000000�00000010720�14364043643�0014752�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This VERSION script controls which symbols in the shared library are exported. # NOTE: Ensure that symbols in zdnn.h and zdnn.map are in sync! # (see https://sourceware.org/binutils/docs/ld/VERSION.html) # All global symbols of the library are exported and can be accessed by other # programs or libraries. All symbols not mentioned in this VERSION script are # considered internal and are not accessible by other programs or libraries. # This is done with help of the wildcard in the local rule. # Each version node contains the symbols which were introduced in this # particular version. # Task: Introduce a new symbol in a new library version. # Add the new function to zdnn.h and provide an implementation. Afterwards, add # a new version node above "older" version node: # ZDNN_NEW.VERSION { # global: # zdnn_NEW_FUNCTION; # }; # # Note: # As long as a version is under development, you can add new symbols # without an extra version node. # Task: Provide a second symbol after making an incompatible change of a symbol. # Add a new version node above "older" version node, e.g.: # ZDNN_NEW.VERSION { # global: # zdnn_refresh_nnpa_query_result; # }; # # Change the implementation and provide an old version, e.g.: # zdnn_status zdnn_refresh_nnpa_query_result() { # puts ("zdnn_refresh_nnpa_query_result(): NEW.VERSION"); # return ZDNN_STATUS_OK; # } # #ifdef LIBSONAME # zdnn_status zdnn_refresh_nnpa_query_result_old() { # puts ("zdnn_refresh_nnpa_query_result(): OLD.VERSION"); # return ZDNN_STATUS_OK; # } # __asm__ (".symver zdnn_refresh_nnpa_query_result_old,zdnn_refresh_nnpa_query_result@ZDNN_OLD.VERSION"); # #endif # # => Now existing programs will use the "OLD.VERSION" of # zdnn_refresh_nnpa_query_result. Programs linked against the new library # will use the "NEW.VERSION". # # Note: # As long as a version is under development and the symbol was introduced in # this version, you can adjust the symbol without providing an old version of # the symbol. # Task: Remove a symbol and only provide an old version for usage by existing programs. # Remove the symbol in zdnn.h, keep the implementation and use it as old version # by specifying the version node where this symbol was introduced with, e.g.: # #ifdef LIBSONAME # zdnn_status zdnn_refresh_nnpa_query_result_old() { # puts ("zdnn_refresh_nnpa_query_result(): OLD.VERSION"); # return ZDNN_STATUS_OK; # } # __asm__ (".symver zdnn_refresh_nnpa_query_result_old,zdnn_refresh_nnpa_query_result@ZDNN_INTRODUCED.VERSION"); # #endif # # zdnn.map is listing symbols introduced in a specific ZDNN_INTRODUCED.VERSION # version node. Thus removed symbols needs to stay in those version nodes. # For a better overview, add a comment like: # # Removed zdnn_refresh_nnpa_query_result with version ZDNN_X.Y # # => Now existing programs will still be able to use the "OLD.VERSION" of # zdnn_refresh_nnpa_query_result. Programs linked against the new library # are not able to call the "OLD.VERSION". Instead ld will fail due to # undefined reference to ... . # # Note: # As long as a version is under development and the symbol was introduced in # this version, you can just remove the symbol without providing an old version # of the symbol. Just remove it in the current version node. ZDNN_1.0 { global: zdnn_init; zdnn_init_pre_transformed_desc; zdnn_generate_transformed_desc; zdnn_generate_transformed_desc_concatenated; zdnn_allochelper_ztensor; zdnn_free_ztensor_buffer; zdnn_init_ztensor; zdnn_init_ztensor_with_malloc; zdnn_reset_ztensor; zdnn_getsize_ztensor; zdnn_is_nnpa_installed; zdnn_is_nnpa_function_installed; zdnn_is_nnpa_parmblk_fmt_installed; zdnn_is_nnpa_datatype_installed; zdnn_is_nnpa_layout_fmt_installed; zdnn_is_nnpa_conversion_installed; zdnn_is_version_runnable; zdnn_get_max_runnable_version; zdnn_get_nnpa_max_dim_idx_size; zdnn_get_nnpa_max_tensor_size; zdnn_get_library_version_str; zdnn_get_library_version; zdnn_refresh_nnpa_query_result; zdnn_add; zdnn_sub; zdnn_mul; zdnn_div; zdnn_min; zdnn_max; zdnn_log; zdnn_exp; zdnn_relu; zdnn_tanh; zdnn_sigmoid; zdnn_softmax; zdnn_lstm; zdnn_gru; zdnn_matmul_op; zdnn_matmul_bcast_op; zdnn_batchnorm; zdnn_meanreduce2d; zdnn_avgpool2d; zdnn_maxpool2d; zdnn_conv2d; zdnn_transform_ztensor; zdnn_transform_origtensor; zdnn_reshape_ztensor; zdnn_get_status_message; local: *; }; ������������������������������������������������zDNN-1.0.1/zdnn/zdnn_init.c�������������������������������������������������������������������������0000664�0000000�0000000�00000012526�14364043643�0015450�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #if defined(__MVS__) #include <cvt.h> #include <ihaecvt.h> #include <ihafacl.h> #include <ihapsa.h> #endif #include "zdnn.h" #include "zdnn_private.h" #ifdef __MVS__ #pragma export(zdnn_init) #pragma export(zdnn_is_nnpa_installed) #endif // global variables, set by zdnn_init() via environment vars log_levels log_level = LOGLEVEL_ERROR; // log level (see enum log_levels) bool precheck_enabled = false; // enables tensor pre-check before invoking NNPA uint32_t status_diag = STATUS_DIAG_NOT_SET; // diagnostic info when status = X char log_module[LOGMODULE_SIZE] = "\0"; // Index of the facility bit for the NNPA facility #define STFLE_NNPA 165 /// Initialize the zDNN library and issue NNPA-QAF to the hardware. Needs to be /// invoked at least once during the lifetime of the application, either /// manually or automatically via DLL-load initializer class. /// /// \return None /// void zdnn_init() { char *ptr, *endptr; if ((ptr = getenv(ENVVAR_LOGLEVEL))) { if (!strcasecmp("off", ptr)) { log_level = LOGLEVEL_OFF; } if (!strcasecmp("fatal", ptr)) { log_level = LOGLEVEL_FATAL; } if (!strcasecmp("error", ptr)) { log_level = LOGLEVEL_ERROR; } if (!strcasecmp("warn", ptr)) { log_level = LOGLEVEL_WARN; } if (!strcasecmp("info", ptr)) { log_level = LOGLEVEL_INFO; } if (!strcasecmp("debug", ptr)) { log_level = LOGLEVEL_DEBUG; } if (!strcasecmp("trace", ptr)) { log_level = LOGLEVEL_TRACE; } } if ((ptr = getenv(ENVVAR_ENABLE_PRECHECK))) { precheck_enabled = !strcasecmp("true", ptr); } if ((ptr = getenv(ENVVAR_STATUS_DIAG))) { uint32_t val; // if it's prefixed with "0x"/"0X" then treat it as hex string if (strstr(ptr, "0x") == ptr || strstr(ptr, "0X") == ptr) { val = (uint32_t)strtol((ptr + 2), &endptr, 16); } else { val = (uint32_t)strtol(ptr, &endptr, 10); } if (endptr == ptr + strlen(ptr)) { status_diag = val; } } if ((ptr = getenv(ENVVAR_LOGMODULE))) { strncpy(log_module, ptr, LOGMODULE_SIZE - 1); } /* Exit silently if there is no NNPA facility installed. Explicit invocations of functions requiring NNPA will result in an error. */ #ifndef ZDNN_CONFIG_NO_NNPA if (zdnn_is_nnpa_installed() == false) return; #endif zdnn_refresh_nnpa_query_result(); } #ifndef __MVS__ #define STFLE_LENGTH 32 static int invoke_stfle(unsigned char *facility_list) { register uint64_t r0 __asm__("%r0") = STFLE_LENGTH / 8 - 1; int cc; struct facility_list_type { // cppcheck-suppress unusedStructMember unsigned char flist[STFLE_LENGTH]; }; if (precheck_enabled) { // ensure facility_list is on a doubleword boundary. if ((uintptr_t)facility_list & 7) return ZDNN_STATUS_NO_MSG(ZDNN_MISALIGNED_PARMBLOCK); } // clang-format off __asm__ __volatile__("stfle %[flist]" "\n\t" "ipm %[cc]" "\n\t" "srl %[cc],28" "\n\t" : [flist] "+Q"(*((struct facility_list_type*)facility_list)), "+d"(r0), [cc] "=d"(cc) : : "memory", "cc"); // clang-format on return cc; } static inline int check_bitfield(uint8_t *bitfield, int bitno) { uint8_t mask = (1 << 7) >> (bitno & 7); return !!(bitfield[bitno / 8] & mask); } #endif /// Determine if NNPA hardware support is available /// /// The function unconditionally uses the STFLE instruction available /// since IBM z9-109. /// /// \param[in] None /// /// \return true /// false /// bool zdnn_is_nnpa_installed() { #ifndef __MVS__ int nnpa_supported; unsigned char facilities[STFLE_LENGTH] = {0}; int cc; cc = invoke_stfle(facilities); if (cc) { LOG_ERROR("STFLE failed with %d", cc); return false; } nnpa_supported = check_bitfield(facilities, STFLE_NNPA); LOG_INFO("Hardware NNPA support available - %s", nnpa_supported ? "TRUE" : "FALSE"); return nnpa_supported; #else /*********************************************************************** * On z/OS, use system copy of STFLE output ("faclnnpaf"). (LoZ has to * worry about dynamic changes to STFLE. z/OS does not support that so * using the static system copy is fine.) ***********************************************************************/ struct psa *psaptr = (struct psa *)0; // cppcheck-suppress nullPointer struct cvtmap *cvtptr = (struct cvtmap *)psaptr->flccvt; struct ecvt *ecvtptr = (struct ecvt *)cvtptr->cvtecvt; struct facl *faclptr = (struct facl *)ecvtptr->ecvtfacl; return faclptr->faclnnpaf; #endif } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������zDNN-1.0.1/zdnn/zdnn_private.h����������������������������������������������������������������������0000664�0000000�0000000�00000070044�14364043643�0016163�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// SPDX-License-Identifier: Apache-2.0 /* * Copyright IBM Corp. 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ZDNN_ZDNN_PRIVATE_H_ #define ZDNN_ZDNN_PRIVATE_H_ #include <stdarg.h> #include <stdio.h> // ----------------------------------------------------------------------------- // convert_hw.c includes // ----------------------------------------------------------------------------- #if defined(__MVS__) // If z/OS, use XL C include and typedef #include <builtins.h> // needed for XL C vector ops #else // If LoZ, use gcc include and typedef #include <s390intrin.h> // needed for LoZ vector ops #endif #include "../config.h" #define AIU_BYTES_PER_STICK 128 #define AIU_2BYTE_CELLS_PER_STICK 64 #define AIU_2BYTE_CELL_SIZE 2 #define AIU_STICKS_PER_PAGE 32 #define AIU_PAGESIZE_IN_BYTES 4096 #define ZDNN_MAX_DIMS 4 // number of dims in AIU's Tensor Descriptor typedef enum log_levels { LOGLEVEL_OFF, LOGLEVEL_FATAL, LOGLEVEL_ERROR, LOGLEVEL_WARN, LOGLEVEL_INFO, LOGLEVEL_DEBUG, LOGLEVEL_TRACE, } log_levels; typedef enum elements_mode { ELEMENTS_AIU, ELEMENTS_PRE, ELEMENTS_PRE_SINGLE_GATE = ELEMENTS_PRE, ELEMENTS_PRE_ALL_GATES } elements_mode; #define LOGMODULE_SIZE 1024 extern log_levels log_level; extern bool precheck_enabled; extern uint32_t status_diag; extern char log_module[LOGMODULE_SIZE]; #define ENVVAR_LOGLEVEL "ZDNN_LOGLEVEL" #define ENVVAR_ENABLE_PRECHECK "ZDNN_ENABLE_PRECHECK" #define ENVVAR_STATUS_DIAG "ZDNN_STATUS_DIAG" #define ENVVAR_LOGMODULE "ZDNN_LOGMODULE" #define STATUS_DIAG_NOT_SET -1 #define DCL_EXTERN_STATUS_STR(a) extern const char *STATUS_STR_##a; DCL_EXTERN_STATUS_STR(ZDNN_OK) DCL_EXTERN_STATUS_STR(ZDNN_ELEMENT_RANGE_VIOLATION) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_SHAPE) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_LAYOUT) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_TYPE) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_FORMAT) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_DIRECTION) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_CONCAT_INFO) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_STRIDE_PADDING) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_STRIDES) DCL_EXTERN_STATUS_STR(ZDNN_MISALIGNED_PARMBLOCK) DCL_EXTERN_STATUS_STR(ZDNN_ALLOCATION_FAILURE) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_BUFFER) DCL_EXTERN_STATUS_STR(ZDNN_CONVERT_FAILURE) DCL_EXTERN_STATUS_STR(ZDNN_INVALID_STATE) DCL_EXTERN_STATUS_STR(ZDNN_UNSUPPORTED_AIU_EXCEPTION) DCL_EXTERN_STATUS_STR(ZDNN_UNSUPPORTED_PARMBLOCK) DCL_EXTERN_STATUS_STR(ZDNN_UNAVAILABLE_FUNCTION) DCL_EXTERN_STATUS_STR(ZDNN_UNSUPPORTED_FORMAT) DCL_EXTERN_STATUS_STR(ZDNN_UNSUPPORTED_TYPE) DCL_EXTERN_STATUS_STR(ZDNN_EXCEEDS_MDIS) DCL_EXTERN_STATUS_STR(ZDNN_EXCEEDS_MTS) DCL_EXTERN_STATUS_STR(ZDNN_MISALIGNED_TENSOR) DCL_EXTERN_STATUS_STR(ZDNN_MISALIGNED_SAVEAREA) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F000) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F001) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F002) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F003) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F004) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F005) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F006) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F007) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F008) DCL_EXTERN_STATUS_STR(ZDNN_FUNC_RC_F009) #undef DCL_EXTERN_STATUS_STR /* * NNPA use of register 0 */ typedef union nnpa_return { uint64_t r0; // for reading from and writing to r0 struct fields { uint16_t rc; // response code, bits [0-15] uint8_t rsvd1; // reserved, bits [16-23] uint8_t ef; // exception flags, bits [24-31] uint8_t rsvd2[3]; // reserved, bits [32-55] uint8_t fc; // function code, bits [56-63] } fields; } nnpa_return; /* * To interface to the zAIU through the NNPA instruction requires the following * parameter blocks */ typedef #ifdef __MVS__ _Packed #endif struct nnpa_tensor_descriptor { uint8_t data_layout_format; uint8_t data_type; uint8_t reserve1[6]; uint32_t dim4_index_size; uint32_t dim3_index_size; uint32_t dim2_index_size; uint32_t dim1_index_size; uint64_t *tensor_data_addr; } #ifndef __MVS__ __attribute__((packed)) #endif nnpa_tensor_descriptor; // BIG ENDIAN 128-bits bits-field, most significant bit is bit 0 typedef #ifdef __MVS__ _Packed #endif struct bit128_t { uint64_t bits_0to63; uint64_t bits_64to127; } #ifndef __MVS__ __attribute__((packed)) #endif bit128_t; // BIG ENDIAN 256-bits bits-field, most significant bit is bit 0 typedef #ifdef __MVS__ _Packed #endif struct bit256_t { uint64_t bits_0to63; uint64_t bits_64to127; uint64_t bits_128to191; uint64_t bits_192to255; } #ifndef __MVS__ __attribute__((packed)) #endif bit256_t; typedef #ifdef __MVS__ _Packed #endif struct nnpa_parameter_block { uint16_t parm_block_version_number; // first 9 bits must be 0 uint8_t model_version_number; // Only set by hardware for continuation. uint8_t reserved_for_ibm[3]; uint16_t reserved1; // 1 bit Continuation Flag at end uint8_t reserved2[48]; uint64_t function_specific_save_area_address; nnpa_tensor_descriptor output_tensor1; nnpa_tensor_descriptor output_tensor2; uint8_t reserved3[64]; nnpa_tensor_descriptor input_tensor1; nnpa_tensor_descriptor input_tensor2; nnpa_tensor_descriptor input_tensor3; uint8_t reserved4[96]; uint32_t function_specific_parm1; uint32_t function_specific_parm2; uint32_t function_specific_parm3; uint32_t function_specific_parm4; uint32_t function_specific_parm5; uint8_t reserved5[108]; uint8_t continuation_state_buffer[3584]; } #ifndef __MVS__ __attribute__((packed, aligned(8))) #endif nnpa_parameter_block #ifdef __MVS__ __attribute__((__aligned__(8))) #endif ; typedef #ifdef __MVS__ _Packed #endif struct nnpa_qaf_parameter_block { bit256_t installed_functions_vector; // bit set of installed operations bit128_t installed_parameter_block_formats; // bit set of installed block formats uint16_t installed_data_types; // bit set of installed data types uint8_t reserved1[2]; uint32_t installed_data_layout_formats; // bit set of supported data layouts uint8_t reserved2[4]; uint32_t maximum_dimension_index_size; // maximum supported number of elements // for any single tensor dimension uint64_t maximum_tensor_size; // maximum supported tensor size (bytes) aka // stick-area size uint16_t installed_dt1_conversions_vector; // bit set of installed Data-Type-1 // conversions uint8_t reserved3[182]; } #ifndef __MVS__ __attribute__((packed, aligned(8))) #endif nnpa_qaf_parameter_block #ifdef __MVS__ __attribute__((__aligned__(8))) #endif ; extern nnpa_qaf_parameter_block nnpa_query_result; // ----------------------------------------------------------------------------- // Versioning // ----------------------------------------------------------------------------- extern uint32_t aiu_lib_vernum; void refresh_aiu_lib_vernum(); // ----------------------------------------------------------------------------- // Floating Point Format Conversion Functions // ----------------------------------------------------------------------------- uint32_t convert_data_format(void *input_data, zdnn_data_types in_data_fmt, void *output_data, zdnn_data_types out_data_fmt, uint32_t num_fields); uint32_t convert_data_format_in_stride(void *input_data, zdnn_data_types in_data_fmt, void *output_data, zdnn_data_types out_data_fmt, uint32_t num_fields, uint32_t input_stride); // ----------------------------------------------------------------------------- // Tensor Functions // ----------------------------------------------------------------------------- void init_transformed_desc(zdnn_data_layouts layout, zdnn_data_types type, zdnn_data_formats format, zdnn_tensor_desc *tfrmd_desc, uint32_t dim4, uint32_t dim3, uint32_t dim2, uint32_t dim1); zdnn_status ztensor_slice_dim4(const zdnn_ztensor *input_ztensor, uint32_t slice_idx, size_t slice_buffer_size, zdnn_tensor_desc *output_pre_tfrmd_desc, zdnn_tensor_desc *output_tfrmd_desc, zdnn_ztensor *output_ztensor); // ----------------------------------------------------------------------------- // NNPA Parm Block Functions // ----------------------------------------------------------------------------- // Define NNPA_PARM_BLOCK_VERSION // Notes: // - The PBVN is not used on a Query NNPA // - The PBVN is architected to be 9-15 of the first word of the // NNPA parm block // - Actual supported values are returned on the aforementioned // Query NNPA in field IPBF #define NNPA_PARM_BLOCK_VERSION 0 void populate_descriptor(nnpa_tensor_descriptor *descriptor, const zdnn_ztensor *ztensor); void populate_nnpa_parm_block( nnpa_parameter_block *parm_block, const zdnn_ztensor *input_ztensor1, const zdnn_ztensor *input_ztensor2, const zdnn_ztensor *input_ztensor3, zdnn_ztensor *output_ztensor1, zdnn_ztensor *output_ztensor2, void *func_sp_savearea_addr, uint32_t func_sp_parm1, uint32_t func_sp_parm2, uint32_t func_sp_parm3, uint32_t func_sp_parm4, uint32_t func_sp_parm5); // ----------------------------------------------------------------------------- // Malloc 4k // ----------------------------------------------------------------------------- void *malloc_aligned_4k(size_t size); void free_aligned_4k(void *aligned_ptr); // ----------------------------------------------------------------------------- // NNPA Invoke Functions // ----------------------------------------------------------------------------- zdnn_status invoke_nnpa(uint8_t function_code, char *parm_block, uint8_t *exception_flags); zdnn_status invoke_nnpa_query(nnpa_qaf_parameter_block *qpb); // ----------------------------------------------------------------------------- // Internal Function for AIU Operations // ----------------------------------------------------------------------------- zdnn_status aiu_ops(uint8_t function_code, const zdnn_ztensor *input1, const zdnn_ztensor *input2, const zdnn_ztensor *input3, zdnn_ztensor *output1, zdnn_ztensor *output2); zdnn_status aiu_ops_func_specific(uint8_t function_code, const zdnn_ztensor *input1, const zdnn_ztensor *input2, const zdnn_ztensor *input3, zdnn_ztensor *output1, zdnn_ztensor *output2, uint64_t func_sp_savearea_addr, uint32_t func_sp_parm1, uint32_t func_sp_parm2, uint32_t func_sp_parm3, uint32_t func_sp_parm4, uint32_t func_sp_parm5); zdnn_status aiu_lstm_gru(uint8_t function_code, const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *c0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, void *work_area, zdnn_ztensor *hn_output, zdnn_ztensor *cf_output); // ----------------------------------------------------------------------------- // Internal Tensor Compatibility Verification // ----------------------------------------------------------------------------- zdnn_status verify_tensors(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, const zdnn_ztensor *output); zdnn_status verify_zdnn_lstm_or_gru_tensors( uint8_t function_code, const zdnn_ztensor *input, const zdnn_ztensor *h0, const zdnn_ztensor *c0, const zdnn_ztensor *weights, const zdnn_ztensor *biases, const zdnn_ztensor *hidden_weights, const zdnn_ztensor *hidden_biases, lstm_gru_direction direction, const zdnn_ztensor *hn_output, const zdnn_ztensor *cf_output); zdnn_status verify_lstm_or_gru_act_tensors(uint8_t function_code, const zdnn_ztensor *ts_fused, const zdnn_ztensor *bias_add_rnn_op, const zdnn_ztensor *prev_state, const zdnn_ztensor *h_output, const zdnn_ztensor *c_output); zdnn_status verify_matmul_op_tensors(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, const zdnn_ztensor *output); zdnn_status verify_matmul_bcast_op_tensors(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, const zdnn_ztensor *output); zdnn_status verify_batchnorm_tensors(const zdnn_ztensor *input_a, const zdnn_ztensor *input_b, const zdnn_ztensor *input_c, const zdnn_ztensor *output); zdnn_status verify_pool_avg_max_tensors( const zdnn_ztensor *input, zdnn_pool_padding padding_type, uint32_t kernel_height, uint32_t kernel_width, uint32_t stride_height, uint32_t stride_width, const zdnn_ztensor *output); zdnn_status verify_conv2d_tensors(const zdnn_ztensor *input, const zdnn_ztensor *kernel, const zdnn_ztensor *bias, uint32_t pad_n_act, uint32_t stride_height, uint32_t stride_width, uint32_t reserved_n_clipping, const zdnn_ztensor *output); zdnn_status verify_relu_tensors(const zdnn_ztensor *input, uint32_t reserved_n_clipping, const zdnn_ztensor *output); zdnn_status verify_pre_transformed_descriptor(const zdnn_tensor_desc *pre_tfrmd_desc); zdnn_status verify_transformed_descriptor(const zdnn_tensor_desc *tfrmd_desc); // ----------------------------------------------------------------------------- // Stickify Related Functions // ----------------------------------------------------------------------------- size_t get_stick_offset(uint32_t e4x, uint32_t e3x, uint32_t e2x, uint32_t e1x, const zdnn_tensor_desc *pre_tfrmd_desc); void setbit_128(bit128_t *field, uint8_t bit_pos); bool is_bitset_128(bit128_t field, uint8_t bit_pos); void setbit_256(bit256_t *field, uint16_t bit_pos); bool is_bitset_256(bit256_t field, uint16_t bit_pos); zdnn_status transform_fico_ztensor(zdnn_ztensor *fico_ztensor, void *fx_data, void *ix_data, void *cx_data, void *ox_data); zdnn_status transform_zrh_ztensor(zdnn_ztensor *zrh_ztensor, void *zx_data, void *rx_data, void *hx_data); // ----------------------------------------------------------------------------- // convert_hw.c wrapper Functions and types // ----------------------------------------------------------------------------- typedef vector unsigned int vec_float32; typedef vector unsigned short vec_int16; typedef vector unsigned char vec_char8; vec_int16 aiu_vec_round_from_fp32(vec_float32 a, vec_float32 b); void aiu_vec_lengthen_to_fp32(vec_int16 a, vec_float32 *out1, vec_float32 *out2); vec_int16 aiu_vec_convert_from_fp16(vec_int16 a); vec_int16 aiu_vec_convert_to_fp16(vec_int16 a); // ----------------------------------------------------------------------------- // NNPA-MATMUL-OP function-specific-parameter-1 bitfields // ----------------------------------------------------------------------------- // bits 0-23: reserved // bits 24-31: operation typedef #ifdef __MVS__ _Packed #endif struct bitfield_func_sp_parm1_matmul_op { uint32_t reserved1 : 24; uint32_t operation : 8; } #ifndef __MVS__ __attribute__((packed)) #endif bitfield_func_sp_parm1_matmul_op; typedef union func_sp_parm1_matmul_op { // for get/setting bitfield individually bitfield_func_sp_parm1_matmul_op bits; // for as a whole. you must clear this before setting bits individual uint32_t val; } func_sp_parm1_matmul_op; // ----------------------------------------------------------------------------- // NNPA-MATMUL-OP-BCAST23 function-specific-parameter-1 bitfields // ----------------------------------------------------------------------------- // bits 0-23: reserved // bits 24-31: operation typedef #ifdef __MVS__ _Packed #endif struct bitfield_func_sp_parm1_matmul_bcast_op { uint32_t reserved1 : 24; uint32_t operation : 8; } #ifndef __MVS__ __attribute__((packed)) #endif bitfield_func_sp_parm1_matmul_bcast_op; typedef union func_sp_parm1_matmul_bcast_op { // for get/setting bitfield individually bitfield_func_sp_parm1_matmul_bcast_op bits; // for as a whole. you must clear this before setting bits individual uint32_t val; } func_sp_parm1_matmul_bcast_op; // ----------------------------------------------------------------------------- // NNPA-SOFTMAX function-specific-parameter-1 bitfields // ----------------------------------------------------------------------------- // bits 0-28: reserved // bits 28-31: activation func typedef #ifdef __MVS__ _Packed #endif struct bitfield_func_sp_parm1_softmax { uint32_t reserved1 : 28; uint32_t act : 4; } #ifndef __MVS__ __attribute__((packed)) #endif bitfield_func_sp_parm1_softmax; typedef union func_sp_parm1_softmax { // for get/setting bitfield individually bitfield_func_sp_parm1_softmax bits; // for as a whole. you must clear this before setting bits individual uint32_t val; } func_sp_parm1_softmax; // ----------------------------------------------------------------------------- // NNPA-RELU function-specific-parameter-1 bitfields // ----------------------------------------------------------------------------- // bits 0-15: reserved // bits 16-31: clipping value typedef #ifdef __MVS__ _Packed #endif struct bitfield_func_sp_parm1_relu { uint32_t reserved1 : 16; uint32_t clipping_value : 16; } #ifndef __MVS__ __attribute__((packed)) #endif bitfield_func_sp_parm1_relu; typedef union func_sp_parm1_relu { // for get/setting bitfield individually bitfield_func_sp_parm1_relu bits; // for as a whole. you must clear this before setting bits individual uint32_t val; } func_sp_parm1_relu; // ----------------------------------------------------------------------------- // NNPA-CONVOLUTION function-specific-parameter-1 bitfields // ----------------------------------------------------------------------------- // bits 0-23: reserved // bits 24-27: activation func // bits 28: reserved // bits 29-31: padding type typedef #ifdef __MVS__ _Packed #endif struct bitfield_func_sp_parm1_conv2d { uint32_t reserved1 : 24; uint32_t act : 4; uint32_t reserved2 : 1; uint32_t pad : 3; } #ifndef __MVS__ __attribute__((packed)) #endif bitfield_func_sp_parm1_conv2d; typedef union func_sp_parm1_conv2d { // for get/setting bitfield individually bitfield_func_sp_parm1_conv2d bits; // for as a whole. you must clear this before setting bits individual uint32_t val; } func_sp_parm1_conv2d; // ----------------------------------------------------------------------------- // NNPA-CONVOLUTION function-specific-parameter-4 bitfields // ----------------------------------------------------------------------------- // bits 0-15: reserved // bits 16-31: clipping value typedef #ifdef __MVS__ _Packed #endif struct bitfield_func_sp_parm4_conv2d { uint32_t reserved1 : 16; uint32_t clipping_value : 16; } #ifndef __MVS__ __attribute__((packed)) #endif bitfield_func_sp_parm4_conv2d; typedef union func_sp_parm4_conv2d { // for get/setting bitfield individually bitfield_func_sp_parm4_conv2d bits; // for as a whole. you must clear this before setting bits individual uint32_t val; } func_sp_parm4_conv2d; // ----------------------------------------------------------------------------- // zDNN Logger Functions // ----------------------------------------------------------------------------- bool logmodule_matches(const char *file_name); void log_fatal(const char *func_name, const char *file_name, int line_no, char *format, ...); void log_error(const char *func_name, const char *file_name, int line_no, char *format, ...); void log_warn(const char *func_name, const char *file_name, int line_no, char *format, ...); void log_info(const char *func_name, const char *file_name, int line_no, char *format, ...); void log_debug(const char *func_name, const char *file_name, int line_no, char *format, ...); void log_trace(const char *func_name, const char *file_name, int line_no, char *format, ...); void log_message(log_levels lvl, const char *func_name, const char *file_name, int line_no, const char *format, va_list arg); #ifndef ZDNN_CONFIG_DEBUG // when ZDNN_CONFIG_DEBUG is off (i.e., production code): // // - no logmodule filtering // - FATAL/ERROR: log the message, no loglevel check // - WARN/INFO/DEBUG/TRACE: no-op #define LOG_FATAL(format, ...) \ log_fatal(__func__, __FILE__, __LINE__, format, __VA_ARGS__) #define LOG_ERROR(format, ...) \ log_error(__func__, __FILE__, __LINE__, format, __VA_ARGS__) #define LOG_WARN(format, ...) #define LOG_INFO(format, ...) #define LOG_DEBUG(format, ...) #define LOG_TRACE(format, ...) #define BEGIN_BLOCK_IF_LOGLEVEL_FATAL #define BEGIN_BLOCK_IF_LOGLEVEL_ERROR #define BEGIN_BLOCK_IF_LOGLEVEL_WARN if (0) #define BEGIN_BLOCK_IF_LOGLEVEL_INFO if (0) #define BEGIN_BLOCK_IF_LOGLEVEL_DEBUG if (0) #define BEGIN_BLOCK_IF_LOGLEVEL_TRACE if (0) #else // when ZDNN_CONFIG_DEBUG is on // // - fully utilize loglevel/logmodule functionalities #define LOG_FATAL(format, ...) \ log_fatal(__func__, __FILE__, __LINE__, format, __VA_ARGS__) #define LOG_ERROR(format, ...) \ log_error(__func__, __FILE__, __LINE__, format, __VA_ARGS__) #define LOG_WARN(format, ...) \ log_warn(__func__, __FILE__, __LINE__, format, __VA_ARGS__) #define LOG_INFO(format, ...) \ log_info(__func__, __FILE__, __LINE__, format, __VA_ARGS__) #define LOG_DEBUG(format, ...) \ log_debug(__func__, __FILE__, __LINE__, format, __VA_ARGS__) #define LOG_TRACE(format, ...) \ log_trace(__func__, __FILE__, __LINE__, format, __VA_ARGS__) #define BEGIN_IF_LOGLEVEL(lvl, file_name) \ if ((log_level >= lvl) && logmodule_matches(file_name)) #define BEGIN_BLOCK_IF_LOGLEVEL_FATAL \ BEGIN_IF_LOGLEVEL(LOGLEVEL_FATAL, __FILE__) #define BEGIN_BLOCK_IF_LOGLEVEL_ERROR \ BEGIN_IF_LOGLEVEL(LOGLEVEL_ERROR, __FILE__) #define BEGIN_BLOCK_IF_LOGLEVEL_WARN BEGIN_IF_LOGLEVEL(LOGLEVEL_WARN, __FILE__) #define BEGIN_BLOCK_IF_LOGLEVEL_INFO BEGIN_IF_LOGLEVEL(LOGLEVEL_INFO, __FILE__) #define BEGIN_BLOCK_IF_LOGLEVEL_DEBUG \ BEGIN_IF_LOGLEVEL(LOGLEVEL_DEBUG, __FILE__) #define BEGIN_BLOCK_IF_LOGLEVEL_TRACE \ BEGIN_IF_LOGLEVEL(LOGLEVEL_TRACE, __FILE__) #endif // ----------------------------------------------------------------------------- // zDNN Status Related Functions // ----------------------------------------------------------------------------- zdnn_status set_zdnn_status(zdnn_status status, const char *func_name, const char *file_name, int line_no, const char *format, ...); #define ZDNN_STATUS(status, format, ...) \ set_zdnn_status(status, __func__, __FILE__, __LINE__, format, __VA_ARGS__) #define NO_ARG 0 #define ZDNN_STATUS_NO_MSG(status) ZDNN_STATUS(status, NULL, NO_ARG) #ifndef ZDNN_CONFIG_DEBUG #define ZDNN_STATUS_OK ZDNN_OK #else #define ZDNN_STATUS_OK ZDNN_STATUS_NO_MSG(ZDNN_OK) #endif // ----------------------------------------------------------------------------- // Misc get_*() Functions // ----------------------------------------------------------------------------- short get_func_code_num_gates(nnpa_function_code func_code); short get_data_layout_num_gates(zdnn_data_layouts layout); short get_data_layout_dims(zdnn_data_layouts layout); const char *get_data_layout_str(zdnn_data_layouts layout); const char *get_data_format_str(zdnn_data_formats format); short get_data_type_size(zdnn_data_types type); const char *get_data_type_str(zdnn_data_types type); const char *get_rnn_direction_str(lstm_gru_direction dir); const char *get_softmax_act_str(zdnn_softmax_act func); const char *get_matmul_op_str(zdnn_matmul_ops op); const char *get_matmul_bcast_op_str(zdnn_matmul_bcast_ops op); const char *get_pool_padding_str(zdnn_pool_padding pad); const char *get_conv2d_act_str(zdnn_conv2d_act func); uint64_t get_num_elements(const zdnn_ztensor *ztensor, elements_mode mode); uint32_t get_rnn_concatenated_dim1(uint32_t val, zdnn_concat_info info); uint32_t get_rnn_concatenated_dim2(uint32_t val, zdnn_concat_info info); // ----------------------------------------------------------------------------- // Print Utilities // ----------------------------------------------------------------------------- void print_bits(size_t const size, void const *const ptr); void print_hex(size_t const size, void const *const ptr); void print_dlf16_buffer(void *buffer, uint64_t buffer_size); void print_desc(zdnn_tensor_desc *desc); void print_ztensor(const zdnn_ztensor *ztensor, char *name, bool print_data); typedef enum dump_mode { AS_HEX, AS_FLOAT } dump_mode; void dumpdata_origtensor(const zdnn_tensor_desc *pre_tfrmd_desc, void *tensor_data, dump_mode mode); void dumpdata_ztensor(const zdnn_ztensor *ztensor, dump_mode mode, bool print_all); // ----------------------------------------------------------------------------- // Misc Macros // ----------------------------------------------------------------------------- #define CEIL(a, b) (uint64_t)((a + b - 1) / b) // positive numbers only #define MIN(a, b) ((a > b) ? b : a) #define MAX(a, b) ((a < b) ? b : a) #define BIT_SIZEOF(a) (sizeof(a) * 8) // padded = next multiple of AIU_2BYTE_CELLS_PER_STICK #define PADDED(x) \ ((uint32_t)CEIL(x, AIU_2BYTE_CELLS_PER_STICK) * AIU_2BYTE_CELLS_PER_STICK) // ----------------------------------------------------------------------------- // Private global variables // ----------------------------------------------------------------------------- #define PRINT_DIMS(x) \ printf(#x " pre: %u %u %u %u\n", (x)->pre_transformed_desc->dim4, \ (x)->pre_transformed_desc->dim3, (x)->pre_transformed_desc->dim2, \ (x)->pre_transformed_desc->dim1); \ printf(#x ": %u %u %u %u\n", (x)->transformed_desc->dim4, \ (x)->transformed_desc->dim3, (x)->transformed_desc->dim2, \ (x)->transformed_desc->dim1); #endif /* ZDNN_ZDNN_PRIVATE_H_ */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������