pax_global_header 0000666 0000000 0000000 00000000064 14364043643 0014521 g ustar 00root root 0000000 0000000 52 comment=4ae745cfa65b694e8af014b3787d9185cc7a7d0d
zDNN-1.0.1/ 0000775 0000000 0000000 00000000000 14364043643 0012331 5 ustar 00root root 0000000 0000000 zDNN-1.0.1/.github/ 0000775 0000000 0000000 00000000000 14364043643 0013671 5 ustar 00root root 0000000 0000000 zDNN-1.0.1/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 14364043643 0016054 5 ustar 00root root 0000000 0000000 zDNN-1.0.1/.github/ISSUE_TEMPLATE/bug_report.md 0000664 0000000 0000000 00000000761 14364043643 0020552 0 ustar 00root root 0000000 0000000 ---
name: Bug
about: File a bug/issue
title: '[BUG]
'
labels: Bug, Needs Triage
assignees: ''
---
### Current Observation:
### Expected:
### Location:
### Anything else:
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
```
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
```
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
```
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
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
[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
[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
[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
[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
[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
[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
[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
[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
[Back to Table of Contents](#TOC)
| Mnemonic Constant | Value | Meaning |
| -------------------------------- | ---------- | ------------------------------ |
| ZDNN_OK | 0x00000000 | Success. |
#### Warning Statuses
| 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
| 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
The following statuses indicate issues returned from the hardware.
| 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.
| 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
[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
[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
[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
[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
- 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
- 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:
- 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)
(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:
`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` |
| bias | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_BIASES` + one of the following:
`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:
`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:
`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:
- 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)
(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:
`PREV_LAYER_NONE`/`PREV_LAYER_UNI`/`PREV_LAYER_BIDIR` |
| bias | `zdnn_generate_transformed_desc_concatenated` - `RNN_TYPE_LSTM` + `USAGE_BIASES` + one of the following:
`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:
`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:
`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:
.
- `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
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:
.
- `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
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:
.
- `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)
width_out = ceil(width_in/stride_width) |
| both strides > 0 and =< 13, VALID padding | height_in must be >= kernel_height
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)
width_out = ceil((width_in - kernel_width + 1)/stride_width) |
| both strides = 0, VALID padding | height_in must be = kernel_height
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
#include
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#### Features
#### Fixes
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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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_";
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
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_";
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
// 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
#include
#include
/// 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_";
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
#include
#include
#include
#include
/*
* 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
#include
#include
#include
#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
#include
#include
#include
#include
#include
#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
#include
#include
#include
#include
#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
#include
#include
#include
#include
#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
#include
#include
#include
#include
// 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
#include
#include
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
#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
#include
#include
#include
#include
#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
#include
#include
#include
/*********************************************************************
* 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
#include
#include
#include
#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
#include
#include
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
#include
#include
#include
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
// 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
#include
#include
#include
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
#include
#include
#include
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
#include
#include
#include
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
#include
#include
#include
#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
#include
#include
#include
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
#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
// 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
#include
#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
#include
#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
#include
#include
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
// -----------------------------------------------------------------------------
// 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 include
#ifdef __MVS__
#define _XOPEN_SOURCE_EXTENDED 1
#undef _ALL_SOURCE
#endif
#include "testsupport.h"
#include "zdnn.h"
#include "zdnn_private.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
#include
#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
#include
// 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 |
// +---------------------------------------------
// | BIAS_ADD |
// +---------------------------------------------
// | TS_C_OUT (LSTM) / TS_H_OUT (GRU) |
// | TS_C_OUT (LSTM) / TS_H_OUT (GRU) |
// ----------------------------------------------
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 | ^
// +--------------------------- | |
// | FWD TS_H_OUT 1 | |
// +--------------------------- | |
// | BWD TS_H_OUT 1 | |
// +--------------------------- | |
// | ... | . .
// +--------------------------- | |
// | FWD TS_H_OUT N | V
// +--------------------------- 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
/// 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
#include
#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
#include
/* 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
#include
#include
#include
#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
#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
/// 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
#include
#include
/// 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
#include
#include
#include
/// 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
#include
#include
#include
#if defined(__MVS__)
#include
#include
#include
#include
#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
#include
#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
#include
#include
#include
#include
#ifndef __MVS__
#include
#include
#else
#include
#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
#include
#include
#include
#include
#include
#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= ] -f
# : gcc -E /zdnn/zdnn.h -o zdnn.i
# : /zdnn/zdnn.map
# : readelf -W --dyn-syms libzdnn.so
# : 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 : 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 : 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 : 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
#include
#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
#include
#include
#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
#include
#include
#include