Full Code of Xtra-Computing/ThunderGP for AI

master c316a34d241f cached
166 files
6.2 MB
1.6M tokens
268 symbols
1 requests
Download .txt
Showing preview only (6,521K chars total). Download the full file or copy to clipboard to get everything.
Repository: Xtra-Computing/ThunderGP
Branch: master
Commit: c316a34d241f
Files: 166
Total size: 6.2 MB

Directory structure:
gitextract_433gbfev/

├── .github/
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.md
│       └── feature_request.md
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── Makefile
├── README.md
├── ThunderGP.mk
├── application/
│   ├── ar/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── bfs/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── casair/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── customized_apply.cpp
│   │   ├── dataPrepare.cpp
│   │   ├── host_vertex_apply.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── casir/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── customized_apply.cpp
│   │   ├── dataPrepare.cpp
│   │   ├── host_vertex_apply.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── cc/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── common.mk
│   ├── global_config.h
│   ├── para_check.h
│   ├── pr/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   └── l2.h
│   ├── spmv/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   └── l2.h
│   ├── sssp/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   └── l2.h
│   ├── template/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── host_vertex_apply.cpp
│   │   ├── l2.h
│   │   └── vertex_apply.cpp
│   └── wcc/
│       ├── apply_kernel.mk
│       ├── build.mk
│       ├── config.mk
│       ├── dataPrepare.cpp
│       └── l2.h
├── automation/
│   ├── auto_gen_code.mk
│   ├── auto_gen_makefile.mk
│   ├── auto_gen_parameters.mk
│   ├── devices/
│   │   ├── device_common.h
│   │   ├── xilinx_u200_xdma_201830_2.h
│   │   ├── xilinx_u250_xdma_201830_2.h
│   │   └── xilinx_vcu1525_xdma_201830_1.h
│   ├── makefile_gen.cpp
│   ├── para_gen.cpp
│   ├── parser/
│   │   ├── customize.cpp
│   │   ├── customize.h
│   │   ├── customize_str.h
│   │   ├── kernel_interface.cpp
│   │   ├── kernel_interface.h
│   │   ├── makefile.cpp
│   │   ├── makefile.h
│   │   ├── mem_interface.cpp
│   │   └── mem_interface.h
│   ├── parser.cpp
│   ├── parser.h
│   ├── parser_debug.cpp
│   └── parser_debug.h
├── dataset/
│   ├── README.md
│   ├── kronecker_generator.m
│   ├── rmat-14-32.txt
│   └── rmat.m
├── docs/
│   ├── algorithm_mapping.md
│   ├── api_details.md
│   ├── compile_arch.md
│   ├── memory.md
│   ├── results.md
│   ├── scheduling.md
│   └── verification.md
├── libfpga/
│   ├── common_template/
│   │   ├── apply_kernel.mk
│   │   ├── apply_top.cpp
│   │   └── scatter_gather_top.cpp
│   ├── customize_template/
│   │   ├── customize_apply_cl_kernel.h
│   │   ├── customize_apply_kernel.mk
│   │   ├── customize_apply_top.cpp
│   │   └── customize_mem.h
│   ├── fpga_application.h
│   ├── fpga_apply.h
│   ├── fpga_cache.h
│   ├── fpga_decoder.h
│   ├── fpga_edge_prop.h
│   ├── fpga_filter.h
│   ├── fpga_gather.h
│   ├── fpga_global_mem.h
│   ├── fpga_gs_top.h
│   ├── fpga_process_edge.h
│   ├── fpga_raw_solver.h
│   ├── fpga_slice.h
│   └── graph_fpga.h
├── libgraph/
│   ├── common.h
│   ├── default_entry.cpp
│   ├── host_graph_api.h
│   ├── host_graph_data_structure.h
│   ├── host_graph_dataflow.cpp
│   ├── host_graph_partition.cpp
│   ├── host_graph_sw.h
│   ├── kernel/
│   │   ├── host_graph_kernel.cpp
│   │   └── host_graph_kernel.h
│   ├── memory/
│   │   ├── he_mapping.cpp
│   │   ├── he_mem.cpp
│   │   ├── he_mem.h
│   │   ├── he_mem_attr.h
│   │   ├── he_mem_config.h
│   │   └── he_mem_id.h
│   ├── misc/
│   │   ├── data_helper.cpp
│   │   ├── graph.cpp
│   │   ├── graph.h
│   │   ├── host_graph_csv.hpp
│   │   ├── host_graph_mem.cpp
│   │   ├── host_graph_mem.h
│   │   └── host_graph_misc_inner.h
│   ├── scheduler/
│   │   ├── host_graph_scheduler.cpp
│   │   ├── host_graph_scheduler.h
│   │   ├── normal/
│   │   │   └── scheduler.cpp
│   │   └── secondOrderEstimator/
│   │       └── scheduler.cpp
│   ├── test/
│   │   └── test_col.c
│   └── verification/
│       ├── host_graph_cmodel.cpp
│       ├── host_graph_verification.h
│       ├── host_graph_verification_apply.cpp
│       ├── host_graph_verification_gs.cpp
│       └── host_graph_verification_inner.h
└── utils/
    ├── bitstream.mk
    ├── clean.mk
    ├── help.mk
    ├── main.mk
    ├── opencl.mk
    ├── report_usage.tcl
    ├── utils.mk
    └── xcl/
        ├── xcl.c
        ├── xcl.h
        └── xcl.mk

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
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 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.


================================================
FILE: .gitignore
================================================
*.diff
*.log
host_graph_fpga*
_x
xclbin
.Xil
*.str
sdx_*
*.json
*.jou
release*
test_log*
xclbin*
*.protoinst
*.csv
sdaccel.ini
.run
csr
*.xclbin
*.sh
tmp_fpga_top
tmp_para
code_gen
para_gen
makefile_gen

================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
 advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
 address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
 professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at xtra-computing@googlegroups.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


================================================
FILE: LICENSE
================================================
                                 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.


================================================
FILE: Makefile
================================================
include ThunderGP.mk

.PHONY: all clean exe hwemuprepare


include utils/main.mk

================================================
FILE: README.md
================================================
![logo](docs/images/ThunderGP.png)

[![GitHub license](https://img.shields.io/badge/license-apache2-yellowgreen)](./LICENSE)
[![GitHub issues](https://img.shields.io/github/issues/Xtra-Computing/ThunderGP.svg)](https://github.com/Xtra-Computing/ThunderGP/issues)
[![DOI](https://zenodo.org/badge/254307005.svg)](https://zenodo.org/badge/latestdoi/254307005)

# ThunderGP: HLS-based Graph Processing Framework on FPGAs

## What's new?

***ThunderGP for HBM-Enabled FPGA platforms has been released. Please see the [branch](https://github.com/Xtra-Computing/ThunderGP/tree/v_HBM).***

ThunderGP has been published in ACM Transactions on Reconfigurable Technology and Systems (TRETS), as one of "Best Papers in FPGA 2021". 

ThunderGP won the third place in [2020 Xilinx Adaptive Computing Developer Contest](https://www.hackster.io/contests/xilinxadaptivecomputing), top 9 out of 79 teams.

ThunderGP is accepted to be [FPGA 2021](https://isfpga.org/). Read [the paper](https://github.com/Xtra-Computing/ThunderGP/blob/master/ThunderGP_camera_ready-pdfa.pdf).

ThunderGP is featured at [Xilinx Apps and Libraries](https://www.xilinx.com/products/apps-and-libraries.html).

ThunderGP was presented at [XACC@NUS Workshop Series 2020: Reconfigurable Computing Systems](https://xaccnus.github.io/). see [Slides](https://xaccnus.github.io/slides/ThunderGP_Fast_Graph_Processing_for_HLS-based_FPGAs.pdf), [Video/Youtube](https://youtu.be/zqxLevJiCpk), [Video/bilibili](https://www.bilibili.com/video/BV1kD4y1m7r8/).


## Introduction

ThunderGP enables data scientists to enjoy the ***performance*** of FPGA-based graph processing without compromising ***programmability***. ***To our best knowledge and experiments, this is the fastest graph processing framework on HLS-based FPGAs.***

Two aspacts make the ThunderGP deliver superior performance.
On the one hand, ThunderGP embraces an improved execution flow to better exploit the pipeline parallelism of FPGA and alleviate the data access amount to the global memory. On the other hand, the memory accesses are highly optimized to fully utilize the memory bandwidth capacity of the hardware platforms. 

On Xilinx multi-SLR based FPGAs, it is running at 250Mhz, and the performance can be up to ***6400 MTEPS (million traversed edges per second)***, or a ***2.9 times speedup*** over the state-of-the-art.  

## Prerequisites
* The gcc-9.3
* Tools:
    * SDAccel 2018.3 Design Suit
    * SDAccel 2019.1 Design Suit
* Evaluated platforms from Xilinx:
    * Xilinx Virtex UltraScale+ FPGA VCU1525 Acceleration Development Kit (SDAccel 2018.3)
    * Alveo U200 Data Center Accelerator Card (SDAccel 2019.1)
    * Alveo U250 Data Center Accelerator Card (SDAccel 2019.1)
    
## Run the code
ThunderGP currently has seven build-in graph algorithms: PageRank (PR), Sparse Matrix-Vector Multiplication (SpMV), Breadth-First Search (BFS), Single Source Shortest Path (SSSP), Closeness Centrality (CC), ArticleRank (AR), and Weakly Connected Component (WCC). 
The desired application can be implemented by passing argument ```app=[the algorithm]``` to ``` make ``` command. The below table is for quick reference.

| Argument    | Accelerated algorithm  |
|--------------|--------------|
| ```app=pr``` | PageRank (PR)|
| ```app=spmv``` | Sparse Matrix-vector Multiplication (SpMV) |
| ```app=bfs``` | Breadth First Search (BFS)|
| ```app=sssp``` | Single Source Shortest Path (SSSP)|
| ```app=cc``` | Closeness Centrality (CC)|
| ```app=ar``` | ArticleRank  (AR)|
| ```app=wcc``` | Weakly Connected Component  (WCC)|

#### Here is the example of implementing the accelerator for PageRank on Alveo U250 platform with SDAccel 2019.1. 
```sh
$ git clone https://github.com/Xtra-Computing/ThunderGP.git
$ cd ./
$ vim ThunderGP.mk 
$ # configure the DEVICE as DEVICES := xilinx_u250_xdma_201830_2; configure TARGETS := hw
$ make app=pr all # make the host execution program and the FPGA bitstream. It takes time :)
# For execution on real hardware. The path of graph dataset needs to be provided by the user. 
$ ./host_graph_fpga_pr xclbin_pr/*.xclbin ./dataset/rmat-14-32.txt
```
#### More details: [Compiling ThunderGP ](docs/compile_arch.md)

## Results (performance)

Throughput (MTEPS) of different graph processing algorithms over datasets on VCU1525 platform.

|App.|PR|SPMV|BFS|SSSP|CC|AR|WCC |
|----|--|----|---|----|--|--|----|
|R21| 5,015|4,190|5,417|3,901|4,623|4,848|4,584 |
|R24| 4,599|3,781|3,437|3,430|4,339|4,486|4,328 |
|G24| 5,039|4,037|5,216|3,725|4,752|4,927|4,704 |
|G25| 4,464|3,615|4,660|3,343|4,344|4,389|4,356 |
|WT|  2,884|2,874|2,717|2,427|2,776|2,833|2,776 |
|MG|  4,454|3,883|4,939|3,699|4,077|4,285|4,088 |
|PK|  4,001|3,729|4,251|3,169|3,833|3,909|3,716 |
|WP|  3,030|2,994|3,112|2,491|2,993|2,931|2,894 |
|LJ|  3,186|3,003|3,408|2,623|3,113|3,081|3,099 |
|TW|  2,938|2,801|2,120|2,425|2,962|2,853|2,894 |


Throughput (MTEPS) of different graph processing algorithms over datasets on U250 platform. 


|App.|PR|SPMV|BFS|SSSP|CC|AR|WCC |
|----|--|----|---|----|--|--|----|
|R21  |4,669|5,056|6,028|4,879|4,783|4,667|4,901 |
|R24  |4,732|4,946|5,897|4,285|4,939|4,732|4,988 |
|G24  |5,040|5,305|5,772|4,428|3,705|5,040|5,303 |
|G25  |4,978|4,072|4,974|3,864|3,661|4,984|5,254 |
|WT   |2,251|2,938|2,630|2,583|2,369|2,253|2,405 |
|MG   |3,756|4,195|4,949|4,378|3,914|3,737|3,891 |
|PK   |3,630|4,372|4,629|3,927|3,865|3,662|3,841 |
|WP   |3,255|3,652|4,058|3,417|3,341|3,259|3,432 |
|LJ   |3,342|3,693|4,329|3,614|3,557|3,328|3,708 |
|TW   |3,538|3,959|3,671|3,585|3,759|3,533|3,806 |



* [Datasets and More Results](docs/results.md)

## APIs (programmability) 
![auto](docs/images/automation.png)


Benefiting from the high level abstraction of HLS, our APIs natively support C/C++ languages.  
ThunderGraph covers three levels of API for implementation or further exploration. 
APIs in L1 and L2 are for building the accelerators, and APIs of L3 are for host program. Details are as below:

* L1 is used to construct the basic modules to build the compute kernels and the dataflow. 

* L2 provides hooks for mapping graph processing algorithms. 
    * [Mapping new graph analytic algorithms](docs/algorithm_mapping.md)  

* L3 provides the high-level APIs on host side to deploy or control graph processing accelerator. Since recent FPGAs usually consist of multiple (SLRs), L3 also wraps the partition scheduling and memory management interface for multiple SLRs. 

    * [Memory Management](docs/memory.md) 

    * [Scheduling across Multi SLRs](docs/scheduling.md) 

    * [Verification](docs/verification.md)

* More details: [ThunderGP APIs ](docs/api_details.md)


## Framework Overview

### The Adopted Computation Model
The Gather-Apply-Scatter (GAS) model is widely used for FPGA-based graph processing frameworks as computation model due to its extensibility to various graph processing algorithms. ThunderGP adopts a simplified version of GAS model by following work [*On-the-fly-data-shuffling-for-OpenCL-based-FPGAs*](https://www.comp.nus.edu.sg/~hebs/pub/fpl19-graph.pdf).
This model updates the vertex property by propagating from source vertex to destination vertex. The input for the model is an unordered set of directed edges of the graph. Undirected edges in a graph can be represented by a pair of directed edges. 

<img src="docs/images/GASmodel.png" alt="drawing" width="500"/>

The process per iteration mainly contains three stages: **Scatter**, **Gather**, and **Apply**. 

* In the  **Scatter** stage (shown in line 2 to 6), for each input edge with format ```<src, dst, weight>```, an update tuple is generated for the destination vertex of the edge. The update tuple is of the format ```<dst, value>```, where the *dst* is the destination vertex of the edge and *value* is generated by processing the vertex properties and edge weights. 
* In the **Gather** stage (shown in line 7 to 9), all the update tuples generated in the  **Scatter** stage are accumulated to update destination vertices. 
* The final **Apply** stage (shown in line 10 to 12) executes an apply function on all the vertices of the graph. 


### The Execution Flow of ThunderGP

![overview](docs/images/overview.png)

As shown in the above diagram, The edges in one partition are streamed into **Scatter** stage, For each edges, the property of source vertices will be fetched from the global memory by the per-fetching and the cache module, at the same time, the property of corresponding edge, or the weight of edge is loaded from global memory in stream, then these two value go through an *__algorithm-specific processing__* which return an update of the property of the destination vertex, finally, at the end of scatter stage, this update value and the destination of this edge is combined to create a update tuple. The update tuples are streamed into the shuffle stage which dispatches the tuples to corresponding gather processing engines(PEs). The **Gather** PEs *__accumulates__* the update value in local on-chip memory which is caching the property of destination vertices. After all the edges in this partition are processed, the cached data in gather PEs will be aggregated to the global memory. and the **Apply** stage which calls *__algorithm-specific function__* updates all the vertices for the next iteration.

### Future Work

* Application wrapper for high level platform (Spark, etc.)
* Hardware-accelerated query engine.
* Cycle-precision software simulation for the verification of dynamic modules(Cache, etc.) and channel depth tuning.
* Optimization for large scale graph. (distributed processing or HBM-based memory hierarchy)


## How to cite **ThunderGP** 
If you use **ThunderGP**  in your paper, please cite our work ([full version](https://github.com/Xtra-Computing/ThunderGP/blob/master/ThunderGP_camera_ready-pdfa.pdf)).
```
@article{10.1145/3517141,
author = {Chen, Xinyu and Cheng, Feng and Tan, Hongshi and Chen, Yao and He, Bingsheng and Wong, Weng-Fai and Chen, Deming},
title = {ThunderGP: Resource-Efficient Graph Processing Framework on FPGAs with HLS},
year = {2022},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
issn = {1936-7406},
url = {https://doi.org/10.1145/3517141},
doi = {10.1145/3517141},
note = {Just Accepted},
journal = {ACM Trans. Reconfigurable Technol. Syst.},
month = {feb},
keywords = {FPGA; HBM; HLS; Graph Processing; Framework}
}

@inbook{10.1145/3431920.3439290,
author = {Chen, Xinyu and Tan, Hongshi and Chen, Yao and He, Bingsheng and Wong, Weng-Fai and Chen, Deming},
title = {ThunderGP: HLS-Based Graph Processing Framework on FPGAs},
year = {2021},
url = {https://doi.org/10.1145/3431920.3439290},
booktitle = {The 2021 ACM/SIGDA International Symposium on Field-Programmable Gate Arrays},
pages = {69–80},
numpages = {12}
}
```

## Related publications
* Xinyu Chen*, Ronak Bajaj^, Yao Chen, Jiong He, Bingsheng He, Weng-Fai Wong and Deming Chen. [On-The-Fly Parallel Data Shuffling for Graph Processing on OpenCL-based FPGAs](https://www.comp.nus.edu.sg/~hebs/pub/fpl19-graph.pdf). FPL, 2019.
* Xinyu Chen*, Yao Chen^, Ronak Bajaj, Jiong He, Bingsheng He, Weng-Fai Wong and Deming Chen. [Is FPGA useful for hash joins](https://www.comp.nus.edu.sg/~hebs/pub/cidr20-join.pdf). CIDR 2020: Conference on Innovative Data Systems Research


## Related systems
* Graph systems on GPU: [G3](https://github.com/Xtra-Computing/G3) | [Medusa](https://github.com/Xtra-Computing/Medusa)
* Other Thunder-series systems in Xtra NUS: [ThunderGBM](https://github.com/Xtra-Computing/thundergbm) | [ThunderSVM](https://github.com/Xtra-Computing/thundersvm)


## Key members
* Hongshi Tan, Xinyu Chen (NUS)
* Advisor: [Bingsheng He](https://www.comp.nus.edu.sg/~hebs/) and [Weng-Fai Wong](https://www.comp.nus.edu.sg/~wongwf/), NUS
* Collaborators: [Yao Chen (ADSC)](https://microideax.github.io/) and [Deming Chen (UIUC)](http://dchen.ece.illinois.edu/)


## Acknowledgement
* [Xilinx Adaptive Compute Clusters (XACC) program](https://www.xilinx.com/support/university/XUP-XACC.html)
* Singapore MoE Tier 2 grant (MOE2017-T2-1-122).
 



================================================
FILE: ThunderGP.mk
================================================
TARGETS := hw
# emu or acc:
#   hw
#   hw_emu

APP := 
# pass in by app=

TARGET_BANDWIDTH := 77
# target memory bandwidth in GB/s
# max: 77GB/s
# this value can be overridden by $(app)/build.mk

DEVICES := xilinx_vcu1525_xdma_201830_1
# device list:
#   xilinx_vcu1525_xdma_201830_1
#   xilinx_u200_xdma_201830_2
#   xilinx_u250_xdma_201830_2


================================================
FILE: application/ar/apply_kernel.mk
================================================


================================================
FILE: application/ar/build.mk
================================================

#scatter-gather kernel
HAVE_EDGE_PROP=false
HAVE_UNSIGNED_PROP=false

#apply kernel
HAVE_APPLY=true
CUSTOMIZE_APPLY=false
HAVE_APPLY_OUTDEG=true

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=false


================================================
FILE: application/ar/config.mk
================================================
FREQ=250

QUEUE_SIZE_FILTER=16
QUEUE_SIZE_MEMORY=512

LOG_SCATTER_CACHE_BURST_SIZE=6

APPLY_REF_ARRAY_SIZE=1


================================================
FILE: application/ar/dataPrepare.cpp
================================================
#include "host_graph_api.h"
#include "fpga_application.h"


static unsigned int avg_outdegree;

unsigned int dataPrepareGetArg(graphInfo *info)
{
    return avg_outdegree;
}

int dataPrepareProperty(graphInfo *info)
{
    int *outDeg              = (int *)get_host_mem_pointer(MEM_ID_OUT_DEG_ORIGIN);
    prop_t *vertexPushinProp = (prop_t*)get_host_mem_pointer(MEM_ID_PUSHIN_PROP);

    int vertexNum = info->vertexNum;
    int alignedVertexNum = get_he_mem(MEM_ID_PUSHIN_PROP)->size/sizeof(int);

    unsigned int total_outdegree = 0;

    for (int i = 0; i < vertexNum; i++)
    {
        vertexPushinProp[i]  = 0;
        total_outdegree +=  outDeg[i];
    }
    avg_outdegree = (unsigned int)(((double)total_outdegree) / vertexNum);

    for (int i = vertexNum; i < alignedVertexNum; i++) {
        vertexPushinProp[i]  = 0;
    }
    return 0;
}

================================================
FILE: application/ar/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__


#define kDamp               (0.85f)
#define kDampFixPoint       108//(0.85 << 7)  // * 128

#define SCALE_DEGREE		(16)
#define SCALE_DAMPING		(7)

/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
	return (srcProp);
}

/* source vertex property & edge property */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
	return (srcProp);
}

/* destination property update dst buffer update */
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
	return ((ori) + (update));
}

inline prop_t applyFunc( prop_t tProp,
                         prop_t source,
                         prop_t outDeg,
                         unsigned int (&extra)[APPLY_REF_ARRAY_SIZE],
                         unsigned int arg
                       )
{

	prop_t new_score ;
	prop_t old_score ;
	unsigned int C_avg = arg;

	prop_t tmp;
	prop_t C_Ta = outDeg;
	tmp = (1 << SCALE_DEGREE ) / (C_Ta + C_avg);

	old_score = source * tmp;
	new_score = kDampFixPoint * tProp + (unsigned int) ((1 << (SCALE_DEGREE + SCALE_DAMPING)) * (1.0f - kDamp));

	prop_t update = (new_score * tmp);

	extra[0] = (new_score - old_score) > 0 ? (new_score - old_score) : (old_score - new_score) ;

	return update;
}
#endif /* __L2_H__ */


================================================
FILE: application/ar/main.cpp
================================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fstream>

#include "host_graph_api.h"
#include "host_graph_verification.h"

using namespace std;

graphInfo graphDataInfo;

int main(int argc, char **argv) {

    char * xcl_file = NULL;
    if (argc > 1)
    {
        xcl_file = argv[1];
    }

    std::string gName;
    if (argc > 2)
    {
        gName = argv[2];
    }
    else
    {
        gName = "wiki-talk";
    }
    std::string mode = "normal";


    DEBUG_PRINTF("start main\n");

    acceleratorInit("graph_fpga", xcl_file);

    acceleratorDataLoad(gName, mode, &graphDataInfo);

    acceleratorDataPreprocess(&graphDataInfo);

    for (int runCounter = 0 ; runCounter < 10 ; runCounter ++)
    {
        double startStamp, endStamp;
        startStamp = getCurrentTimestamp();

        acceleratorSuperStep(runCounter, &graphDataInfo);

        endStamp = getCurrentTimestamp();

        /* profile */
        acceleratorProfile(runCounter, runCounter, &graphDataInfo, endStamp - startStamp);
    }
    acceleratorDeinit();

    return 0;
}



================================================
FILE: application/bfs/apply_kernel.mk
================================================


================================================
FILE: application/bfs/build.mk
================================================

#scatter-gather kernel
HAVE_EDGE_PROP=false
HAVE_UNSIGNED_PROP=true

#apply kernel
HAVE_APPLY=true
CUSTOMIZE_APPLY=false
HAVE_APPLY_OUTDEG=false

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=false



================================================
FILE: application/bfs/config.mk
================================================
FREQ=250

QUEUE_SIZE_FILTER=32
QUEUE_SIZE_MEMORY=512

LOG_SCATTER_CACHE_BURST_SIZE=7

APPLY_REF_ARRAY_SIZE=1


================================================
FILE: application/bfs/dataPrepare.cpp
================================================
#include "host_graph_api.h"
#include "fpga_application.h"

#include <cstdlib>
#include <iostream>
#include <ctime>

unsigned int dataPrepareGetArg(graphInfo *info)
{
	return 0;
}

int dataPrepareProperty(graphInfo *info)
{
	int *vertexPushinProp =      (int*)get_host_mem_pointer(MEM_ID_PUSHIN_PROP);

	int alignedVertexNum = get_he_mem(MEM_ID_PUSHIN_PROP)->size / sizeof(int);

	for (int i = 0; i < alignedVertexNum; i++)
	{
		vertexPushinProp[i]    = MAX_PROP;
	}
	int select_index  = ((double)std::rand()) / ((RAND_MAX + 1u) / info->vertexNum);
	vertexPushinProp[select_index] = 0x80000001;
	return 0;
}

================================================
FILE: application/bfs/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__


#define MAX_PROP                  (INT_MAX - 1)

#define VERTEX_ACTIVE_BIT_MASK    (0x80000000)
#define IS_ACTIVE_VERTEX(a)       ((((((a) & VERTEX_ACTIVE_BIT_MASK) == VERTEX_ACTIVE_BIT_MASK))) ? 1 : 0)

/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
  return ((srcProp) + 1);
}

/* source vertex property & edge property */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
  return (srcProp);
}

/* destination property update dst buffer update */
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
  return (
           (
             (
               (((ori) & (~VERTEX_ACTIVE_BIT_MASK)) > ((update) & (~VERTEX_ACTIVE_BIT_MASK)))
               && (update != 0)
             )
             || (ori == 0x0)
           ) ? (update) : (ori)
         );
}

inline prop_t applyFunc( prop_t tProp,
                         prop_t source,
                         prop_t outDeg,
                         unsigned int (&extra)[APPLY_REF_ARRAY_SIZE],
                         unsigned int arg
                       )
{
  prop_t update = 0;

  prop_t uProp  = source;
  prop_t wProp;
  if (((tProp & VERTEX_ACTIVE_BIT_MASK) == VERTEX_ACTIVE_BIT_MASK) && (uProp == MAX_PROP))
  {
    extra[0] = 1;
    wProp = tProp; // current active vertex, not travsered
  }
  else
  {
    extra[0] = 0;
    wProp = uProp & 0x7fffffff; // not travsered
  }
  update = wProp;

  return update;
}

#endif /* __L2_H__ */


================================================
FILE: application/bfs/main.cpp
================================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fstream>

#include "host_graph_api.h"
#include "host_graph_verification.h"

using namespace std;

graphInfo graphDataInfo;

int main(int argc, char **argv) {

    char * xcl_file = NULL;
    if (argc > 1)
    {
        xcl_file = argv[1];
    }

    std::string gName;
    if (argc > 2)
    {
        gName = argv[2];
    }
    else
    {
        gName = "wiki-talk";
    }
    std::string mode = "normal";



    DEBUG_PRINTF("start main\n");

    acceleratorInit("graph_fpga", xcl_file);

    acceleratorDataLoad(gName, mode, &graphDataInfo);

    acceleratorDataPreprocess(&graphDataInfo);

    int runCounter = 0;
    int activeVertices = 1;
    while (activeVertices != 0)
    {

        double startStamp, endStamp;
        startStamp = getCurrentTimestamp();

        acceleratorSuperStep(runCounter, &graphDataInfo);

        endStamp = getCurrentTimestamp();

        int *reg = (int *)acceleratorQueryRegister();
        activeVertices = reg[0];
        DEBUG_PRINTF("activeVertice : %d \n", activeVertices);


        /* profile */
        acceleratorProfile(runCounter, runCounter, &graphDataInfo, endStamp - startStamp);
        runCounter++;
    }
    acceleratorDeinit();

    return 0;
}



================================================
FILE: application/casair/apply_kernel.mk
================================================


================================================
FILE: application/casair/build.mk
================================================

#scatter-gather kernel
HAVE_EDGE_PROP=true
HAVE_UNSIGNED_PROP=false

#apply kernel
HAVE_APPLY=true
CUSTOMIZE_APPLY=true
HAVE_APPLY_OUTDEG=false

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=false

#override bandwidth
TARGET_BANDWIDTH = 17

#override partition_size
TARGET_PARTITION_SIZE = 66536


================================================
FILE: application/casair/config.mk
================================================
FREQ=300

QUEUE_SIZE_FILTER=32
QUEUE_SIZE_MEMORY=512

LOG_SCATTER_CACHE_BURST_SIZE=7

APPLY_REF_ARRAY_SIZE=1


================================================
FILE: application/casair/customized_apply.cpp
================================================

// pre-define:
//                  uProp = theta_i * N
//                  tProp = sum(sourceVertexProp * w) in scatter-gather stage
//                  wProp: write back value

/* Apply: updates all vertices for next iteration */
int applyFunc( ... )
{
#pragma THUNDERGP APPLY_BASE_TYPE  float

#pragma THUNDERGP DEF_ARRAY theta_s
float theta_s;
#pragma THUNDERGP DEF_ARRAY theta_a
float theta_a;
#pragma THUNDERGP DEF_ARRAY theta_r
float theta_r;
#pragma THUNDERGP DEF_INPUT_ONLY_ARRAY alpha
float alpha;
#pragma THUNDERGP DEF_INPUT_ONLY_ARRAY  pi
float pi;
#pragma THUNDERGP DEF_INPUT_ONLY_ARRAY  N
float N;
#pragma THUNDERGP DEF_SCALAR beta
float beta;
#pragma THUNDERGP DEF_SCALAR gamma
float gamma;


#pragma THUNDERGP USER_APPLY_CODE_START
//start

float n = 1 / N;
float theta_i = uProp * n / FIXED_SCALE;
float weightSum = tProp / FIXED_SCALE;
float updated_i =  beta * pi * theta_s * (theta_i +  weightSum * n);
float theta_i_update = (1 - gamma) * theta_i + updated_i;

float newtheta_a =  theta_a + alpha * theta_s;
float newtheta_s = (1 - alpha) * theta_s - updated_i;
float newtheta_r = theta_r + gamma * theta_i;

wProp = (theta_i_update * N) * FIXED_SCALE;

#pragma THUNDERGP USER_APPLY_CODE_END
//end
}


================================================
FILE: application/casair/dataPrepare.cpp
================================================
#include "host_graph_api.h"
#include "fpga_application.h"
#include "customize_mem_1.h"


const float epsilion = 0.077;
const float nu = 0.023;

#define DATA_PATH                   "../../sir/"
#define MEM_ID_LOAD_EDGE_PROP       (MEM_ID_USER_DEFINE_BASE)
#define MEM_ID_LOAD_VERTEX_PROP     (MEM_ID_USER_DEFINE_BASE + 1)

int dataPrepareProperty(graphInfo *info)
{

    global.gamma = nu;
    global.beta = epsilion;

    load_from_csv<float>(DATA_PATH"input_S0.csv",    MEM_ID_THETA_S, MEM_ATTR_THETA_S);
    output_init<float>(MEM_ID_NEWTHETA_S, MEM_ATTR_NEWTHETA_S, MEM_ID_THETA_S);
    load_from_csv<float>(DATA_PATH"input_A0.csv",    MEM_ID_THETA_A, MEM_ATTR_THETA_A);
    output_init<float>(MEM_ID_NEWTHETA_A, MEM_ATTR_NEWTHETA_A, MEM_ID_THETA_A);
    load_from_csv<float>(DATA_PATH"input_R0.csv",    MEM_ID_THETA_R, MEM_ATTR_THETA_R);
    output_init<float>(MEM_ID_NEWTHETA_R, MEM_ATTR_NEWTHETA_R, MEM_ID_THETA_R);

    load_from_csv<float>(DATA_PATH"input_alpha.csv", MEM_ID_ALPHA,   MEM_ATTR_ALPHA);
    load_from_csv<float>(DATA_PATH"input_pi.csv",    MEM_ID_PI,      MEM_ATTR_PI);

    float * pop = load_from_csv<float>(DATA_PATH"input_pop.csv", MEM_ID_N,       MEM_ATTR_N);
    float * i0  = load_from_csv<float>(DATA_PATH"input_I0.csv", MEM_ID_LOAD_VERTEX_PROP, ATTR_HOST_ONLY);
   
    if ((pop == NULL) || (i0 == NULL))
    {
        return -1;
    }

    prop_t *vertexPushinProp = (prop_t*)get_host_mem_pointer(MEM_ID_PUSHIN_PROP);
    int vertexNum = info->vertexNum;
    for (int i = 0; i < info->vertexNum; i++)
    {
        vertexPushinProp[i] = (int)(i0[i] * pop[i] * FIXED_SCALE);
    }
    int alignedVertexNum = get_he_mem(MEM_ID_PUSHIN_PROP)->size / sizeof(int);
    for (int i = vertexNum; i < alignedVertexNum; i++) {
        vertexPushinProp[i]  = 0;
    }

    int * loadedEdgeProp = load_from_csv<int>(DATA_PATH"edge_prop.txt",     MEM_ID_LOAD_EDGE_PROP, ATTR_HOST_ONLY);
    prop_t *edgeProp    = (prop_t*)get_host_mem_pointer(MEM_ID_EDGE_PROP);
    int edgeNum = info->edgeNum;
    for (int i = 0; i < edgeNum; i++)
    {
        edgeProp[i] = loadedEdgeProp[i];
    }
    int alignedEdgeNum = get_he_mem(MEM_ID_EDGE_PROP)->size / sizeof(int);
    for (int i = edgeNum; i < alignedEdgeNum; i++)
    {
        edgeProp[i] = 0;
    }


    return 0;
}

unsigned int dataPrepareGetArg(graphInfo *info)
{
    return 0;
}

================================================
FILE: application/casair/host_vertex_apply.cpp
================================================
#include "host_graph_sw.h"

#include "fpga_application.h"

#include "host_graph_verification.h"


#include "customize_mem_1.h"
#include "customize_apply_cl_kernel_1.h"





void partitionApplyCModel(
    cl_context              &context,
    cl_device_id            &device,
    int                     superStep,
    int                     partId,
    unsigned int            applyArg
)
{
}


================================================
FILE: application/casair/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__


#define FIXED_SCALE                    (1000000)


/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
    return (srcProp);
}

/* Scatter: return source vertex property "srcProp" as the value of update tuple */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
    return ((srcProp) * (edgeProp));
}

/* Gather: accumulates the update values from source vertices to original values*/
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
    return ((ori) + (update));
}

#endif /* __L2_H__ */


================================================
FILE: application/casair/main.cpp
================================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fstream>


#include "customize_mem_1.h"
#include "host_graph_api.h"

using namespace std;

graphInfo graphDataInfo;

int main(int argc, char **argv) {

    char * xcl_file = NULL;
    if (argc > 1)
    {
        xcl_file = argv[1];
    }

    std::string gName;
    if (argc > 2)
    {
        gName = argv[2];
    }
    else
    {
        gName = "wiki-talk";
    }
    std::string mode = "normal";

    DEBUG_PRINTF("start main\n");

    acceleratorInit("graph_fpga", xcl_file);
    acceleratorDataLoad(gName, mode, &graphDataInfo);
    acceleratorDataPreprocess(&graphDataInfo);

    {
        double startStamp, endStamp;
        startStamp = getCurrentTimestamp();
        acceleratorSuperStep(0, &graphDataInfo);
        endStamp = getCurrentTimestamp();
        DEBUG_PRINTF("exe time : %lf \n", endStamp - startStamp);
    }

    write_back_csv<float>("out_s1.csv", MEM_ID_NEWTHETA_S);
    write_back_csv<float>("out_a1.csv", MEM_ID_NEWTHETA_A);
    write_back_csv<float>("out_r1.csv", MEM_ID_NEWTHETA_R);

    acceleratorDeinit();

    return 0;
}


================================================
FILE: application/casir/apply_kernel.mk
================================================


================================================
FILE: application/casir/build.mk
================================================

#scatter-gather kernel
HAVE_EDGE_PROP=true
HAVE_UNSIGNED_PROP=false

#apply kernel
HAVE_APPLY=true
CUSTOMIZE_APPLY=true
HAVE_APPLY_OUTDEG=false

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=false

#override bandwidth
TARGET_BANDWIDTH = 17

#override partition_size
TARGET_PARTITION_SIZE = 66536


================================================
FILE: application/casir/config.mk
================================================
FREQ=300

QUEUE_SIZE_FILTER=32
QUEUE_SIZE_MEMORY=512

LOG_SCATTER_CACHE_BURST_SIZE=7

APPLY_REF_ARRAY_SIZE=1


================================================
FILE: application/casir/customized_apply.cpp
================================================

// pre-define:
//                  uProp = theta_i * N
//                  tProp = sum(sourceVertexProp * w) in scatter-gather stage
//                  wProp: write back value

/* Apply: updates all vertices for next iteration */
int applyFunc( ... )
{
#pragma THUNDERGP APPLY_BASE_TYPE  float

#pragma THUNDERGP DEF_ARRAY theta_s
	float theta_s;
#pragma THUNDERGP DEF_ARRAY theta_r
	float theta_r;
#pragma THUNDERGP DEF_INPUT_ONLY_ARRAY  N
	float N;
#pragma THUNDERGP DEF_SCALAR epsilon
	float epsilon;
#pragma THUNDERGP DEF_SCALAR nu
	float nu;
#pragma THUNDERGP DEF_SCALAR a
	float a;
#pragma THUNDERGP DEF_SCALAR eta
	float eta;


#pragma THUNDERGP USER_APPLY_CODE_START
//start
	/*
	    St = Sp-epsilon*Sp*Ip - Sp*a * epsilon * eta* wetVec
	    It = (1-nu)*Ip+epsilon*Sp*Ip + Sp *a * epsilon * eta * wetVec
	    Rt = Rp+nu*Ip
	*/
	float theta_i = uProp / N / FIXED_SCALE;
	float wetVec = tProp / N / FIXED_SCALE;
	float newtheta_s = theta_s
	                   - epsilon * theta_s * theta_i
	                   - theta_s * a * eta * wetVec;
	float newtheta_r = theta_r + nu * theta_i;

	float newtheta_i = (1 - nu) * theta_i
	                   + epsilon * theta_s * theta_i
	                   + theta_s * a * eta * wetVec;
	wProp = newtheta_i * N * FIXED_SCALE;
#pragma THUNDERGP USER_APPLY_CODE_END
//end
}


================================================
FILE: application/casir/dataPrepare.cpp
================================================
#include "host_graph_api.h"
#include "fpga_application.h"
#include "customize_mem_1.h"


#define DATA_PATH                   "/graph_data/sir/"
#define MEM_ID_LOAD_EDGE_PROP       (MEM_ID_USER_DEFINE_BASE)
#define MEM_ID_LOAD_VERTEX_PROP     (MEM_ID_USER_DEFINE_BASE + 1)

int dataPrepareProperty(graphInfo *info)
{

    global.nu = 0.023;
    global.epsilon =  0.077;
    global.a = 0.5;
    global.eta = 0.01;

    load_from_csv<float>(DATA_PATH"input_S0.csv",    MEM_ID_THETA_S, MEM_ATTR_THETA_S);
    output_init<float>(MEM_ID_NEWTHETA_S, MEM_ATTR_NEWTHETA_S, MEM_ID_THETA_S);
    load_from_csv<float>(DATA_PATH"input_R0.csv",    MEM_ID_THETA_R, MEM_ATTR_THETA_R);
    output_init<float>(MEM_ID_NEWTHETA_R, MEM_ATTR_NEWTHETA_R, MEM_ID_THETA_R);

    float * pop = load_from_csv<float>(DATA_PATH"input_pop.csv", MEM_ID_N,       MEM_ATTR_N);
    float * i0  = load_from_csv<float>(DATA_PATH"input_I0.csv", MEM_ID_LOAD_VERTEX_PROP, ATTR_HOST_ONLY);
   
    if (i0 == NULL)
    {
        return -1;
    }

    prop_t *vertexPushinProp = (prop_t*)get_host_mem_pointer(MEM_ID_PUSHIN_PROP);
    int vertexNum = info->vertexNum;
    for (int i = 0; i < info->vertexNum; i++)
    {
        vertexPushinProp[i] = (int)(i0[i] * pop[i] * FIXED_SCALE);
    }
    int alignedVertexNum = get_he_mem(MEM_ID_PUSHIN_PROP)->size / sizeof(int);
    for (int i = vertexNum; i < alignedVertexNum; i++) {
        vertexPushinProp[i]  = 0;
    }

    int * loadedEdgeProp = load_from_csv<int>(DATA_PATH"edge_prop_sir.txt",     MEM_ID_LOAD_EDGE_PROP, ATTR_HOST_ONLY);
    prop_t *edgeProp    = (prop_t*)get_host_mem_pointer(MEM_ID_EDGE_PROP);
    int edgeNum = info->edgeNum;
    for (int i = 0; i < edgeNum; i++)
    {
        edgeProp[i] = loadedEdgeProp[i];
    }
    int alignedEdgeNum = get_he_mem(MEM_ID_EDGE_PROP)->size / sizeof(int);
    for (int i = edgeNum; i < alignedEdgeNum; i++)
    {
        edgeProp[i] = 0;
    }

    prop_t *test = (prop_t*)get_host_mem_pointer(MEM_ID_TEST);
    for (int i = 0; i < info->vertexNum; i++)
    {
        test[i] = vertexPushinProp[i];
    }


    return 0;
}

unsigned int dataPrepareGetArg(graphInfo *info)
{
    return 0;
}

================================================
FILE: application/casir/host_vertex_apply.cpp
================================================
#include "host_graph_sw.h"

#include "fpga_application.h"

#include "host_graph_verification.h"


#include "customize_mem_1.h"
#include "customize_apply_cl_kernel_1.h"





void partitionApplyCModel(
    cl_context              &context,
    cl_device_id            &device,
    int                     superStep,
    int                     partId,
    unsigned int            applyArg
)
{
}


================================================
FILE: application/casir/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__


#define FIXED_SCALE                    (1000000)


/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
    return (srcProp);
}

/* Scatter: return source vertex property "srcProp" as the value of update tuple */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
    return ((srcProp) * (edgeProp));
}

/* Gather: accumulates the update values from source vertices to original values*/
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
    return ((ori) + (update));
}

#endif /* __L2_H__ */


================================================
FILE: application/casir/main.cpp
================================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fstream>

#include "customize_mem_1.h"
#include "host_graph_api.h"
using namespace std;

graphInfo graphDataInfo;

int main(int argc, char **argv) {

    char * xcl_file = NULL;
    if (argc > 1)
    {
        xcl_file = argv[1];
    }

    std::string gName;
    if (argc > 2)
    {
        gName = argv[2];
    }
    else
    {
        gName = "wiki-talk";
    }
    std::string mode = "normal";

    DEBUG_PRINTF("start main\n");

    acceleratorInit("graph_fpga", xcl_file);
    acceleratorDataLoad(gName, mode, &graphDataInfo);
    acceleratorDataPreprocess(&graphDataInfo);

    {
        double startStamp, endStamp;
        startStamp = getCurrentTimestamp();
        acceleratorSuperStep(0, &graphDataInfo);
        endStamp = getCurrentTimestamp();
        DEBUG_PRINTF("exe time : %lf \n", endStamp - startStamp);
    }

    write_back_csv<float>("out_s1.csv", MEM_ID_NEWTHETA_S);
    write_back_csv<float>("out_r1.csv", MEM_ID_NEWTHETA_R);

    acceleratorDeinit();

    return 0;
}


================================================
FILE: application/cc/apply_kernel.mk
================================================


================================================
FILE: application/cc/build.mk
================================================

#scatter-gather kernel
HAVE_EDGE_PROP=false
HAVE_UNSIGNED_PROP=true

#apply kernel
HAVE_APPLY=true
CUSTOMIZE_APPLY=false
HAVE_APPLY_OUTDEG=false

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=false



================================================
FILE: application/cc/config.mk
================================================
FREQ=250

QUEUE_SIZE_FILTER=16
QUEUE_SIZE_MEMORY=512

LOG_SCATTER_CACHE_BURST_SIZE=7

APPLY_REF_ARRAY_SIZE=32


================================================
FILE: application/cc/dataPrepare.cpp
================================================
#include "host_graph_api.h"
#include "fpga_application.h"

#include <cstdlib>
#include <iostream>
#include <ctime>


unsigned int dataPrepareGetArg(graphInfo *info)
{
    return 0;
}

int dataPrepareProperty(graphInfo *info)
{
    std::srand(std::time(nullptr));
    int *vertexPushinProp =      (int*)get_host_mem_pointer(MEM_ID_PUSHIN_PROP);

    int alignedVertexNum = get_he_mem(MEM_ID_PUSHIN_PROP)->size/sizeof(int);

    for (int i = 0; i < alignedVertexNum; i++)
    {
        vertexPushinProp[i]    = 0;
    }
    for (int i = 0; i < 32; i++)
    {
        int select_index  = ((double)std::rand())/((RAND_MAX + 1u)/info->vertexNum);
        vertexPushinProp[select_index] = 1 << i;
    }
    return 0;
}


================================================
FILE: application/cc/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__


#define MAX_PROP                  (INT_MAX - 1)

#define VERTEX_ACTIVE_BIT_MASK    (0x80000000)
#define IS_ACTIVE_VERTEX(a)       (a != 0)

/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
    return ((srcProp));
}

/* source vertex property & edge property */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
    return (srcProp);
}

/* destination property update dst buffer update */
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
    return (ori | update);
}

inline prop_t applyFunc( prop_t tProp,
                         prop_t source,
                         prop_t outDeg,
                         unsigned int (&extra)[APPLY_REF_ARRAY_SIZE],
                         unsigned int arg
                       )
{

    for (int i = 0; i < APPLY_REF_ARRAY_SIZE; i++)
    {
        const prop_t mask = (1 << i);

        if (((source & mask) != mask ) && ((tProp & mask) == mask))
        {
            extra[i] = 1;
        }
        else
        {
            extra[i] = 0;
        }
    }

    return tProp | source;
}

#endif /* __L2_H__ */


================================================
FILE: application/cc/main.cpp
================================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fstream>

#include "host_graph_api.h"
#include "host_graph_verification.h"

using namespace std;

graphInfo graphDataInfo;

int main(int argc, char **argv) {

    char * xcl_file = NULL;
    if (argc > 1)
    {
        xcl_file = argv[1];
    }

    std::string gName;
    if (argc > 2)
    {
        gName = argv[2];
    }
    else
    {
        gName = "wiki-talk";
    }
    std::string mode = "normal";

    DEBUG_PRINTF("start main\n");

    acceleratorInit("graph_fpga", xcl_file);

    acceleratorDataLoad(gName, mode, &graphDataInfo);

    acceleratorDataPreprocess(&graphDataInfo);
    // 10 times for averaging result;
    for (int j = 0; j < 10 ; j ++)
    {
        int runCounter = 0;
        int totalActiveVertices = 1;
        int closenessCentrality[32];

        //random set 32 nodes to calculated their closeness centrality
        reTransferProp(&graphDataInfo);
        for (int i = 0; i < 32; i++)
        {
            closenessCentrality[i] = 0;
        }
        while (totalActiveVertices != 0)
        {
            totalActiveVertices = 0;
            double startStamp, endStamp;
            startStamp = getCurrentTimestamp();

            acceleratorSuperStep(runCounter, &graphDataInfo);

            endStamp = getCurrentTimestamp();

            int *reg = (int *)acceleratorQueryRegister();
            for (int i = 0; i < 32; i++)
            {
                int activeVertices = reg[i];
                totalActiveVertices += activeVertices;
                DEBUG_PRINTF("activeVertice@path_%d : %d \n", i, activeVertices);
            }
            for (int i = 0; i < 32; i++)
            {
                closenessCentrality[i] += reg[i] * runCounter;
            }
            /* profile */
            acceleratorProfile(runCounter, runCounter, &graphDataInfo, endStamp - startStamp);
            runCounter ++;
        }
    }
    //dumpResult(&graphDataInfo);
    acceleratorDeinit();

    return 0;
}



================================================
FILE: application/common.mk
================================================
VAR_TRUE=true

CP = cp -rf
XCLBIN := ./xclbin_$(APP)
DSA := $(call device2sandsa, $(DEVICE))

CXX := $(XILINX_SDX)/bin/xcpp
XOCC := $(XILINX_SDX)/bin/xocc

GS_KERNEL_PATH    = ./tmp_fpga_top
APPLY_KERNEL_PATH = ./tmp_fpga_top



include $(ABS_COMMON_REPO)/utils/opencl.mk



#--kernel_frequency <frequency>
#--xp prop:solution.kernel_compiler_margin=<Frequency Percentage>
#--xp param:compiler.enableAutoFrequencyScaling=0

HOST_SRCS = ./libgraph/misc/graph.cpp ./libgraph/misc/data_helper.cpp

ifeq ($(strip $(DEFAULT_ENTRY)), $(strip $(VAR_TRUE)))
	HOST_SRCS +=  ./libgraph/default_entry.cpp
else
	HOST_SRCS +=  $(APPCONFIG)/main.cpp
endif

HOST_SRCS += ./libgraph/memory/he_mem.cpp
HOST_SRCS += ./libgraph/memory/he_mapping.cpp
HOST_SRCS += ./libgraph/misc/host_graph_mem.cpp
HOST_SRCS += ./libgraph/host_graph_partition.cpp
HOST_SRCS += ./libgraph/kernel/host_graph_kernel.cpp
HOST_SRCS += ./libgraph/host_graph_dataflow.cpp
HOST_SRCS += ./libgraph/scheduler/host_graph_scheduler.cpp
HOST_SRCS += ./libgraph/scheduler/$(SCHEDULER)/scheduler.cpp
HOST_SRCS += $(APPCONFIG)/dataPrepare.cpp
HOST_SRCS += ./libgraph/verification/host_graph_verification_gs.cpp
HOST_SRCS += ./libgraph/verification/host_graph_cmodel.cpp

ifeq ($(strip $(HAVE_APPLY)), $(strip $(VAR_TRUE)))
    ifeq ($(strip $(CUSTOMIZE_APPLY)), $(strip $(VAR_TRUE)))
        HOST_SRCS += $(APPCONFIG)/host_vertex_apply.cpp
    endif
        HOST_SRCS += ./libgraph/verification/host_graph_verification_apply.cpp
endif


# Host compiler global settings
CXXFLAGS :=  $(AUTOGEN_CFLAG) 

CXXFLAGS += $(opencl_CXXFLAGS) -Wall
CXXFLAGS += -I/$(XILINX_SDX)/Vivado_HLS/include/ -O3 -g -fmessage-length=0 -std=c++14 -Wno-deprecated-declarations
CXXFLAGS += -I ./
CXXFLAGS += -I ./libfpga
CXXFLAGS += -I ./libgraph
CXXFLAGS += -I ./libgraph/memory
CXXFLAGS += -I ./libgraph/scheduler
CXXFLAGS += -I ./libgraph/verification
CXXFLAGS += -I ./libgraph/misc
CXXFLAGS += -I ./libgraph/kernel
CXXFLAGS += -I $(APPCONFIG)
CXXFLAGS += -I ./application
CXXFLAGS += -I tmp_para
CXXFLAGS += -I tmp_fpga_top

# Host linker flags
LDFLAGS := $(opencl_LDFLAGS)
LDFLAGS += -lrt -lstdc++  -lxilinxopencl



CLFLAGS := $(AUTOGEN_CFLAG)

ifeq ($(TARGET),$(filter $(TARGET), hw_emu))
CLFLAGS += -g -t $(TARGET)
else
CLFLAGS += -t $(TARGET)
endif

# Kernel compiler global settings
CLFLAGS += --platform $(DEVICE) --save-temps  -O3
CLFLAGS += -I ./
CLFLAGS += -I ./libfpga
CLFLAGS += -I ./libfpga/common
CLFLAGS += -I $(APPCONFIG)
CLFLAGS += -I ./application
CLFLAGS += --xp prop:solution.kernel_compiler_margin=10%

# Kernel linker flags

LDCLFLAGS += --xp prop:solution.kernel_compiler_margin=10% --kernel_frequency=$(FREQ)

EXECUTABLE = host_graph_fpga_$(APP)

EMCONFIG_DIR = $(XCLBIN)/$(DSA)

BINARY_CONTAINERS += $(XCLBIN)/graph_fpga.$(TARGET).$(DSA).xclbin


#Include Libraries

include $(UTILS_PATH)/xcl/xcl.mk
CXXFLAGS +=  $(xcl_CXXFLAGS)
LDFLAGS +=   $(xcl_CXXFLAGS)
HOST_SRCS += $(xcl_SRCS)


#############################################################################
#                                                                           #
#                     Specific Build Configuration                          #
#                                                                           #
#############################################################################


ifeq ($(strip $(HAVE_APPLY)), $(strip $(VAR_TRUE)))
CXXFLAGS += -DHAVE_APPLY=1
else
CXXFLAGS += -DHAVE_APPLY=0
endif


ifeq ($(strip $(HAVE_EDGE_PROP)), $(strip $(VAR_TRUE)))
CXXFLAGS += -DHAVE_EDGE_PROP=1
CLFLAGS  += -DHAVE_EDGE_PROP=1
else
CXXFLAGS += -DHAVE_EDGE_PROP=0
CLFLAGS  += -DHAVE_EDGE_PROP=0
endif


ifeq ($(strip $(HAVE_UNSIGNED_PROP)), $(strip $(VAR_TRUE)))
CXXFLAGS += -DHAVE_UNSIGNED_PROP=1
CLFLAGS  += -DHAVE_UNSIGNED_PROP=1
else
CXXFLAGS += -DHAVE_UNSIGNED_PROP=0
CLFLAGS  += -DHAVE_UNSIGNED_PROP=0
endif


ifeq ($(strip $(HAVE_APPLY_OUTDEG)), $(strip $(VAR_TRUE)))
CXXFLAGS += -DHAVE_APPLY_OUTDEG=1
CLFLAGS  += -DHAVE_APPLY_OUTDEG=1
else
CXXFLAGS += -DHAVE_APPLY_OUTDEG=0
CLFLAGS  += -DHAVE_APPLY_OUTDEG=0
endif



ifeq ($(strip $(CUSTOMIZE_APPLY)), $(strip $(VAR_TRUE)))
CXXFLAGS += -DCUSTOMIZE_APPLY=1
CLFLAGS  += -DCUSTOMIZE_APPLY=1
else
CXXFLAGS += -DCUSTOMIZE_APPLY=0
CLFLAGS  += -DCUSTOMIZE_APPLY=0
endif


#############################################################################
#                                                                           #
#                     Specific Configuration                                #
#                                                                           #
#############################################################################

## for hardware
CLFLAGS  += -DQUEUE_SIZE_FILTER=$(QUEUE_SIZE_FILTER)
CLFLAGS  += -DQUEUE_SIZE_MEMORY=$(QUEUE_SIZE_MEMORY)
CLFLAGS  += -DLOG_SCATTER_CACHE_BURST_SIZE=$(LOG_SCATTER_CACHE_BURST_SIZE)


CLFLAGS  += -DAPPLY_REF_ARRAY_SIZE=$(APPLY_REF_ARRAY_SIZE)
CXXFLAGS  += -DAPPLY_REF_ARRAY_SIZE=$(APPLY_REF_ARRAY_SIZE)


ifdef TARGET_PARTITION_SIZE
CLFLAGS  += -DTARGET_PARTITION_SIZE=$(TARGET_PARTITION_SIZE)
CXXFLAGS  += -DTARGET_PARTITION_SIZE=$(TARGET_PARTITION_SIZE)

endif


================================================
FILE: application/global_config.h
================================================
#ifndef __GLOBAL_CONFIG_H__
#define __GLOBAL_CONFIG_H__

#include <climits>
#include <math.h>


#if HAVE_UNSIGNED_PROP
typedef  unsigned int       prop_t;
#else
typedef  int                prop_t;
#endif

#ifdef TARGET_PARTITION_SIZE
#undef PARTITION_SIZE
#define PARTITION_SIZE  (TARGET_PARTITION_SIZE)
#endif
#define MAX_VERTICES_IN_ONE_PARTITION           (PARTITION_SIZE)

#define ENDFLAG                                 0xffffffff

#define LOG_BURSTBUFFERSIZE     (7)
#define BURSTBUFFERSIZE         (1<<7)
#define ALIGN_SIZE              (BURSTBUFFERSIZE * 16)

//#define SW_DEBUG

#define CAHCE_FETCH_DEBUG       (0)





#endif /* __GLOBAL_CONFIG_H__ */


================================================
FILE: application/para_check.h
================================================
#ifndef __PARA_CHECK__
#define __PARA_CHECK__

#ifndef SUB_PARTITION_NUM
#error "SUB_PARTITION_NUM is not define! please check the ThunderGP para_gen."
#endif

#ifndef PARTITION_SIZE
#error "PARTITION_SIZE is not define! please check the ThunderGP para_gen."
#endif

#endif /* __PARA_CHECK__ */


================================================
FILE: application/pr/apply_kernel.mk
================================================


================================================
FILE: application/pr/build.mk
================================================

#scatter-gather kernel
HAVE_EDGE_PROP=false
HAVE_UNSIGNED_PROP=false

#apply kernel
HAVE_APPLY=true
CUSTOMIZE_APPLY=false
HAVE_APPLY_OUTDEG=true

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=true


================================================
FILE: application/pr/config.mk
================================================
FREQ=280

QUEUE_SIZE_FILTER=16
QUEUE_SIZE_MEMORY=512

LOG_SCATTER_CACHE_BURST_SIZE=6

APPLY_REF_ARRAY_SIZE=1


================================================
FILE: application/pr/dataPrepare.cpp
================================================
#include "host_graph_api.h"
#include "fpga_application.h"

#define INT2FLOAT                   (pow(2,30))

int float2int(float a) {
    return (int)(a * INT2FLOAT);
}

float int2float(int a) {
    return ((float)a / INT2FLOAT);
}

unsigned int dataPrepareGetArg(graphInfo *info)
{
    return float2int((1.0f - kDamp) / info->vertexNum);
}

int dataPrepareProperty(graphInfo *info)
{
    int *tempPropValue   =  (int*)get_host_mem_pointer(MEM_ID_PROP_FOR_DATAPREPARE);
    int *outDeg          =  (int*)get_host_mem_pointer(MEM_ID_OUT_DEG_ORIGIN);
    prop_t *vertexPushinProp = (prop_t*)get_host_mem_pointer(MEM_ID_PUSHIN_PROP);

    int vertexNum = info->vertexNum;
    int alignedVertexNum = get_he_mem(MEM_ID_PUSHIN_PROP)->size/sizeof(int);

    float init_score_float = 1.0f / vertexNum;
    int init_score_int = float2int(init_score_float);


    for (int i = 0; i < vertexNum; i++) {
        tempPropValue[i] = init_score_int;
        if (outDeg[i] > 0)
        {
            vertexPushinProp[i] =  tempPropValue[i] / outDeg[i];
        }
        else
        {
            vertexPushinProp[i]  = 0;
        }
    }

    for (int i = vertexNum; i < alignedVertexNum; i++) {
        vertexPushinProp[i]  = 0;
    }
    return 0;
}

================================================
FILE: application/pr/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__


#define kDamp               (0.85f)
#define kDampFixPoint       108//(0.85 << 7)  // * 128

/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
	return (srcProp);
}

/* source vertex property & edge property */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
	return (srcProp);
}

/* destination property update dst buffer update */
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
	return ((ori) + (update));
}

inline prop_t applyFunc( prop_t tProp,
                                prop_t source,
                                prop_t outDeg,
                                unsigned int (&extra)[APPLY_REF_ARRAY_SIZE],
                                unsigned int arg
                              )
{

	prop_t old_score = source;
	prop_t new_score = arg  + ((kDampFixPoint * tProp) >> 7);
	prop_t tmp;
	if (outDeg != 0)
	{
		tmp = (1 << 16 ) / outDeg;
	}
	else
	{
		tmp = 0;
	}

	prop_t update = (new_score * tmp) >> 16;

	extra[0] = (new_score - old_score) > 0 ? (new_score - old_score) : (old_score - new_score) ;

	return update;
}
#endif /* __L2_H__ */


================================================
FILE: application/spmv/apply_kernel.mk
================================================


================================================
FILE: application/spmv/build.mk
================================================

#scatter-gather kernel
HAVE_EDGE_PROP=true
HAVE_UNSIGNED_PROP=false

#apply kernel
HAVE_APPLY=false
CUSTOMIZE_APPLY=false
HAVE_APPLY_OUTDEG=false

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=true


================================================
FILE: application/spmv/config.mk
================================================
FREQ=250

QUEUE_SIZE_FILTER=32
QUEUE_SIZE_MEMORY=512

LOG_SCATTER_CACHE_BURST_SIZE=7

APPLY_REF_ARRAY_SIZE=1


================================================
FILE: application/spmv/dataPrepare.cpp
================================================
#include "host_graph_api.h"


unsigned int dataPrepareGetArg(graphInfo *info)
{
	return 0;
}

int dataPrepareProperty(graphInfo *info)
{
	prop_t *vertexPushinProp =      (prop_t*)get_host_mem_pointer(MEM_ID_PUSHIN_PROP);

	int alignedVertexNum = get_he_mem(MEM_ID_PUSHIN_PROP)->size/sizeof(int);

	for (int i = 0; i < alignedVertexNum; i++) {
		vertexPushinProp[i]    = i;
	}
	 prop_t *edgeProp    = (prop_t*)get_host_mem_pointer(MEM_ID_EDGE_PROP);

	//int edgeNum = info->edgeNum;
	int alignedEdgeNum = get_he_mem(MEM_ID_EDGE_PROP)->size/sizeof(int);

	for (int i = 0; i < alignedEdgeNum; i++)
	{
		edgeProp[i] = i;
	}


	return 0;
}

================================================
FILE: application/spmv/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__

/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
    return (srcProp);
}

/* source vertex property & edge property */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
    return ((srcProp) * (edgeProp));
}

/* destination property update dst buffer update */
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
    return ((ori) + (update));
}

inline prop_t applyFunc( prop_t tProp,
                                prop_t source,
                                prop_t outDeg,
                                unsigned int (&extra)[APPLY_REF_ARRAY_SIZE],
                                unsigned int arg
                              )
{
    return tProp;
}


#endif /* __L2_H__ */


================================================
FILE: application/sssp/apply_kernel.mk
================================================


================================================
FILE: application/sssp/build.mk
================================================

#scatter-gather kernel
HAVE_EDGE_PROP=true
HAVE_UNSIGNED_PROP=true

#apply kernel
HAVE_APPLY=true
CUSTOMIZE_APPLY=false
HAVE_APPLY_OUTDEG=false

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=true


================================================
FILE: application/sssp/config.mk
================================================
FREQ=250

QUEUE_SIZE_FILTER=16
QUEUE_SIZE_MEMORY=512

LOG_SCATTER_CACHE_BURST_SIZE=6

APPLY_REF_ARRAY_SIZE=1


================================================
FILE: application/sssp/dataPrepare.cpp
================================================
#include "host_graph_api.h"
#include "fpga_application.h"

unsigned int dataPrepareGetArg(graphInfo *info)
{
    return 0;
}

int dataPrepareProperty(graphInfo *info)
{
    int *vertexPushinProp =      (int*)get_host_mem_pointer(MEM_ID_PUSHIN_PROP);

    int alignedVertexNum = get_he_mem(MEM_ID_PUSHIN_PROP)->size / sizeof(int);

    for (int i = 0; i < alignedVertexNum; i++)
    {
        vertexPushinProp[i]    = MAX_PROP;
    }
    prop_t *edgeProp    = (prop_t*)get_host_mem_pointer(MEM_ID_EDGE_PROP);

    //int edgeNum = info->edgeNum;
    int alignedEdgeNum = get_he_mem(MEM_ID_EDGE_PROP)->size / sizeof(int);

    for (int i = 0; i < alignedEdgeNum; i++)
    {
        edgeProp[i] = i % 16;
    }
    int select_index  = ((double)std::rand()) / ((RAND_MAX + 1u) / info->vertexNum);
    vertexPushinProp[select_index] = 0x80000001;

    return 0;
}

================================================
FILE: application/sssp/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__


#define MAX_PROP                  (INT_MAX - 1)

#define VERTEX_ACTIVE_BIT_MASK    (0x80000000)
#define IS_ACTIVE_VERTEX(a)       ((((((a) & VERTEX_ACTIVE_BIT_MASK) == VERTEX_ACTIVE_BIT_MASK))) ? 1 : 0)

/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
    return (srcProp);
}

/* source vertex property & edge property */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
    if((srcProp & VERTEX_ACTIVE_BIT_MASK) == VERTEX_ACTIVE_BIT_MASK)
      return ((srcProp) + (edgeProp));
    else
      return (srcProp);
}

/* destination property update dst buffer update */
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
    return (
               (
                   (
                       (((ori) & (~VERTEX_ACTIVE_BIT_MASK)) > ((update) & (~VERTEX_ACTIVE_BIT_MASK)))
                       && (update != 0)
                   )
                   || (ori == 0x0)
               ) ? (update) : (ori)
           );
}

inline prop_t applyFunc( prop_t tProp,
                                prop_t source,
                                prop_t outDeg,
                                unsigned int (&extra)[APPLY_REF_ARRAY_SIZE],
                                unsigned int arg
                              )
{
    prop_t update = 0;

    prop_t uProp  = source;
    prop_t wProp;
    if (((tProp & VERTEX_ACTIVE_BIT_MASK) == VERTEX_ACTIVE_BIT_MASK) && (uProp == MAX_PROP))
    {
        extra[0] = 1;
        wProp = tProp; // current active vertex, not travsered
    }
    else
    {
        extra[0] = 0;
        wProp = uProp & 0x7fffffff; // not travsered
    }
    update = wProp;

    return update;
}


#endif /* __L2_H__ */


================================================
FILE: application/template/apply_kernel.mk
================================================


================================================
FILE: application/template/build.mk
================================================
# Need modification !

#scatter-gather kernel
HAVE_EDGE_PROP=true/false
HAVE_UNSIGNED_PROP=true/false

#apply kernel
HAVE_APPLY=true/false
CUSTOMIZE_APPLY=true/false
HAVE_APPLY_OUTDEG=true/false

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=true



================================================
FILE: application/template/config.mk
================================================


================================================
FILE: application/template/host_vertex_apply.cpp
================================================
#include "host_graph_sw.h"

#include "fpga_application.h"

#include "host_graph_verification.h"


void setApplyKernel(cl_kernel &kernel_apply, int partId, int vertexNum)
{

}


void partitionApplyCModel(
    cl_context              &context,
    cl_device_id            &device,
    int                     partId,
    unsigned int            argReg
)
{
}






================================================
FILE: application/template/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__

/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
    return 0;
}

/* source vertex property & edge property */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
    return 0;
}

/* destination property update in RAW solver */
inline prop_t updateMergeInRAWSolver(prop_t ori, prop_t update)
{
    return 0;
}

/* destination property update dst buffer update */
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
    return 0;
}


#endif /* __L2_H__ */


================================================
FILE: application/template/vertex_apply.cpp
================================================
#include <hls_stream.h>
#include <string.h>
#include "graph_fpga.h"


#include "fpga_global_mem.h"


void apply(
    int                             loopNum,
    hls::stream<burst_raw>          &outDegreeStream,
    hls::stream<burst_raw>          &vertexPropStream,
    hls::stream<burst_raw>          &tmpVertexPropStream,
    unsigned int                    baseScore ,
    hls::stream<burst_raw>          &newVertexPropStream,
    int                             *error
)
{
    int error_l[BURST_ALL_BITS / INT_WIDTH];
#pragma HLS ARRAY_PARTITION variable=error_l dim=0 complete
    for (int i = 0; i < BURST_ALL_BITS / INT_WIDTH; i++)
    {
        error_l[i] = 0;
    }
    for (int loopCount = 0; loopCount < loopNum; loopCount ++)
    {

#pragma HLS PIPELINE II=1
        burst_raw vertexProp;
        burst_raw tmpVertexProp;
        burst_raw outDeg;
        read_from_stream(vertexPropStream, vertexProp);
        read_from_stream(tmpVertexPropStream, tmpVertexProp);
        read_from_stream(outDegreeStream, outDeg);


        burst_raw newVertexProp;

        for (int i = 0; i < BURST_ALL_BITS / INT_WIDTH; i++)
        {
#pragma HLS UNROLL
            int tProp     = tmpVertexProp.range((i + 1) * INT_WIDTH - 1, i * INT_WIDTH );
            int old_score = vertexProp.range(   (i + 1) * INT_WIDTH - 1, i * INT_WIDTH );
            int new_score = baseScore  + ((kDampFixPoint * tProp) >> 7);
            int out_deg   = outDeg.range(       (i + 1) * INT_WIDTH - 1, i * INT_WIDTH );
            int update = 0;
            if (out_deg != 0)
            {
                update = new_score / out_deg;
            }
            else
            {
                update = 0;
            }

            newVertexProp.range((i + 1) * INT_WIDTH - 1, i * INT_WIDTH ) = update;
            //debug[i] = (new_score - old_score) > 0 ? (new_score - old_score) : (old_score - new_score);
            error_l[i] += (new_score - old_score) > 0 ? (new_score - old_score) : (old_score - new_score) ;
        }
        write_to_stream(newVertexPropStream, newVertexProp);

    }
    int total_error = 0;

    for (int i = 0; i < BURST_ALL_BITS / INT_WIDTH; i ++)
    {
        DEBUG_PRINTF("error_l %d %d \n", i, error_l[i]);
        total_error += error_l[i];
    }
    error[0] = total_error;

}




extern "C" {
    void  vertexApply(
        uint16        *vertexProp,
        uint16        *tmpVertexProp1,
        uint16        *tmpVertexProp2,
        uint16        *tmpVertexProp3,
        uint16        *tmpVertexProp4,
        uint16        *newVertexProp1,
        uint16        *newVertexProp2,
        uint16        *newVertexProp3,
        uint16        *newVertexProp4,
        uint16        *outDegree,
        int           *error,
        unsigned int  vertexNum,
        unsigned int  addrOffset,
        unsigned int  baseScore
    )
    {



        /* cu1 */
#pragma HLS INTERFACE m_axi port=tmpVertexProp1 offset=slave bundle=gmem1 max_read_burst_length=64 num_write_outstanding=4
#pragma HLS INTERFACE s_axilite port=tmpVertexProp1 bundle=control

#pragma HLS INTERFACE m_axi port=newVertexProp1 offset=slave bundle=gmem1 max_read_burst_length=64 num_write_outstanding=4
#pragma HLS INTERFACE s_axilite port=newVertexProp1 bundle=control


        /* cu2 */
#pragma HLS INTERFACE m_axi port=tmpVertexProp2 offset=slave bundle=gmem2 max_read_burst_length=64 num_write_outstanding=4
#pragma HLS INTERFACE s_axilite port=tmpVertexProp2 bundle=control

#pragma HLS INTERFACE m_axi port=newVertexProp2 offset=slave bundle=gmem2 max_read_burst_length=64 num_write_outstanding=4
#pragma HLS INTERFACE s_axilite port=newVertexProp2 bundle=control


        /* cu3 */
#pragma HLS INTERFACE m_axi port=tmpVertexProp3 offset=slave bundle=gmem3 max_read_burst_length=64 num_write_outstanding=4
#pragma HLS INTERFACE s_axilite port=tmpVertexProp3 bundle=control

#pragma HLS INTERFACE m_axi port=newVertexProp3 offset=slave bundle=gmem3 max_read_burst_length=64 num_write_outstanding=4
#pragma HLS INTERFACE s_axilite port=newVertexProp3 bundle=control


        /* cu4 */
#pragma HLS INTERFACE m_axi port=tmpVertexProp4 offset=slave bundle=gmem4 max_read_burst_length=64 num_write_outstanding=4
#pragma HLS INTERFACE s_axilite port=tmpVertexProp4 bundle=control

#pragma HLS INTERFACE m_axi port=newVertexProp4 offset=slave bundle=gmem4 max_read_burst_length=64 num_write_outstanding=4
#pragma HLS INTERFACE s_axilite port=newVertexProp4 bundle=control



#pragma HLS INTERFACE m_axi port=error offset=slave bundle=gmem5
#pragma HLS INTERFACE s_axilite port=error bundle=control


#pragma HLS INTERFACE m_axi port=vertexProp offset=slave bundle=gmem6 max_read_burst_length=64
#pragma HLS INTERFACE s_axilite port=vertexProp bundle=control


#pragma HLS INTERFACE m_axi port=outDegree offset=slave bundle=gmem7 max_read_burst_length=64 
#pragma HLS INTERFACE s_axilite port=outDegree bundle=control


#pragma HLS INTERFACE s_axilite port=vertexNum      bundle=control
#pragma HLS INTERFACE s_axilite port=baseScore      bundle=control
#pragma HLS INTERFACE s_axilite port=addrOffset     bundle=control
#pragma HLS INTERFACE s_axilite port=return         bundle=control

#pragma HLS DATAFLOW

        hls::stream<burst_raw>      vertexPropStream;
#pragma HLS stream variable=vertexPropStream depth=128

        hls::stream<burst_raw>      tmpVertexPropArray[4];
#pragma HLS stream variable=tmpVertexPropArray depth=2


        hls::stream<burst_raw>      tmpVertexPropStream;
#pragma HLS stream variable=tmpVertexPropStream depth=128

        hls::stream<burst_raw>      outDegreeStream;
#pragma HLS stream variable=outDegreeStream depth=256


        hls::stream<burst_raw>      newVertexPropStream;
#pragma HLS stream variable=newVertexPropStream depth=128

        hls::stream<burst_raw>      newVertexPropArray[4];
#pragma HLS stream variable=newVertexPropArray depth=2

        int loopNum = (vertexNum >> 4) ;



        burstReadLite(addrOffset, vertexNum, vertexProp, vertexPropStream);
        burstReadLite(addrOffset, vertexNum, outDegree, outDegreeStream);


        burstReadLite(0, vertexNum, tmpVertexProp1, tmpVertexPropArray[0]);
        burstReadLite(0, vertexNum, tmpVertexProp2, tmpVertexPropArray[1]);
        burstReadLite(0, vertexNum, tmpVertexProp3, tmpVertexPropArray[2]);
        burstReadLite(0, vertexNum, tmpVertexProp4, tmpVertexPropArray[3]);

        cuMerge(loopNum, tmpVertexPropArray, tmpVertexPropStream);

        apply(
            loopNum,
            outDegreeStream,
            vertexPropStream,
            tmpVertexPropStream,
            baseScore,
            newVertexPropStream,
            error
        );

        cuDuplicate(loopNum , newVertexPropStream,
                    newVertexPropArray);

        writeBackLite(vertexNum, newVertexProp1 + (addrOffset >> 4), newVertexPropArray[0]);
        writeBackLite(vertexNum, newVertexProp2 + (addrOffset >> 4), newVertexPropArray[1]);
        writeBackLite(vertexNum, newVertexProp3 + (addrOffset >> 4), newVertexPropArray[2]);
        writeBackLite(vertexNum, newVertexProp4 + (addrOffset >> 4), newVertexPropArray[3]);

    }

}


================================================
FILE: application/wcc/apply_kernel.mk
================================================


================================================
FILE: application/wcc/build.mk
================================================

#scatter-gather kernel
HAVE_EDGE_PROP=false
HAVE_UNSIGNED_PROP=true

#apply kernel
HAVE_APPLY=true
CUSTOMIZE_APPLY=false
HAVE_APPLY_OUTDEG=false

#scheduler
SCHEDULER=secondOrderEstimator

#entry
DEFAULT_ENTRY=true



================================================
FILE: application/wcc/config.mk
================================================
FREQ=250

QUEUE_SIZE_FILTER=32
QUEUE_SIZE_MEMORY=512

LOG_SCATTER_CACHE_BURST_SIZE=7

APPLY_REF_ARRAY_SIZE=1


================================================
FILE: application/wcc/dataPrepare.cpp
================================================
#include "host_graph_api.h"
#include "fpga_application.h"

#include <cstdlib>
#include <iostream>
#include <ctime>

unsigned int dataPrepareGetArg(graphInfo *info)
{
    return 0;
}

int dataPrepareProperty(graphInfo *info)
{
    int *vertexPushinProp =      (int*)get_host_mem_pointer(MEM_ID_PUSHIN_PROP);

    int alignedVertexNum = get_he_mem(MEM_ID_PUSHIN_PROP)->size/sizeof(int);

    for (int i = 0; i < alignedVertexNum; i++)
    {
        vertexPushinProp[i]    = 0;
    }
    int select_index  = ((double)std::rand()) / ((RAND_MAX + 1u) / info->vertexNum);
    vertexPushinProp[select_index] = 1;
    return 0;
}

================================================
FILE: application/wcc/l2.h
================================================
#ifndef __L2_H__
#define __L2_H__


/*
    Reference the mapping method in TABLE 1 from hitgraph:
    Zhou, Shijie, et al. "HitGraph: High-throughput graph processing framework on FPGA."
    IEEE Transactions on Parallel and Distributed Systems 30.10 (2019): 2249-2264.

    but we change the min operation to max, for the initialization of BRAM is zero.
    Therefore, do not need another memory interface to reload data from DRAM.
    Note: this implementation ONLY for performance comparison!
*/


/* source vertex property process */
inline prop_t preprocessProperty(prop_t srcProp)
{
    return (srcProp);
}

/* source vertex property & edge property */
inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
{
    return (srcProp);
}

/* destination property update dst buffer update */
inline prop_t gatherFunc(prop_t ori, prop_t update)
{
    return (update > ori) ? update : ori;
}


inline prop_t applyFunc( prop_t tProp,
                                prop_t source,
                                prop_t outDeg,
                                unsigned int (&extra)[APPLY_REF_ARRAY_SIZE],
                                unsigned int arg
                              )
{
    return tProp;
}

#endif /* __L2_H__ */


================================================
FILE: automation/auto_gen_code.mk
================================================
include ThunderGP.mk

CODE_GEN_PATH   =./automation
CODE_GEN_PARSER_PATH  = $(CODE_GEN_PATH)/parser
CODE_GEN_FILE =  $(CODE_GEN_PATH)/parser.cpp
CODE_GEN_FILE += $(CODE_GEN_PATH)/parser_debug.cpp
CODE_GEN_FILE += $(CODE_GEN_PARSER_PATH)/mem_interface.cpp
CODE_GEN_FILE += $(CODE_GEN_PARSER_PATH)/kernel_interface.cpp
CODE_GEN_FILE += $(CODE_GEN_PARSER_PATH)/customize.cpp
CODE_GEN_FILE += $(CODE_GEN_PARSER_PATH)/makefile.cpp


# AUTOGEN_CFLAG in here:
include tmp_para/para.mk


INCLUDE_FLAG =  -I application
INCLUDE_FLAG += -I libgraph
INCLUDE_FLAG += -I $(CODE_GEN_PATH)
INCLUDE_FLAG += -I $(CODE_GEN_PARSER_PATH)


VAR_TRUE=true
APP = $(app)
APPCONFIG = ./application/$(APP)
include $(APPCONFIG)/build.mk

.PHONY: code_gen
code_gen:

	rm -rf tmp_fpga_top
	mkdir -p tmp_fpga_top
	g++  -static-libstdc++ $(INCLUDE_FLAG) $(AUTOGEN_CFLAG) $(CODE_GEN_FILE) -o code_gen
	./code_gen libfpga/common_template/apply_top.cpp             tmp_fpga_top/apply_top
	./code_gen libfpga/common_template/scatter_gather_top.cpp    tmp_fpga_top/scatter_gather_top
ifndef app
	$(error app is undefined)
else
ifeq ($(strip $(CUSTOMIZE_APPLY)), $(strip $(VAR_TRUE)))
	./code_gen libfpga/customize_template/customize_apply_top.cpp        application/$(app)/customized_apply.cpp  tmp_fpga_top/customize_apply_top
	./code_gen libfpga/customize_template/customize_mem.h                application/$(app)/customized_apply.cpp  tmp_fpga_top/customize_mem
	./code_gen libfpga/customize_template/customize_apply_cl_kernel.h    application/$(app)/customized_apply.cpp  tmp_fpga_top/customize_apply_cl_kernel
endif
endif


================================================
FILE: automation/auto_gen_makefile.mk
================================================
include ThunderGP.mk

CODE_GEN_PATH  =./automation
CODE_GEN_FILE  =  $(CODE_GEN_PATH)/makefile_gen.cpp
CODE_GEN_FILE += -I libgraph/
# AUTOGEN_CFLAG in here:
include tmp_para/para.mk


VAR_TRUE=true
APP = $(app)
APPCONFIG = ./application/$(APP)
include $(APPCONFIG)/build.mk

.PHONY: makefile_gen
makefile_gen:
	rm -f tmp_fpga_top/*.mk
	mkdir -p tmp_fpga_top
	g++  -static-libstdc++ -I application $(AUTOGEN_CFLAG) $(CODE_GEN_FILE) -o makefile_gen
	./makefile_gen
	
ifndef app
	$(error app is undefined)
else
ifeq ($(strip $(CUSTOMIZE_APPLY)), $(strip $(VAR_TRUE)))
	./code_gen libfpga/customize_template/customize_apply_kernel.mk   application/$(app)/customized_apply.cpp tmp_fpga_top/apply_kernel
else
	./code_gen libfpga/common_template/apply_kernel.mk                tmp_fpga_top/apply_kernel
endif
endif


================================================
FILE: automation/auto_gen_parameters.mk
================================================
include ThunderGP.mk

CODE_GEN_PATH  =./automation
PARA_GEN_CFLAGS := -I $(CODE_GEN_PATH)/devices
PARA_GEN_CFLAGS += -DDEVICE_HEADER="$(DEVICES).h"
PARA_GEN_CFLAGS += -I libgraph/



.PHONY: auto_para para_gen tmp_para/para.mk
auto_para: tmp_para/para.mk

VAR_TRUE=true
APP = $(app)
APPCONFIG = ./application/$(APP)
include $(APPCONFIG)/build.mk

PARA_GEN_CFLAGS += -DTARGET_BANDWIDTH=$(TARGET_BANDWIDTH)

para_gen:
	rm -rf para_gen
	rm -rf tmp_para
	mkdir -p tmp_para
	g++  -g -static-libstdc++  $(PARA_GEN_CFLAGS)   ./automation/para_gen.cpp -o para_gen

tmp_para/para.mk: para_gen
	./para_gen
	rm -rf code_gen


================================================
FILE: automation/devices/device_common.h
================================================
#ifndef __DEVICE_COMMON_H__
#define __DEVICE_COMMON_H__

typedef struct 
{
	int slr_id;
	int luts;
	int ffs;
	int dsp;
	int bram;
	int uram;
	int mem_chns;
} slr_resource_info_t;


#endif /* __DEVICE_COMMON_H__ */


================================================
FILE: automation/devices/xilinx_u200_xdma_201830_2.h
================================================
#include "device_common.h"

const char * board_name = "u200";

const slr_resource_info_t slrs[] =
{
    {
        .slr_id  = 0,
        .luts    = 354831,
        .ffs     = 723372,
        .dsp     = 2265,
        .bram    = 638,
        .uram    = 320,
        .mem_chns= 1,
    },
    {
        .slr_id  = 1,
        .luts    = 159854,
        .ffs     = 331711,
        .dsp     = 1317,
        .bram    = 326,
        .uram    = 160,
        .mem_chns= 2,
    },
    {
        .slr_id  = 2,
        .luts    = 354962,
        .ffs     = 723353,
        .dsp     = 2265,
        .bram    = 638,
        .uram    = 320,
        .mem_chns= 1,
    },
};

const int mem_cu_map[] =
{
    0, 1, 1, 2
};

const int platform_memory_bandwidth_per_channel = 19;


================================================
FILE: automation/devices/xilinx_u250_xdma_201830_2.h
================================================
#include "device_common.h"

const char * board_name = "u250";

const slr_resource_info_t slrs[] =
{
    {
        .slr_id  = 0,
        .luts    = 345171,
        .ffs     = 704801,
        .dsp     = 2877,
        .bram    = 500,
        .uram    = 320,
        .mem_chns= 1,
    },
    {
        .slr_id  = 1,
        .luts    = 344533,
        .ffs     = 702517,
        .dsp     = 2877,
        .bram    = 500,
        .uram    = 320,
        .mem_chns= 1,
    },
    {
        .slr_id  = 2,
        .luts    = 344878,
        .ffs     = 703253,
        .dsp     = 2877,
        .bram    = 500,
        .uram    = 320,
        .mem_chns= 1,
    },
    {
        .slr_id  = 3,
        .luts    = 345158,
        .ffs     = 703761,
        .dsp     = 2877,
        .bram    = 500,
        .uram    = 320,
        .mem_chns= 1,
    },
};

const int mem_cu_map[] =
{
    0, 1, 2, 3
};

const int platform_memory_bandwidth_per_channel = 19;


================================================
FILE: automation/devices/xilinx_vcu1525_xdma_201830_1.h
================================================
#include "device_common.h"

const char * board_name = "vcu1525";

const slr_resource_info_t slrs[] =
{
    {
        .slr_id  = 0,
        .luts    = 354830,
        .ffs     = 723371,
        .dsp     = 2265,
        .bram    = 638,
        .uram    = 320,
        .mem_chns= 1,
    },
    {
        .slr_id  = 1,
        .luts    = 159088,
        .ffs     = 329162,
        .dsp     = 1317,
        .bram    = 326,
        .uram    = 160,
        .mem_chns= 2,
    },
    {
        .slr_id  = 2,
        .luts    = 354934,
        .ffs     = 723328,
        .dsp     = 2265,
        .bram    = 638,
        .uram    = 320,
        .mem_chns= 1,
    },
};

const int mem_cu_map[] =
{
    0, 1, 1, 2
};

const int platform_memory_bandwidth_per_channel = 19;


================================================
FILE: automation/makefile_gen.cpp
================================================
#include <cmath>
#include <cstdio>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>

#include "common.h"
#include "para_check.h"

/* TODO: remove hard-code */
/* only generate the makefile of scatter-gather kernels */
/* the makefile of apply kernel is generated by code_gen in parser/customize.cpp  */

int main(int argc, char **argv) {
    std::ofstream file;
    file.open("./tmp_fpga_top/gs_kernel.mk");
    for (int i = 0; i < SUB_PARTITION_NUM; i ++)
    {
        file << "############# gs " << (i + 1) << " #############" << std::endl;
        file << "$(XCLBIN)/readEdgesCU" << (i + 1)
             << ".$(TARGET).$(DSA).xo: $(GS_KERNEL_PATH)/scatter_gather_top_"
             << (i + 1) << ".cpp" << std::endl;
        file << "\tmkdir -p $(XCLBIN)" << std::endl;
        file << "\t$(XOCC) $(CLFLAGS) -c -k readEdgesCU" << (i + 1) << " -I'$(<D)' -o'$@' '$<'" << std::endl;
        file << "BINARY_CONTAINER_OBJS += $(XCLBIN)/readEdgesCU" << (i + 1) << ".$(TARGET).$(DSA).xo" << std::endl;
        file << "BINARY_LINK_OBJS    += --nk  readEdgesCU" << (i + 1) << ":1" << std::endl;
        file << "BINARY_LINK_OBJS    += --sp  readEdgesCU" << (i + 1) << "_1.edgesHeadArray:DDR[$(GS" << (i + 1) << "_DDR)]" << std::endl;
        file << "BINARY_LINK_OBJS    += --sp  readEdgesCU" << (i + 1) << "_1.edgesTailArray:DDR[$(GS" << (i + 1) << "_DDR)]" << std::endl;
        file << "BINARY_LINK_OBJS    += --sp  readEdgesCU" << (i + 1) << "_1.vertexPushinProp:DDR[$(GS" << (i + 1) << "_DDR)]" << std::endl;
        file << "BINARY_LINK_OBJS    += --sp  readEdgesCU" << (i + 1) << "_1.tmpVertexProp:DDR[$(GS" << (i + 1) << "_DDR)]" << std::endl;
        file << "ifeq ($(strip $(HAVE_EDGE_PROP)), $(strip $(VAR_TRUE)))" << std::endl;
        file << "BINARY_LINK_OBJS    += --sp  readEdgesCU" << (i + 1) << "_1.edgeProp:DDR[$(GS" << (i + 1) << "_DDR)]" << std::endl;
        file << "endif" << std::endl;
        file << "BINARY_LINK_OBJS    += --slr readEdgesCU" << (i + 1) << "_1:SLR$(GS" << (i + 1) << "_SLR)" << std::endl;
    }
    file.flush();
    file.close();

    return 0;
}


================================================
FILE: automation/para_gen.cpp
================================================
#include <cmath>
#include <cstdio>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>

#include "common.h"
#include "device_common.h"

#ifndef DEVICE_HEADER
#error  "board name miss!"
#endif

#ifndef TARGET_BANDWIDTH
#error "TARGET_BANDWIDTH do not defined!"
#endif

#include STRINGIFY_MACRO(EXPAND(DEVICE_HEADER))

#define SCATTER_URAM_COST               (40)
#define URAM_CAPACITY                   (8192)
#define MAX_SUPPROTED_KERNEL            (128)
#define URAM_UPBOUND                    (0.9f)

typedef struct
{
    int uram;
    int luts;
    int id;
    int mem_chn;
} slr_info_t;

using namespace std;

int partition_size = 0;
int kernel_num = 0;

std::vector<int> kernel_mapping;
int apply_mapping = 0;

std::vector<int> memory_mapping;

int main(int argc, char **argv) {
    std::ofstream file;
    file.open("./tmp_para/para.mk");
    std::vector<slr_info_t> slr_ordered;
    DEBUG_PRINTF("board: %s \n", board_name);
    int max_bw_required = 0;
    int platform_max_memory_bandwidth = platform_memory_bandwidth_per_channel * ARRAY_SIZE(mem_cu_map);
    if (TARGET_BANDWIDTH > platform_max_memory_bandwidth)
    {
        max_bw_required = platform_max_memory_bandwidth;
    }
    else
    {
        max_bw_required = TARGET_BANDWIDTH;
    }

    int channel_num = max_bw_required / platform_memory_bandwidth_per_channel + 1;

    if (channel_num > ARRAY_SIZE(mem_cu_map))
    {
        channel_num = ARRAY_SIZE(mem_cu_map);
    }
    DEBUG_PRINTF("\t targeted memory bandwidth: %d GB/s\n", max_bw_required);
    DEBUG_PRINTF("\t utilzated memory channel: %d/%ld\n",
                 channel_num, ARRAY_SIZE(mem_cu_map));

    /* partition size */
    int max_avaliable_uram = 0;
    int max_gather_uram = 0;
    for (int i = 0; i < ARRAY_SIZE(slrs); i++)
    {
        if (max_avaliable_uram < slrs[i].uram)
        {
            max_avaliable_uram = slrs[i].uram;
        }
    }
    max_gather_uram = max_avaliable_uram - SCATTER_URAM_COST;
    int max_partition_size = 1 << ((int)log2(max_gather_uram * URAM_CAPACITY));
    DEBUG_PRINTF("\t max_gather_uram: %d\n", max_gather_uram);
    DEBUG_PRINTF("\t max_partition_size: %d\n", max_partition_size);


    int uram_cost = 0;
    while (true)
    {
        int est_urams = max_partition_size / URAM_CAPACITY;
        kernel_num = 0;
        for (int i = 0; i < ARRAY_SIZE(slrs); i++)
        {
            // avoid run out all urams,
            kernel_num += ( slrs[i].uram * URAM_UPBOUND ) / (est_urams + SCATTER_URAM_COST);
        }
        DEBUG_PRINTF("\t\t partition_size: %d, group_num: %d \n",
                     max_partition_size, kernel_num);
        if (kernel_num <  channel_num)
        {
            max_partition_size = max_partition_size / 2 ;
        }
        else
        {
            partition_size = max_partition_size;

            break;
        }
    }
    // up-bound number of kernels,
    // as one gather scatter kernel can fully utilzated one memory channel
    if (kernel_num > channel_num)
    {
        kernel_num = channel_num;
    }
    uram_cost = partition_size / URAM_CAPACITY + SCATTER_URAM_COST;


    DEBUG_PRINTF("\t final partition size: %d kernel num: %d\n",
                 partition_size, kernel_num);

    std::vector<int> sort;
    for (int i = 0; i < ARRAY_SIZE(slrs); i++)
    {
        sort.push_back(slrs[i].slr_id);
    }

    for (int k = 0; k < sort.size(); k++)
    {

        for (int j = 0; j < sort.size() - k - 1; j++)
        {
            int current = 0;
            int next = 0;
            for (int tmp = 0; tmp < sort.size(); tmp ++)
            {
                if (slrs[sort[tmp]].slr_id == j)
                {
                    current = tmp;
                }
                if (slrs[sort[tmp]].slr_id == j + 1)
                {
                    next = tmp;
                }
            }
            if (slrs[current].uram < slrs[next].uram)
            {
                int id = sort[j];
                sort[j] = sort[j + 1];
                sort[j + 1]  = id;
            }
        }
    }

    for (int i = 0; i < ARRAY_SIZE(slrs); i++)
    {
        slr_info_t resource;
        resource.id      = sort[i];
        resource.uram    = slrs[sort[i]].uram * URAM_UPBOUND;
        resource.luts    = slrs[sort[i]].luts;
        resource.mem_chn = slrs[sort[i]].mem_chns;
        slr_ordered.push_back(resource);
    }


    for (int i = 0; i < kernel_num; i++)
    {
        for (int j = 0; j < slr_ordered.size(); j++)
        {
            if (slr_ordered[j].uram > uram_cost)
            {
                kernel_mapping.push_back(slr_ordered[j].id);
                slr_ordered[j].uram -= uram_cost;
                break;
            }
        }
    }
    DEBUG_PRINTF("\t kernel mapping\n");
    for (int i = 0; i < kernel_mapping.size(); i ++)
    {
        DEBUG_PRINTF("\t\t gather scatter%d --> slr%d\n", i, kernel_mapping[i]);
    }
    for (int i = 0; i < slr_ordered.size(); i++)
    {
        DEBUG_PRINTF("\t\t lefted uram %d@%d --> slr%d\n",
                   slr_ordered[i].id, i, slr_ordered[i].uram);
    }


    int min_id = 0;
    int max_id = 0;
    int lut_max_id = 0;
    for (int i = 0; i < slr_ordered.size(); i ++)
    {
        if (slr_ordered[i].uram < slr_ordered[min_id].uram)
        {
            min_id = i;
        }
        if (slr_ordered[i].uram > slr_ordered[max_id].uram)
        {
            max_id = i;
        }
        if (slr_ordered[i].luts > slr_ordered[lut_max_id].luts)
        {
            lut_max_id = i;
        }
    }

    int diff = 0;

    for (int i = 0; i < slr_ordered.size(); i ++)
    {
        diff += slr_ordered[i].uram - slr_ordered[min_id].uram;
    }

    /* if all the slrs cost the same urams, we choose the one with max clbs(luts & ffs)*/
    DEBUG_PRINTF("\t\t apply  diff is %d\n", diff);

    if (diff == 0)
    {
        apply_mapping = slr_ordered[lut_max_id].id;
    }
    else
    {
        apply_mapping = slr_ordered[max_id].id;
    }

    DEBUG_PRINTF("\t\t apply           --> slr%d\n", apply_mapping);




    if (!file.is_open()) {
        DEBUG_PRINTF("error: can not open para.mk\n");
    }

    file << "# [ThunderGP] board: " << board_name << std::endl;
    file << "# Do not modify this file!" << std::endl;
    file << "KERNEL_NUM=" << kernel_num << std::endl;
    file << "SUB_PARTITION_NUM=" << kernel_num << std::endl;
    file << "AUTOGEN_CFLAG=-DSUB_PARTITION_NUM=$(SUB_PARTITION_NUM)" << std::endl;
    file << "PARTITION_SIZE=" << partition_size << std::endl;
    file << "AUTOGEN_CFLAG +=-DPARTITION_SIZE=$(PARTITION_SIZE)" << std::endl;
    for (int i = 0; i < kernel_mapping.size(); i ++)
    {
        file << "GS" << (i + 1) << "_SLR" << "=" << kernel_mapping[i] << std::endl;
    }
    file << "APPLY_SLR" << "=" << apply_mapping << std::endl;

#define INVALID_FLAG  0xffff

    std::vector<int> mem_cu_map_mask;
    for (int i = 0; i < kernel_mapping.size(); i ++)
    {
        int invalid = INVALID_FLAG;
        memory_mapping.push_back(invalid);
        mem_cu_map_mask.push_back(invalid);

    }
    //direct find the corresponding memory channel
    for (int i = 0; i < memory_mapping.size(); i ++)
    {
        int slr_id = 0;
        for (int j = 0; j < slr_ordered.size(); j ++)
        {
            if (slr_ordered[j].id == kernel_mapping[i])
            {
                slr_id = j;
                break;
            }
        }

        if ((slr_ordered[slr_id].mem_chn != 0) && (memory_mapping[i] == INVALID_FLAG))
        {
            slr_ordered[slr_id].mem_chn--;
            for (int j = 0; j < ARRAY_SIZE(mem_cu_map); j++)
            {
                if (mem_cu_map[j] == kernel_mapping[i])
                {
                    memory_mapping[i] = j;
                    mem_cu_map_mask[j] = 1;
                    break;
                }
            }
        }
    }
    // second option is cross slr
    for (int i = 0; i < memory_mapping.size(); i ++)
    {
        if (memory_mapping[i] == INVALID_FLAG)
        {
            int found_flag = 0;
            for (int k = 0; k < slr_ordered.size(); k++)
            {
                int slr_id = k;
                if (slr_ordered[slr_id].mem_chn != 0)
                {
                    slr_ordered[slr_id].mem_chn--;
                    for (int j = 0; j < ARRAY_SIZE(mem_cu_map); j++)
                    {
                        if ((mem_cu_map[j] == slr_ordered[slr_id].id)
                                && (mem_cu_map_mask[j] == INVALID_FLAG))
                        {
                            memory_mapping[i] = j;
                            mem_cu_map_mask[j] = 1;
                            found_flag = 1;
                            break;
                        }
                    }
                }
                if (found_flag == 1)
                {
                    break;
                }
            }
            if (found_flag == 0)
            {
                DEBUG_PRINTF("\t Error, memory channel is not available for kernel %d\n", i);
            }
        }
    }

    for (int i = 0; i < memory_mapping.size(); i ++)
    {
        file << "GS" << (i + 1) << "_DDR" << "=" << memory_mapping[i] << std::endl;
    }

    for (int i = 0; i < memory_mapping.size(); i ++)
    {
        file << "INTERFACE_" << (i) << "_ID" << "=" << memory_mapping[i] << std::endl;
    }
    file.flush();
    file.close();

    file.open("./tmp_para/mapping.h");
    file << "const cumem_lut_t mapping_item[] =" << std::endl;
    file << "{" << std::endl;
    for (int i = 0; i < memory_mapping.size(); i ++)
    {
        file << "\t{" << std::endl;
        file << "\t\t.cu_id  = " << i << "," << std::endl;
        file << "\t\t.mem_id = XCL_MEM_DDR_BANK" << memory_mapping[i] << "," << std::endl;
        file << "\t\t.he_attr_id = ATTR_PL_DDR" << memory_mapping[i] << "," << std::endl;
        file << "\t\t.interface_id = " << memory_mapping[i] << "," << std::endl;
        file << "\t}," << std::endl;
    }
    file << "};" << std::endl;

    file.flush();
    file.close();


    return 0;
}


================================================
FILE: automation/parser/customize.cpp
================================================
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <algorithm>

#include "parser.h"
#include "parser_debug.h"

#include "customize_str.h"


#define ARG_ITEM(N)   {                 \
        .id      = N,                   \
        .keyword = #N,                  \
        .func    = register_##N,        \
    },

#define MARKER_DEFINE(N) int  N##_ln;   \
    int N##_flag;                       \
    arg_instance_t N##_marker;

#define MARKER_FUNCTION(N,var)                                  \
int register_##N(arg_instance_t item)                           \
{                                                               \
    if (marker.var##_flag == FLAG_RESET)                        \
    {                                                           \
        marker.var##_flag    = FLAG_SET;                        \
        marker.var##_marker  = item;                            \
        marker.var##_ln      = item.ln;                         \
        return 0;                                               \
    }                                                           \
    DEBUG_PRINTF("redef apply %s marker by %s",#var,#N);        \
    return -1;                                                  \
}

#define MARKER_OUTPUT(var,code)                                 \
if (marker.var##_flag == FLAG_SET)                              \
{                                                               \
    if ((ln + 1) == marker.var##_ln )                           \
    {                                                           \
        for (auto args : def_arg_list)                          \
        {                                                       \
            code                                                \
        }                                                       \
        return 1;                                               \
    }                                                           \
}

using namespace std;

typedef enum { VAR_SCALAR = 1, VAR_INPUT_ARRAY, VAR_DUPLEX_ARRAY } var;

typedef struct
{
    std::string    name;
    arg_instance_t input;
    var            var_type;
    int            mem_chn;
} def_arg_instance_t;

typedef struct
{
    MARKER_DEFINE(function)
    MARKER_DEFINE(stream_attr)
    MARKER_DEFINE(scalar_attr)
    MARKER_DEFINE(write)
    MARKER_DEFINE(read_from_stream)
    MARKER_DEFINE(cov)
    MARKER_DEFINE(cov_write)
    MARKER_DEFINE(write_to_stream)
    MARKER_DEFINE(cal)
    MARKER_DEFINE(makefile)
    MARKER_DEFINE(dump)
    MARKER_DEFINE(dump_scalar)
    MARKER_DEFINE(cl)

} arg_mark_t;

typedef struct
{
    std::string type;

    int code_start_ln;
    arg_instance_t start;
    int code_start_flag;

    int code_end_ln;
    arg_instance_t end;
    int code_end_flag;
} code_region_t;

static std::vector<def_arg_instance_t> def_arg_list;
static arg_mark_t marker;
static code_region_t region;

MARKER_FUNCTION(USER_APPLY_ARG, function)
MARKER_FUNCTION(USER_APPLY_STREAM_ATTR, stream_attr)
MARKER_FUNCTION(USER_APPLY_SCALAR_ATTR, scalar_attr)
MARKER_FUNCTION(USER_APPLY_WRITE, write)
MARKER_FUNCTION(USER_APPLY_READ_FROM_STREAM, read_from_stream)
MARKER_FUNCTION(USER_APPLY_COV_FOR_CAL, cov)
MARKER_FUNCTION(USER_APPLY_COV_FOR_WRITE, cov_write)
MARKER_FUNCTION(USER_APPLY_WRITE_TO_STREAM, write_to_stream)
MARKER_FUNCTION(USER_APPLY_CAL, cal)
MARKER_FUNCTION(MAKEFILE_USER_APPLY, makefile)

MARKER_FUNCTION(DUMP_MEM_ATTR, dump);
MARKER_FUNCTION(DUMP_MEM_SCALAR, dump_scalar)

MARKER_FUNCTION(USER_APPLY_CL_KERNEL, cl);


static int gmem_counter = 6;
static int mem_id_offset = 0;
static int output_to_file(std::ofstream * of, int ln, int fileid, int gn)
{
    if (marker.cal_flag == FLAG_SET)
    {
        if ((ln + 1) == marker.cal_ln )
        {
            DEBUG_PRINTF("    enter: %d %d %d\n", ln, fileid, gn);
            if ((region.code_start_flag == FLAG_RESET)
                    || (region.code_end_flag == FLAG_RESET))
            {
                DEBUG_PRINTF("    error: missing code region marker start %d end %d!\n",
                             region.code_start_flag, region.code_end_flag);
                exit(-1);
            }
            if (region.start.file_name != region.end.file_name)
            {
                DEBUG_PRINTF("    error: mismatch file name %s end %s!\n",
                             region.start.file_name.c_str(), region.end.file_name.c_str());
                exit(-1);
            }
            if (region.start.ln > region.end.ln)
            {
                DEBUG_PRINTF("    error: start & end in wrong order!\n");
                exit(-1);
            }
            std::ifstream fhandle(region.start.file_name.c_str());
            if (!fhandle.is_open()) {
                DEBUG_PRINTF("error: can not open %s \n", region.start.file_name.c_str());
                exit(EXIT_FAILURE);
            }
            std::string line;
            int line_number  = 0;
            while (std::getline(fhandle, line)) {
                if ((line_number > region.start.ln ) && line_number < (region.end.ln - 1))
                {
                    ( *of) << line << std::endl;
                }
                line_number ++;
            }
            fhandle.close();
            return 1;
        }
    }

    MARKER_OUTPUT(write_to_stream,
    {
        DEBUG_PRINTF("   write_to_stream enter: %d \n", ln);
        if (args.var_type == VAR_DUPLEX_ARRAY)
        {
            std::string name = args.input.name;
            std::string object("write_to_stream(new%sStream, new%s_u512);");
            replace_all(object, "%s", name);
            ( *of) << object << std::endl;
        }
    })
    MARKER_OUTPUT(cov_write,
    {
        if (args.var_type == VAR_DUPLEX_ARRAY)
        {
            std::string name = args.input.name;
            std::string object(COV_STR_WRITE);
            replace_all(object, "%s", name);
            ( *of) << object << std::endl;
        }
    })
    MARKER_OUTPUT(cov,
    {
        if ((args.var_type == VAR_DUPLEX_ARRAY)
        || ((args.var_type == VAR_INPUT_ARRAY)))
        {
            std::string name = args.input.name;
            std::string object(COV_STR);
            replace_all(object, "%s", name);
            ( *of) << object << std::endl;
        }
    })
    MARKER_OUTPUT(read_from_stream,
    {
        if ((args.var_type == VAR_DUPLEX_ARRAY)
        || ((args.var_type == VAR_INPUT_ARRAY)))
        {
            std::string name = args.input.name;
            std::string object(READ_STR);
            replace_all(object, "%s", name);
            ( *of) << object << std::endl;
        }
        if (args.var_type == VAR_DUPLEX_ARRAY)
        {
            std::string name = args.input.name;
            ( *of) << "burst_raw " << "new" << name << "_u512;" << std::endl;
        }
    })
    MARKER_OUTPUT(function,
    {
        std::string name = args.input.name;

        if (args.var_type == VAR_DUPLEX_ARRAY)
        {
            ( *of) << "uint16    *" << name << "," << std::endl;
            ( *of) << "uint16    *" << "new" << name << "," << std::endl;
        }
        if (args.var_type == VAR_INPUT_ARRAY)
        {
            ( *of) << "uint16    *" << name << "," << std::endl;
        }
        if (args.var_type == VAR_SCALAR)
        {
            ( *of) << region.type << "     " << name << "," << std::endl;
        }
    })
    MARKER_OUTPUT(stream_attr,
    {

        if ((args.var_type == VAR_DUPLEX_ARRAY)
        || ((args.var_type == VAR_INPUT_ARRAY)))
        {
            std::string name = args.input.name;
            std::string object(STREAM_ATTR_STR);
            replace_all(object, "%s", name);
            replace_all(object,  "%d", to_string(gmem_counter));
            ( *of) << object << std::endl;

            if ((args.var_type == VAR_DUPLEX_ARRAY))
            {
                std::string object(STREAM_DUPLEX_OUTPUT_ATTR_STR);
                replace_all(object, "%s",  "new" + name);
                replace_all(object,  "%d", to_string(gmem_counter));
                ( *of) << object << std::endl;
            }
            gmem_counter ++;
        }
    })
    MARKER_OUTPUT(scalar_attr,
    {

        if (args.var_type == VAR_SCALAR)
        {
            std::string name = args.input.name;
            std::string object(SCALAR_ATTR_STR);
            replace_all(object, "%s",  name);
            ( *of) << object << std::endl;
        }
    })
    MARKER_OUTPUT(write,
    {
        if (args.var_type == VAR_DUPLEX_ARRAY)
        {
            std::string name = args.input.name;
            std::string object(WRITE_STR);
            replace_all(object, "%s",  "new" + name);

            ( *of) << object << std::endl;
        }
    })
    MARKER_OUTPUT(dump_scalar,
    {
        if (args.var_type == VAR_SCALAR)
        {
            ( *of) << region.type  << " " << args.input.name << ";" << std::endl;
        }
    })
    MARKER_OUTPUT(dump,
    {
        if ((args.var_type == VAR_DUPLEX_ARRAY)
        || ((args.var_type == VAR_INPUT_ARRAY)))
        {
            mem_id_offset ++;
            std::ostringstream ss1;
            ss1  << " MEM_ID_"
            << args.input.name
            << " "
            << "(MEM_ID_CUSTOM_BASE +"
            << to_string(mem_id_offset)
            << ")"
            << std::endl;
            std::string def_mem_id = ss1.str();
            std::transform(def_mem_id.begin(), def_mem_id.end(), def_mem_id.begin(), ::toupper);

            std::ostringstream ss2;
            ss2  << " MEM_ATTR_"
            << args.input.name
            << " "
            << "("
            << "ATTR_PL_DDR"
            << to_string(args.mem_chn)
            << ")"
            << std::endl;
            std::string def_mem_attr = ss2.str();
            std::transform(def_mem_attr.begin(), def_mem_attr.end(), def_mem_attr.begin(), ::toupper);

            ( *of) << "#define " << def_mem_id << std::endl;
            ( *of) << "#define " << def_mem_attr << std::endl;
        }
        if (args.var_type == VAR_DUPLEX_ARRAY)
        {
            mem_id_offset ++;
            std::ostringstream ss1;
            ss1  << " MEM_ID_"
            << "new"
            << args.input.name
            << " "
            << "(MEM_ID_CUSTOM_BASE +"
            << to_string(mem_id_offset)
            << ")"
            << std::endl;
            std::string def_mem_id = ss1.str();
            std::transform(def_mem_id.begin(), def_mem_id.end(), def_mem_id.begin(), ::toupper);

            std::ostringstream ss2;
            ss2  << " MEM_ATTR_"
            << "new"
            << args.input.name
            << " "
            << "("
            << "ATTR_PL_DDR"
            << to_string(args.mem_chn)
            << ")"
            << std::endl;
            std::string def_mem_attr = ss2.str();
            std::transform(def_mem_attr.begin(), def_mem_attr.end(), def_mem_attr.begin(), ::toupper);

            ( *of) << "#define " << def_mem_id << std::endl;
            ( *of) << "#define " << def_mem_attr << std::endl;
        }


    })
    MARKER_OUTPUT(cl,
    {
        if ((args.var_type == VAR_DUPLEX_ARRAY)
        || ((args.var_type == VAR_INPUT_ARRAY)))
        {
            std::ostringstream ss;
            ss  << " MEM_ID_" << args.input.name;
            std::string mem_id_macro = ss.str();
            std::transform(mem_id_macro.begin(), mem_id_macro.end(), mem_id_macro.begin(), ::toupper);
            ( *of) << "clSetKernelArg(applyHandler->kernel, argvi++, sizeof(cl_mem), get_cl_mem_pointer("
            << mem_id_macro
            << "));" << std::endl;
            //he_set_dirty(MEM_ID_RESULT_REG);
        }
        if (args.var_type == VAR_DUPLEX_ARRAY)
        {
            std::ostringstream ss;
            ss  << " MEM_ID_" << "new" << args.input.name;
            std::string mem_id_macro = ss.str();
            std::transform(mem_id_macro.begin(), mem_id_macro.end(), mem_id_macro.begin(), ::toupper);
            ( *of) << "clSetKernelArg(applyHandler->kernel, argvi++, sizeof(cl_mem), get_cl_mem_pointer("
            << mem_id_macro
            << "));" << std::endl;
            ( *of) << "he_set_dirty("
            << mem_id_macro
            << ");" << std::endl;
        }
        if (args.var_type == VAR_SCALAR)
        {
            ( *of) << "clSetKernelArg(applyHandler->kernel, argvi++, 4,    &(global." <<  args.input.name << "));" << std::endl;
        }
    })
    MARKER_OUTPUT(makefile,
    {
        if ((args.var_type == VAR_DUPLEX_ARRAY)
        || ((args.var_type == VAR_INPUT_ARRAY)))
        {
            std::string name = args.input.name;
            std::string object(MAKFILE_STR);
            replace_all(object, "%s", name);
            replace_all(object, "%d", to_string(args.mem_chn));

            ( *of) << object << std::endl;
        }
        if (args.var_type == VAR_DUPLEX_ARRAY)
        {
            std::string name = args.input.name;
            std::string object(MAKFILE_STR);
            replace_all(object, "%s", "new" + name);
            replace_all(object, "%d", to_string(args.mem_chn));
            ( *of) << object << std::endl;
        }
    })
    return 0;
}

static def_arg_instance_t * get_def_arg(std::string arg)
{
    for (int i = 0; i < def_arg_list.size(); i ++)
    {
        if (arg == def_arg_list[i].name)
        {
            return &def_arg_list[i];
        }
    }
    return NULL;
}

int register_base_type(arg_instance_t item)
{
    region.type = item.name;
    DEBUG_PRINTF("    [BASE] %s\n", region.type.c_str());
    return 0;
}

int register_USER_APPLY_CODE_START(arg_instance_t item)
{
    if (region.code_start_flag == FLAG_RESET)
    {
        region.code_start_flag = FLAG_SET;
        region.code_start_ln = item.ln;
        region.start = item;
        DEBUG_PRINTF("    [START] registered @%d \n", item.ln);
        DEBUG_PRINTF("    [START] file: %s \n", item.file_name.c_str());
        return 0;
    }
    return -1;
}


int register_USER_APPLY_CODE_END(arg_instance_t item)
{
    if (region.code_end_flag == FLAG_RESET)
    {
        region.code_end_flag = FLAG_SET;
        region.code_end_ln = item.ln;
        region.end = item;
        DEBUG_PRINTF("    [END] registered @%d \n", item.ln);
        DEBUG_PRINTF("    [END] file: %s \n", item.file_name.c_str());
        return 0;
    }
    return -1;
}


int register_def_scalar(arg_instance_t item)
{
    if (get_def_arg(item.name))
    {
        DEBUG_PRINTF("    error: %s redefine!\n", item.name.c_str());
        return -1;
    }
    def_arg_instance_t new_arg;
    new_arg.name  = item.name;
    new_arg.input = item;
    new_arg.var_type = VAR_SCALAR;
    DEBUG_PRINTF("    registered %s \n", item.name.c_str());
    DEBUG_PRINTF("    object: %s \n", item.object.c_str());
    def_arg_list.push_back(new_arg);
    return 0;
}
static int memory_chn = 0;

int register_def_input_only_array(arg_instance_t item)
{
    if (get_def_arg(item.name))
    {
        DEBUG_PRINTF("    error: %s redefine!\n", item.name.c_str());
        return -1;
    }
    def_arg_instance_t new_arg;
    new_arg.name  = item.name;
    new_arg.input = item;
    new_arg.mem_chn = memory_chn % 4;
    memory_chn ++;
    new_arg.var_type = VAR_INPUT_ARRAY;
    DEBUG_PRINTF("    registered input-only %s \n", item.name.c_str());
    DEBUG_PRINTF("    object: %s \n", item.object.c_str());
    def_arg_list.push_back(new_arg);
    return 0;
}

int register_def_dou_array(arg_instance_t item)
{
    if (get_def_arg(item.name))
    {
        DEBUG_PRINTF("    error: %s redefine!\n", item.name.c_str());
        return -1;
    }
    def_arg_instance_t new_arg;
    new_arg.name  = item.name;
    new_arg.input = item;
    new_arg.mem_chn = memory_chn % 4;
    memory_chn ++;
    new_arg.var_type = VAR_DUPLEX_ARRAY;
    DEBUG_PRINTF("    registered duplex %s \n", item.name.c_str());
    DEBUG_PRINTF("    object: %s \n", item.object.c_str());
    def_arg_list.push_back(new_arg);
    return 0;
}


static int get_of_number(void)
{
    return OUTPUT_ATTR_SINGLE;
}

output_method_t customize_output_method =
{
    .of_number = get_of_number,
    .output    = output_to_file,
};


static parser_item_t local_parser[] =
{
    {
        .id      = DEF_SCALAR,
        .keyword = "DEF_SCALAR",
        .func    = register_def_scalar,
    },
    {
        .id      = DEF_ARRAY,
        .keyword = "DEF_ARRAY",
        .func    = register_def_dou_array,
    },
    {
        .id      = DEF_INPUT_ONLY_ARRAY,
        .keyword = "DEF_INPUT_ONLY_ARRAY",
        .func    = register_def_input_only_array,
    },
    {
        .id      = APPLY_BASE_TYPE,
        .keyword = "APPLY_BASE_TYPE",
        .func    = register_base_type,
    },

    ARG_ITEM(USER_APPLY_ARG)
    ARG_ITEM(USER_APPLY_STREAM_ATTR)
    ARG_ITEM(USER_APPLY_SCALAR_ATTR)
    ARG_ITEM(USER_APPLY_READ_FROM_STREAM)
    ARG_ITEM(USER_APPLY_COV_FOR_CAL)
    ARG_ITEM(USER_APPLY_CAL)
    ARG_ITEM(USER_APPLY_COV_FOR_WRITE)
    ARG_ITEM(USER_APPLY_WRITE_TO_STREAM)
    ARG_ITEM(USER_APPLY_WRITE)
    ARG_ITEM(USER_APPLY_CODE_START)
    ARG_ITEM(USER_APPLY_CODE_END)
    ARG_ITEM(MAKEFILE_USER_APPLY)
    ARG_ITEM(DUMP_MEM_ATTR)
    ARG_ITEM(DUMP_MEM_SCALAR)
    ARG_ITEM(USER_APPLY_CL_KERNEL)
};


reg_parser_item_t customize_interface_parser =
{
    .pointer = local_parser,
    .size  = ARRAY_SIZE(local_parser),
};


================================================
FILE: automation/parser/customize.h
================================================
#ifndef __CUSTOMIZE_INTERFACE_H__
#define __CUSTOMIZE_INTERFACE_H__

extern output_method_t customize_output_method;

extern reg_parser_item_t customize_interface_parser;

#endif /* __CUSTOMIZE_INTERFACE_H__ */


================================================
FILE: automation/parser/customize_str.h
================================================
#ifndef __CUSTOMIZE_STR_H__
#define __CUSTOMIZE_STR_H__



#define  STREAM_ATTR_STR ("\n\
#pragma HLS INTERFACE m_axi port=%s offset=slave bundle=gmem%d \n\
#pragma HLS INTERFACE s_axilite port=%s bundle=control\n\
        hls::stream<burst_raw>      %sStream;\n\
#pragma HLS stream variable=%sStream depth=16\n\
        burstReadLite(addrOffset, vertexNum, %s, %sStream);\n\
        ")
#define STREAM_DUPLEX_OUTPUT_ATTR_STR ("\n\
#pragma HLS INTERFACE m_axi port=%s offset=slave bundle=gmem%d \n\
#pragma HLS INTERFACE s_axilite port=%s bundle=control \n\
        hls::stream<burst_raw>      %sStream;\n\
#pragma HLS stream variable=%sStream depth=16\n\
")


#define SCALAR_ATTR_STR ("\n\
#pragma HLS INTERFACE s_axilite port=%s      bundle=control \n\
")

#define WRITE_STR ("\n        \
writeBackLite(vertexNum, %s + (addrOffset >> 4), %sStream);\n\
")
#define READ_STR ("\n\
burst_raw %s_u512;\n\
read_from_stream(%sStream, %s_u512);\n\
")

#define COV_STR ("type_cov %s_tmp; \n\
%s_tmp.ui=%s_u512.range((i + 1) * INT_WIDTH - 1, i * INT_WIDTH );\n\
float %s=%s_tmp.f;")


#define COV_STR_WRITE ("type_cov new%s_tmp;\n\
new%s_tmp.f =new%s;\n\
new%s_u512.range((i + 1) * INT_WIDTH - 1, i * INT_WIDTH ) = new%s_tmp.ui;")

#define MAKFILE_STR ("\n\
BINARY_LINK_OBJS    += --sp  vertexApply_1.%s:DDR[%d]")


#endif /* __CUSTOMIZE_STR_H__ */


================================================
FILE: automation/parser/kernel_interface.cpp
================================================

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>


#include "parser.h"
#include "parser_debug.h"

using namespace std;

typedef struct
{
    std::string    name;
    arg_instance_t kernel_arg;
} kernel_arg_instance_t;



static std::vector<kernel_arg_instance_t> kernel_arg_list;

static kernel_arg_instance_t * get_kernel_arg(std::string arg)
{
    for (int i = 0; i < kernel_arg_list.size(); i ++)
    {
        if (arg == kernel_arg_list[i].name)
        {
            return &kernel_arg_list[i];
        }
    }
    return NULL;
}

int register_kernel_arg(arg_instance_t item)
{
    if (get_kernel_arg(item.name))
    {
        DEBUG_PRINTF("    error: %s redefine!\n", item.name.c_str());
        return -1;
    }
    kernel_arg_instance_t new_arg;
    new_arg.name  = item.name;
    new_arg.kernel_arg = item;
    DEBUG_PRINTF("    registered %s \n", item.name.c_str());
    DEBUG_PRINTF("    object: %s \n", item.object.c_str());
    kernel_arg_list.push_back(new_arg);
    return 0;
}
static int get_of_number(void)
{
    if (kernel_arg_list.size() > 0)
        return OUTPUT_ATTR_MULTI;

    else
        return OUTPUT_ATTR_SINGLE;
}
static int output_to_file(std::ofstream * of, int ln, int fileid, int gn)
{
    for (int i = 0; i < kernel_arg_list.size(); i ++)
    {
        if (kernel_arg_list[i].kernel_arg.ln == ln )
        {
            return 1;
        }
        else if (kernel_arg_list[i].kernel_arg.ln == ln + 1 )
        {
            std::string object = kernel_arg_list[i].kernel_arg.object;
            while (true)
            {
                bool ret = replace(object, "#%d#", to_string(fileid + 1));
                if (ret == false)
                {
                    break;
                }
            }
            ( *of) << object << std::endl;
            return 1;
        }
    }
    return 0;
}

output_method_t kernel_output_method =
{
    .of_number = get_of_number,
    .output    = output_to_file,
};


static parser_item_t local_parser[] =
{
    {
        .id      = PRAGMA_ID_CU_DUPLICATE,
        .keyword = "MSLR_FUNCTION",
        .func    = register_kernel_arg,
    },
};

reg_parser_item_t kernel_interface_parser =
{
    .pointer = local_parser,
    .size  = ARRAY_SIZE(local_parser),
};


================================================
FILE: automation/parser/kernel_interface.h
================================================
#ifndef __KERNEL_INTERFACE_H__
#define __KERNEL_INTERFACE_H__

extern output_method_t kernel_output_method;

extern reg_parser_item_t kernel_interface_parser;

#endif /* __KERNEL_INTERFACE_H__ */


================================================
FILE: automation/parser/makefile.cpp
================================================

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>

#include "parser.h"
#include "parser_debug.h"

using namespace std;

typedef struct
{
    std::string    name;
    arg_instance_t input;
} mk_arg_instance_t;

static std::vector<mk_arg_instance_t> mk_list;

int register_makefile_instance(arg_instance_t item)
{
    mk_arg_instance_t mk_item;
    mk_item.input = item;
    mk_list.push_back(mk_item);
    return 0;
}

static int get_of_number(void)
{
    return OUTPUT_ATTR_SINGLE;
}

static int output_to_file(std::ofstream * of, int ln, int fileid, int gn)
{
    for (int i = 0; i < mk_list.size(); i ++)
    {
        /* MSLR_INTERFACE_ARG */
        if (mk_list[i].input.ln == ln )
        {
            return 1;
        }
        else if (mk_list[i].input.ln == ln + 1 )
        {
            for (int j = 0; j < gn ; j ++)
            {
                std::string object = mk_list[i].input.object;
                while (true)
                {
                    bool ret = replace(object, "$(%d)", to_string(j));
                    if (ret == false)
                    {
                        break;
                    }
                }
                ( *of) << object << std::endl;
            }
            return 1;
        }
    }
    return 0;
}

output_method_t makefile_output_method =
{
    .of_number = get_of_number,
    .output    = output_to_file,
};


static parser_item_t local_parser[] =
{
    {
        .id      = MAKEFILE_MEM_INSTANCE,
        .keyword = "MAKEFILE_MEM_INSTANCE",
        .func    = register_makefile_instance,
    }
};



reg_parser_item_t makefile_interface_parser =
{
    .pointer = local_parser,
    .size  = ARRAY_SIZE(local_parser),
};


================================================
FILE: automation/parser/makefile.h
================================================
#ifndef __MAKEFILE_INTERFACE_H__
#define __MAKEFILE_INTERFACE_H__

extern output_method_t makefile_output_method;

extern reg_parser_item_t makefile_interface_parser;

#endif /* __MAKEFILE_INTERFACE_H__ */


================================================
FILE: automation/parser/mem_interface.cpp
================================================

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>



#include "parser.h"
#include "parser_debug.h"

using namespace std;

typedef struct
{
    unsigned int   mask;
    std::string    name;
    arg_instance_t input;
    arg_instance_t attr;
    std::vector<arg_instance_t> instance;
} mem_arg_instance_t;


const int dependence_map[] =
{
    PRAGMA_ID_MEM_ARG,
    PRAGMA_ID_MEM_ATTR,
    PRAGMA_ID_MEM_INSTANCE,
};

static std::vector<mem_arg_instance_t> mem_list;



static mem_arg_instance_t * get_mem_arg(std::string arg)
{
    for (int i = 0; i < mem_list.size(); i ++)
    {
        if (arg == mem_list[i].name)
        {
            return &mem_list[i];
        }
    }
    return NULL;
}

int find_in_dependency(int id)
{
    for (int i = 0; i < ARRAY_SIZE(dependence_map); i++)
    {
        if (id == dependence_map[i])
        {
            return i;
        }
    }
    return -1;
}

unsigned int get_dependency_mask(int id)
{
    int i = 0;
    for (int i = 0; i < ARRAY_SIZE(dependence_map); i++)
    {
        if (id == dependence_map[i])
        {
            unsigned int mask = (1 << i) - 1;
            return mask;
        }
    }
    return 0;

}

int register_mem_arg(arg_instance_t item)
{
    if (get_mem_arg(item.name))
    {
        DEBUG_PRINTF("    error: %s redefine!\n", item.name.c_str());
        return -1;
    }
    mem_arg_instance_t new_arg;
    new_arg.name  = item.name;
    new_arg.input = item;
    new_arg.mask = 0;
    int dep_bit = find_in_dependency(item.id);
    if (dep_bit < 0)
    {
        DEBUG_PRINTF("    error: %s is invalid!\n", item.name.c_str());
        return -1;
    }
    new_arg.mask |= (1 << dep_bit);
    DEBUG_PRINTF("    registered %s \n", item.name.c_str());
    DEBUG_PRINTF("    object: %s \n", item.object.c_str());
    mem_list.push_back(new_arg);
    return 0;
}


int register_mem_attr(arg_instance_t item)
{
    mem_arg_instance_t * p_registered = get_mem_arg(item.name);
    if (p_registered != NULL)
    {
        if (p_registered->mask != get_dependency_mask(item.id))
        {
            DEBUG_PRINTF("    error: dependency mismatch %x of %s\n",
                         p_registered->mask,
                         item.name.c_str());
            return -1;
        }
        p_registered->attr = item;
        int dep_bit = find_in_dependency(item.id);
        if (dep_bit < 0)
        {
            DEBUG_PRINTF("    error: %s is invalid!\n", item.name.c_str());
            return -1;
        }
        p_registered->mask |= (1 << dep_bit);
        p_registered->attr = item;
        DEBUG_PRINTF("    %s attr registered \n", item.name.c_str())
        DEBUG_PRINTF("    object: %s \n", item.object.c_str());
        return 0;
    }
    else
    {
        DEBUG_PRINTF("    error: %s not exist!\n", item.name.c_str());
        return -1;
    }
    return 0;
}



int register_mem_instance(arg_instance_t item)
{
    mem_arg_instance_t * p_registered = get_mem_arg(item.name);
    if (p_registered != NULL)
    {
        if ((p_registered->mask & get_dependency_mask(item.id))
                != get_dependency_mask(item.id))
        {
            DEBUG_PRINTF("    error: dependency mismatch %x of %s instance\n",
                         p_registered->mask,
                         item.name.c_str());
            return -1;
        }
        int dep_bit = find_in_dependency(item.id);
        if (dep_bit < 0)
        {
            DEBUG_PRINTF("    error: %s is invalid!\n", item.name.c_str());
            return -1;
        }
        p_registered->mask |= (1 << dep_bit);
        DEBUG_PRINTF("    %s instance registered \n", item.name.c_str());
        p_registered->instance.push_back(item);
        DEBUG_PRINTF("    %s total registered %d \n", item.name.c_str(), p_registered->instance.size());
        DEBUG_PRINTF("    object: %s \n", item.object.c_str());
        return 0;
    }
    else
    {
        DEBUG_PRINTF("    error: %s not exist!\n", item.name.c_str());
        return -1;
    }
    return 0;
}

static int get_of_number(void)
{
    return OUTPUT_ATTR_SINGLE;
}

static int output_to_file(std::ofstream * of, int ln, int fileid, int gn)
{
    for (int i = 0; i < mem_list.size(); i ++)
    {
        /* MSLR_INTERFACE_ARG */
        if (mem_list[i].input.ln == ln )
        {
            return 1;
        }
        else if (mem_list[i].input.ln == ln + 1 )
        {
            for (int j = 0; j < gn ; j ++)
            {
                std::string object = mem_list[i].input.object;
                while (true)
                {
                    bool ret = replace(object, "#%d#", to_string(j));
                    if (ret == false)
                    {
                        break;
                    }
                }
                ( *of) << object << std::endl;
            }
            return 1;
        }
        /* MSLR_INTERFACE_ATTR */
        if (mem_list[i].attr.ln == ln )
        {
            return 1;
        }
        else if (mem_list[i].attr.ln == ln + 1 )
        {
#if 0
            std::string object ("#pragma HLS INTERFACE s_axilite port=#%d# bundle=control");
            while (true)
            {
                bool ret = replace(object, "#%d#", mem_list[i].name);
                if (ret == false)
                {
                    break;
                }
            }
            ( *of) << object << std::endl;
#endif
            return 1;
        }
        /* MSLR_INTERFACE_INSTANCE */
        for (int k = 0; k < mem_list[i].instance.size(); k++)
        {
            if (mem_list[i].instance[k].ln == ln )
            {
                return 1;
            }
            else if (mem_list[i].instance[k].ln == ln + 1 )
            {
                for (int j = 0; j < gn ; j ++)
                {
                    std::string object = mem_list[i].instance[k].object;
                    while (true)
                    {
                        bool ret = replace(object, "#%d#", to_string(j));
                        if (ret == false)
                        {
                            break;
                        }
                    }
                    ( *of) << object << std::endl;
                }
                return 1;
            }
        }
    }
    return 0;
}

output_method_t mem_output_method =
{
    .of_number = get_of_number,
    .output    = output_to_file,
};


static parser_item_t local_parser[] =
{
    {
        .id      = PRAGMA_ID_MEM_ARG,
        .keyword = "MSLR_INTERFACE_ARG",
        .func    = register_mem_arg,
    },
    {
        .id      = PRAGMA_ID_MEM_ATTR,
        .keyword = "MSLR_INTERFACE_ATTR",
        .func    = register_mem_attr,
    },
    {
        .id      = PRAGMA_ID_MEM_INSTANCE,
        .keyword = "MSLR_INTERFACE_INSTANCE",
        .func    = register_mem_instance,
    }
};



reg_parser_item_t mem_interface_parser =
{
    .pointer = local_parser,
    .size  = ARRAY_SIZE(local_parser),
};


================================================
FILE: automation/parser/mem_interface.h
================================================
#ifndef __MEM_INTERFACE_H__
#define __MEM_INTERFACE_H__

extern output_method_t mem_output_method;

extern reg_parser_item_t mem_interface_parser;

#endif /* __MEM_INTERFACE_H__ */


================================================
FILE: automation/parser.cpp
================================================

#include <string>
#include <cctype>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>

#include <stdarg.h>
#include <vector>

#include "para_check.h"

#include "parser.h"
#include "parser_debug.h"
#include "mem_interface.h"
#include "kernel_interface.h"
#include "customize.h"
#include "makefile.h"

using namespace std;

#define REG_PARSER(N)       for (int i = 0; i < (N##_interface_parser).size;i++){       \
                                local_item.push_back(N##_interface_parser.pointer[i]);  \
                            }                                                           \
                            register_output_method(N##_output_method);

int register_output_method(output_method_t method);


std::vector<parser_item_t> local_item;
int parser_init(void)
{
    const char * prefix = PRAGMA_PERFIX;

    REG_PARSER(kernel);
    REG_PARSER(mem);
    REG_PARSER(customize);
    REG_PARSER(makefile);
    for (int i = 0; i < local_item.size(); i++)
    {
        int ret = snprintf(local_item[i].pragma_string, MAX_CHAR_LENGTH, "%s %s", prefix, local_item[i].keyword);
        if (ret <= 0)
        {
            DEBUG_PRINTF("bug: pragma string overflow\n");
            exit(EXIT_FAILURE);
        }
    }
    return 0;
}

std::string find_arg(void * context, std::string &line, int ln)
{
    parser_item_t * p_context = (parser_item_t *)context;
    std::string arg = line;
    std::string target(p_context->pragma_string);
    target.erase(std::remove_if(target.begin(), target.end(), ::isspace), target.end());
    size_t pos = arg.find(target);
    if (pos != std::string::npos)
    {
        arg.erase(pos, target.length());
        DEBUG_PRINTF("ARG: %s of %s in line: %d\n", arg.c_str(), p_context->keyword, ln);
    }
    return arg;
}

int identify_pragmas(std::string file_name, std::string &current_line, std::string &next_line, int line_number)
{
    std::string stripped_line = current_line;
    stripped_line.erase(
        std::remove_if(stripped_line.begin(), stripped_line.end(), ::isspace),
        stripped_line.end()
    );
    arg_instance_t arg_ins;
    for (int i = 0; i < local_item.size(); i++)
    {
        std::string target(local_item[i].pragma_string);
        target.erase(std::remove_if(target.begin(), target.end(), ::isspace), target.end());
        if (stripped_line.find(target) != std::string::npos) {
            arg_ins.name    = find_arg(&local_item[i], stripped_line, line_number);
            arg_ins.orginal = current_line;
            arg_ins.ln      = line_number;
            arg_ins.id      = local_item[i].id;
            arg_ins.object  = next_line;
            arg_ins.file_name = file_name;

            if (local_item[i].func != NULL)
            {
                int ret = local_item[i].func(arg_ins);
                if (ret < 0)
                {
                    exit(EXIT_FAILURE);
                }
            }
            return 0;
        }
    }
    return 1;
}

int file_input(const std::string& input)
{
    std::ifstream fhandle(input.c_str());
    if (!fhandle.is_open()) {
        DEBUG_PRINTF("error: can not open %s \n", input.c_str());
        exit(EXIT_FAILURE);
    }

    std::string line;
    std::string last_line;
    int line_number  = 0;
    while (std::getline(fhandle, line)) {
        if (line_number > 0)
        {
            identify_pragmas(input, last_line, line, (line_number));
        }
        line_number ++;
        last_line  = line;
    }
    fhandle.close();
    return 0;
}


std::vector<output_method_t> output_methods;

int register_output_method(output_method_t method)
{
    output_methods.push_back(method);
    return 0;
}

std::vector<std::ofstream *> output_files;

int file_output(const std::string& input, const std::string& output)
{
    int of_attr = OUTPUT_ATTR_SINGLE;
    for (auto method : output_methods)
    {
        if (method.of_number() > of_attr)
        {
            of_attr = method.of_number();
        }
    }
    int total_file_num;
    int group_num = SUB_PARTITION_NUM;

    if (of_attr == OUTPUT_ATTR_SINGLE)
        total_file_num = 1;
    else
        total_file_num = group_num;

    for (int i = 0; i < total_file_num; i++)
    {

        std::ostringstream output_file_name;
        output_file_name << output;
        output_file_name << "_";
        output_file_name << (i + 1);
        // TODO: hardcode
        {
            size_t pos = input.find(".cpp");
            if (pos != std::string::npos)
            {
                output_file_name << ".cpp";
            }
        }
        {
            size_t pos = input.find(".mk");
            if (pos != std::string::npos)
            {
                output_file_name << ".mk";
            }
        }
        {
            size_t pos = input.find(".h");
            if (pos != std::string::npos)
            {
                output_file_name << ".h";
            }
        }

        DEBUG_PRINTF("output file: %s\n", output_file_name.str().c_str());

        std::ofstream * of = new std::ofstream(output_file_name.str().c_str());
        //(*of) << "autogen"<<std::endl;
        output_files.push_back(of);
    }

    std::ifstream fhandle(input.c_str());
    if (!fhandle.is_open()) {
        DEBUG_PRINTF("error: can not open %s \n", input.c_str());
        exit(EXIT_FAILURE);
    }

    std::string line;
    std::string last_line;
    int line_number  = 0;
    while (std::getline(fhandle, line)) {

        int ret = 0;
        for (int i = 0; i < output_methods.size(); i++)
        {
            for (int j = 0; j < total_file_num; j++)
            {
                if (output_methods[i].output)
                {
                    ret += output_methods[i].output(output_files[j],
                                                    line_number,
                                                    j,
                                                    group_num);
                }
            }
        }

        if (ret == 0)
        {
            for (int i = 0; i < total_file_num; i++)
            {
                (*output_files[i]) << line << std::endl;
            }
        }
        else
        {
            std::cout << "[" << line_number << "] " << line << std::endl;
        }
        line_number ++;
    }
    fhandle.close();

    for (int i = 0; i < total_file_num; i++)
    {
        (*output_files[i]).flush();
        (*output_files[i]).close();
    }
    return 0;
}

int main(int argc, char **argv) {
    std::string input_code;
    parser_init();
    if (argc < 2)
    {
        DEBUG_PRINTF("error: no input \n");
        DEBUG_PRINTF("./code_gen  base_input input2 ... output \n");
    }
    for (int i = 1; i < argc - 1; i++)
    {
        DEBUG_PRINTF("read in %d@%d\n", i, argc - 2);
        file_input(argv[i]);
    }
    DEBUG_PRINTF("output\n")
    file_output(argv[1], argv[argc - 1]);

    return 0;
}

================================================
FILE: automation/parser.h
================================================
#ifndef __PARSER_H__
#define __PARSER_H__

#include "common.h"

#define MAX_CHAR_LENGTH         (256)

#define PRAGMA_ID_CU_DUPLICATE  (0)

#define PRAGMA_ID_MEM_ARG       (1)
#define PRAGMA_ID_MEM_ATTR      (2)
#define PRAGMA_ID_MEM_INSTANCE  (3)

#define USER_APPLY_ARG          (4)
#define USER_APPLY_STREAM_ATTR  (5)
#define USER_APPLY_SCALAR_ATTR  (6)




#define USER_APPLY_WRITE              (10)
#define USER_APPLY_READ_FROM_STREAM   (11)
#define USER_APPLY_COV_FOR_CAL        (12)
#define USER_APPLY_COV_FOR_WRITE      (13)
#define USER_APPLY_WRITE_TO_STREAM    (14)
#define USER_APPLY_CAL                (15)

#define DEF_SCALAR                    (7)
#define DEF_INPUT_ONLY_ARRAY          (8)
#define DEF_ARRAY                     (9)
#define USER_APPLY_CODE_START         (16)
#define USER_APPLY_CODE_END           (17)

#define MAKEFILE_MEM_INSTANCE         (18)
#define MAKEFILE_USER_APPLY           (19)
#define DUMP_MEM_ATTR                 (20)
#define DUMP_MEM_SCALAR               (21)
#define USER_APPLY_CL_KERNEL          (22)
#define APPLY_BASE_TYPE               (23)


#define OUTPUT_ATTR_SINGLE      (1)
#define OUTPUT_ATTR_MULTI       (2)

#define PRAGMA_PERFIX           "#pragma THUNDERGP"


typedef struct
{
    std::string orginal;
    std::string object;
    std::string name;
    std::string file_name;
    int ln;
    int id;
} arg_instance_t;


typedef int (*parser_func)(arg_instance_t item);

typedef struct
{
    const int    id;
    const char   *keyword;

    parser_func  func;
    char         pragma_string[MAX_CHAR_LENGTH];

} parser_item_t;

typedef struct
{
    parser_item_t * pointer;
    int size;
} reg_parser_item_t;

typedef int (*get_of_attr)(void);
typedef int (*output_line)(std::ofstream * of, int ln, int fileid, int gn);

typedef struct
{
    get_of_attr  of_number;
    output_line  output;
} output_method_t;


bool replace(std::string& str, const std::string& from, const std::string& to);

inline int replace_all(std::string &object, std::string sub, std::string target)
{
    while (true)
    {
        bool ret = replace(object, sub, target);
        if (ret == false)
        {
            break;
        }
    }
    return 0;
}


#endif /*__PARSER_H__ */


================================================
FILE: automation/parser_debug.cpp
================================================
#include <string>
#include <stdarg.h>

void logger (char *fmt, ...)
{
    va_list argp;
    fprintf(stdout, "[PARSER] ");
    va_start(argp, fmt);
    vfprintf(stdout, fmt, argp);
    va_end(argp);
}


bool replace(std::string& str, const std::string& from, const std::string& to) {
    size_t start_pos = str.find(from);
    if (start_pos == std::string::npos)
        return false;
    str.replace(start_pos, from.length(), to);
    return true;
}


================================================
FILE: automation/parser_debug.h
================================================
#ifndef __PARSER_DEBUG__
#define __PARSER_DEBUG__

#undef DEBUG_PRINTF
#define DEBUG_PRINTF(fmt,...)   logger((char *)fmt,##__VA_ARGS__);


extern void logger (char *fmt, ...);


#endif /* __PARSER_DEBUG__ */


================================================
FILE: dataset/README.md
================================================
# Dataset and Data Format


| Graphs  | *```E```* | *```V```*  | *```D_avg```* | Graph type |
|--------|-----------|------------|-------------|------------ |
| rmat-19-32 (R19)  | 524.3K | 16.8M | 32 | Synthetic |
| rmat-21-32 (R21)  | 2.1M | 67.1M | 32 | Synthetic |
| rmat-24-16 (R24)  | 16.8M | 268.4M | 16 | Synthetic |
| graph500-scale23-ef16 (G23)  | 4.6M | 258.5M | 56 | Synthetic |
| graph500-scale24-ef16 (G24)  | 8.9M | 520.5M | 59 | Synthetic |
| graph500-scale25-ef16 (G25)  | 17.0M | 1.0B | 61 | Synthetic |
| wiki-talk (WT)  | 2.4M | 5.0M | 2 | Communication |
| web-google (GG)  | 916.4K | 5.1M | 6 | Web |
| amazon-2008 (AM)  | 735.3K | 5.2M | 7  | Social |
| bio-mouse-gene (MG)  | 45.1K | 14.5M | 322 | biological |
| web-hudong (HD)  | 2.0M | 14.9M | 7 | Web |
| soc-flickr-und (FU)  | 1.7M | 15.6M | 9 | Social |
| web-baidu-baike (BB)  | 2.1M | 17.8M | 8 | Web |
| wiki-topcats (TC)  | 1.8M | 28.5M | 16 | Web |
| pokec-relationships (PK)  | 1.6M | 30.6M | 19 | Social |
| wikipedia-20070206 (WP)  | 3.6M | 45.0M | 13 | Web |
| ca-hollywood-2009 (HW)  | 1.1M | 56.3M | 53 | Social |
| liveJournal1 (LJ)  | 4.8M | 69.0M | 14 | Social |
| soc-twitter (TW)  | 21.3M | 265.0M | 12 | Social |


The recursive graph (rmat) datasets are generated by the script located at ```dataset```, and the format is edge list which is shown below.

**Edge list file format:**
```
<vertex id> <vertex id>
```

The property of vertices and the property of edges are __32-bit__ value (can be integer of float type). During the entire processing flow the id of vertices is unsigned __32-bit__ integer.


================================================
FILE: dataset/kronecker_generator.m
================================================
function ijw = kronecker_generator (SCALE, edgefactor)
%% Generate an edgelist according to the Graph500 parameters.  In this
%% sample, the edge list is returned in an array with three rows,
%% where StartVertex is first row, EndVertex is the second row, and
%% Weight is the third row.  The vertex labels start at zero.
%%  
%% Example, creating a sparse matrix for viewing:
%%   ijw = kronecker_generator (10, 16);
%%   G = sparse (ijw(1,:)+1, ijw(2,:)+1, ones (1, size (ijw, 2)));
%%   spy (G);
%% The spy plot should appear fairly dense. Any locality
%% is removed by the final permutations.

  %% Set number of vertices.
  N = 2^SCALE;

  %% Set number of edges.
  M = edgefactor * N;

  %% Set initiator probabilities.
  [A, B, C] = deal (0.57, 0.19, 0.19);

  %% Create index arrays.
  ijw = ones (3, M);
  %% Loop over each order of bit.
  ab = A + B;
  c_norm = C/(1 - (A + B));
  a_norm = A/(A + B);

  for ib = 1:SCALE,
    %% Compare with probabilities and set bits of indices.
    ii_bit = rand (1, M) > ab;
    jj_bit = rand (1, M) > ( c_norm * ii_bit + a_norm * not (ii_bit) );
    ijw(1:2,:) = ijw(1:2,:) + 2^(ib-1) * [ii_bit; jj_bit];
  end

  %% Generate weights
  ijw(3,:) = unifrnd(0, 1, [1,M]);

  %% Permute vertex labels
  p = randperm (N);
  ijw(1:2,:) = p(ijw(1:2,:));

  %% Permute the edge list
  p = randperm (M);
  ijw = ijw(:, p);

  %% Adjust to zero-based labels.
  ijw(1:2,:) = ijw(1:2,:) - 1;

endfunction


================================================
FILE: dataset/rmat-14-32.txt
================================================
5430 9982 
10517 12137 
9114 7782 
13395 8156 
2102 2122 
16046 1212 
11053 14922 
1551 15526 
11851 15530 
11934 2508 
13267 5662 
2928 4064 
15223 11148 
3230 14339 
14702 4600 
4790 16028 
4351 2102 
10384 13267 
4751 15767 
11246 16108 
10446 2074 
1251 4207 
15354 293 
6036 1551 
10734 11377 
13395 7279 
798 7760 
4656 4207 
12658 759 
12851 2468 
1181 4207 
5765 11834 
3730 10050 
8289 1467 
3891 4268 
11879 11160 
15143 15223 
548 3882 
9691 12450 
12929 12063 
14159 911 
5876 2891 
10619 12760 
11508 10692 
3023 15223 
8208 9389 
7420 3936 
15537 15 
3184 7420 
1842 13817 
13784 13267 
2981 3974 
13732 9004 
11458 6439 
15530 5865 
2054 8754 
3433 5139 
11541 473 
6954 16105 
10064 15742 
12929 5004 
15074 13437 
897 6930 
6859 13932 
1619 6121 
704 4343 
15223 7229 
10563 1459 
10834 14408 
9881 8916 
1179 2925 
7959 4696 
4452 13227 
3305 5382 
9442 13362 
14687 10411 
13890 2981 
5597 12808 
3732 7095 
13192 16198 
6112 7003 
10446 12157 
8083 6476 
5727 9953 
6256 14382 
663 11742 
9238 3405 
9743 12163 
16198 6235 
4844 15272 
115 7366 
15192 13227 
5996 6335 
12342 1735 
4611 4222 
6951 15354 
2218 14151 
15602 524 
5471 14212 
15878 3749 
2891 12851 
6177 11964 
6317 10176 
9141 308 
11845 8343 
2034 15579 
759 4067 
2854 14382 
13996 13192 
4334 4270 
5699 6667 
7708 13816 
8119 10486 
13360 5488 
14785 5163 
3449 1282 
8965 2102 
14472 13310 
4696 13306 
15354 7152 
10955 7705 
3536 9946 
2513 5991 
13395 14094 
9743 13395 
10059 115 
1802 16328 
14657 11980 
3047 1124 
11673 4021 
7471 10899 
2203 1518 
5517 15075 
3486 6859 
10186 11608 
7420 1705 
336 4696 
10691 7420 
3829 15767 
9545 11934 
13360 13411 
11246 71 
10750 4863 
9946 13342 
6985 5699 
8696 11763 
6645 13192 
394 71 
8193 13395 
4137 1619 
1383 2586 
15074 15192 
4665 9124 
7420 16317 
3816 9940 
12962 7420 
9176 484 
13395 13509 
4686 7420 
8890 7769 
2944 7171 
14478 10446 
12040 5517 
15223 15354 
6177 11131 
10782 911 
69 14375 
1104 10825 
115 4672 
472 9935 
16007 1156 
11945 10329 
7420 14199 
15223 10177 
8558 3025 
4876 1517 
13996 15530 
5239 4207 
248 11931 
11461 9946 
16007 7420 
345 15354 
15054 14816 
10064 3584 
13929 15342 
14922 4352 
15561 14147 
9143 12822 
12791 7927 
9946 12248 
6702 472 
1428 2125 
13844 329 
14985 15498 
12504 443 
12234 11121 
1263 5558 
12061 14472 
9743 14781 
14696 4706 
4860 2703 
4207 5876 
14525 7420 
7460 5672 
14237 7583 
15271 4681 
11457 12162 
16336 15700 
4207 6600 
15308 5797 
3363 10734 
1619 4790 
6178 12420 
9504 16363 
4099 9005 
9005 11316 
9041 12021 
15894 6148 
8355 15470 
6036 12202 
12558 2925 
12919 14478 
7708 10822 
6985 10679 
3287 15192 
11160 11297 
10059 177 
12130 1177 
15295 10596 
5827 14171 
10089 8969 
472 8515 
8732 11766 
15045 8510 
10479 10108 
938 13267 
4912 15537 
7031 1023 
10050 7936 
13192 7420 
7476 12176 
9989 3869 
1551 3936 
13548 11763 
12948 6884 
15529 5332 
1278 9953 
13039 2102 
9005 901 
10059 15223 
13189 3315 
15192 7936 
5236 3484 
5983 15354 
6954 8368 
16243 7021 
3764 7420 
13781 12754 
16301 6107 
2140 4672 
4790 13227 
16284 2793 
14744 4190 
13227 7420 
2793 9479 
9097 10101 
833 15012 
11461 15852 
6726 4111 
15963 15354 
9019 16036 
11933 4655 
15192 14220 
7708 13400 
4064 14719 
1438 9124 
1104 12791 
9946 13884 
15481 15526 
6954 3567 
1735 15526 
15074 15436 
9464 12429 
472 12929 
11043 16188 
3465 11325 
15894 12913 
9621 1281 
4889 8969 
10910 8140 
3549 13408 
5191 798 
11377 6217 
13306 16148 
13306 11148 
1692 15710 
16022 9494 
15223 11245 
1946 7877 
15354 16167 
1964 4655 
1467 14357 
472 2470 
1391 7723 
15488 5054 
11407 8941 
6060 12157 
3784 2981 
1904 13702 
15103 6859 
12808 2703 
15710 9743 
12893 14199 
2401 1426 
5974 3305 
3369 7095 
418 10467 
2981 8586 
5670 1058 
11641 7820 
12760 10983 
4612 284 
11314 10446 
5517 9886 
15767 16108 
10171 16188 
2054 12903 
7420 6119 
15635 394 
9946 8156 
10435 12971 
5352 2703 
13556 10955 
11356 12061 
2687 15354 
4600 6177 
911 5944 
7014 9089 
3893 13306 
15963 16188 
15541 374 
5336 6924 
6726 4158 
4898 11457 
1639 9504 
15289 10373 
14382 13605 
10965 12870 
1677 9306 
2228 7420 
11879 13264 
15710 7420 
11933 15470 
7275 14478 
16073 12808 
7420 13591 
15701 14970 
71 16188 
13917 1667 
9242 10897 
11472 7196 
394 9576 
12760 3362 
7903 3466 
7516 8982 
16284 5765 
7420 5043 
12233 473 
6453 743 
6669 15993 
7476 3724 
12071 8575 
4396 14419 
3391 2981 
2145 8807 
2485 13688 
12942 11461 
10050 8490 
14562 4070 
11148 15270 
15537 1032 
15841 10089 
15354 14036 
4207 10446 
9858 3699 
7095 15710 
11407 11850 
15036 11879 
248 9504 
6486 14785 
8965 10822 
13591 1946 
5775 3165 
13395 9681 
11121 115 
6859 4405 
12893 8490 
5827 9124 
15354 10446 
8449 3098 
3983 3023 
8965 381 
12893 5629 
10097 16028 
13816 12880 
13306 1869 
115 4612 
1046 952 
11222 15192 
13721 13227 
13395 5507 
9674 2067 
10047 16234 
3117 1781 
6726 3749 
15005 11407 
3287 7765 
15287 11945 
9442 13227 
7238 13843 
16188 6985 
3287 14687 
15824 1104 
13567 3305 
1093 1124 
15222 10467 
6669 10955 
6343 2145 
8473 5517 
8788 2687 
9772 663 
13124 7420 
4091 3983 
4605 14603 
8969 9037 
14650 4207 
5765 7067 
3780 625 
2313 15354 
8391 12851 
16198 2283 
374 7824 
9733 14199 
2408 6541 
3230 2793 
1445 9935 
12065 6177 
13133 3433 
329 7384 
987 4896 
11989 14529 
629 4600 
11980 16188 
9235 13267 
516 309 
10089 9514 
14922 9743 
9585 12555 
2102 13267 
11569 6217 
6144 16188 
16028 3584 
5491 5827 
13045 2981 
10287 15103 
11485 7264 
1391 7708 
13065 1946 
4158 4696 
4376 12668 
9663 9041 
6439 3762 
4329 7515 
15958 8969 
13941 10446 
2881 10009 
14075 12546 
10828 15354 
4981 14144 
10181 7420 
3238 12400 
2409 12424 
1619 4612 
6256 14751 
6439 11121 
15710 15828 
7420 6797 
13227 7870 
16015 7420 
293 1179 
12997 16381 
1281 7914 
10648 15354 
16279 9209 
2497 15354 
13360 10674 
14647 10923 
9466 4207 
4207 1752 
9775 10177 
10446 5368 
5517 14709 
1440 12618 
6500 369 
6838 4295 
5243 10040 
2854 14268 
14165 8965 
10064 10018 
10910 13227 
3673 3391 
8575 2657 
5260 3804 
14866 7420 
5114 164 
4178 7507 
13267 5029 
10089 2586 
4203 374 
9072 2928 
1464 15474 
7420 9145 
6912 12805 
12159 9041 
11980 7165 
11461 9124 
4453 10656 
5341 4339 
7420 6541 
2283 3551 
2142 7420 
13395 4937 
13817 9743 
5423 7420 
10177 12964 
12519 5289 
2170 9450 
9775 1369 
9940 15355 
13378 12997 
9886 15192 
7420 15160 
15513 8137 
5162 3155 
10843 293 
1551 7621 
2792 6726 
6075 10446 
7160 15559 
16317 4937 
8621 9184 
2703 12760 
16007 6060 
4360 4312 
13605 7570 
8965 13754 
732 1104 
1467 13306 
13284 5670 
11121 12711 
12870 329 
12804 7415 
13169 6541 
2509 12504 
4334 11673 
9124 3287 
2687 15919 
16055 7420 
9472 1946 
5054 2102 
6580 10905 
1946 6003 
13395 15266 
10446 1004 
6920 9841 
14747 14419 
16243 2022 
376 4600 
121 472 
3355 4845 
9198 4696 
12120 6859 
4370 11314 
12720 6144 
9504 2102 
1017 1946 
5859 4029 
1457 123 
16088 12121 
7420 839 
5264 4361 
11906 8343 
2102 4321 
9641 16188 
11759 4032 
5938 15180 
4178 12111 
13267 5804 
14144 71 
12466 1426 
15776 12176 
890 4506 
11457 7765 
6954 8838 
1467 6486 
16085 8251 
12162 15488 
2902 12368 
8754 13175 
14419 15746 
13306 3272 
6060 11488 
2174 4930 
13169 5236 
5394 5054 
5019 13306 
11662 4761 
5074 16176 
9464 15222 
11980 2203 
10446 10857 
4077 11246 
6358 5873 
15194 9572 
6407 8300 
5559 2687 
15223 14829 
738 12382 
6003 4207 
6050 4360 
15160 6568 
705 7095 
1782 10691 
6419 13591 
14179 15354 
15212 4295 
15223 5352 
7420 9674 
15036 10446 
10878 12453 
9946 15289 
3536 896 
10734 6694 
6439 13267 
4207 683 
13267 6476 
10118 1840 
5276 11774 
13227 14655 
13395 4215 
15797 13996 
559 5003 
11541 998 
7570 9041 
2283 2999 
10983 6726 
3704 8575 
15749 6764 
13518 10250 
2673 754 
15470 7182 
101 15529 
4210 10145 
15530 11177 
5613 14687 
115 2928 
15635 15710 
4155 11337 
5276 13735 
4215 14147 
12650 2162 
13227 4669 
15187 6262 
9769 9572 
7420 2993 
7772 6036 
9779 11093 
2060 9946 
5712 7420 
2751 7570 
7141 12771 
14816 15269 
10991 1551 
7719 3618 
9584 13843 
7814 7803 
6667 4985 
2751 6541 
2054 13817 
4268 9710 
4557 5139 
16108 12411 
9887 4370 
12130 14382 
1212 2707 
874 8343 
15223 14017 
14153 11681 
12380 3749 
1287 3215 
6726 5451 
16336 6439 
11220 10294 
12948 5829 
13352 4694 
4373 12248 
10250 13361 
13033 12157 
9885 2283 
16254 1281 
10081 4879 
5260 10064 
1890 15354 
11541 7620 
15824 7471 
14408 329 
5155 8965 
1160 2374 
5670 5827 
12760 12553 
11093 15978 
13285 6350 
9017 47 
13591 13395 
2903 13306 
6142 4790 
7420 15958 
6529 1667 
11211 4452 
1715 9647 
12671 4896 
13496 15852 
9743 14816 
13267 10089 
2319 13395 
4655 115 
6177 5613 
4207 14237 
894 15710 
7653 9881 
9953 11434 
14038 16065 
1786 15203 
13781 12791 
1107 8473 
12900 10691 
5862 13306 
9585 11213 
3559 13395 
1570 9041 
798 13306 
3023 164 
12504 12234 
12603 10446 
13306 9472 
11246 5664 
12248 10157 
5565 15528 
4696 4064 
14922 14146 
7453 5582 
312 4091 
9794 8640 
10059 263 
12126 15481 
14781 6476 
5582 13483 
13306 7732 
9946 7546 
11625 663 
8916 16006 
3595 4155 
11924 15411 
1343 3391 
10177 13267 
14611 6638 
4360 16198 
13227 6476 
12051 890 
15759 15223 
11203 12176 
6107 16198 
15354 4207 
2192 11461 
1628 11673 
11957 1104 
7420 11980 
4233 7420 
4790 205 
14561 1842 
5849 15710 
9238 8788 
13253 6003 
4504 13227 
1177 15742 
5488 13923 
7653 2891 
10691 10386 
9531 12559 
14199 5336 
472 12304 
6985 16198 
12030 8886 
6541 5699 
473 9041 
15354 11191 
10691 6544 
948 13411 
71 9176 
11461 9507 
15671 13110 
9946 11246 
6476 12928 
1391 1104 
4846 2102 
11133 10860 
7420 6144 
6608 15470 
3358 3357 
14382 14221 
16108 13359 
12791 8896 
12877 7420 
5336 9156 
15342 7766 
8201 10157 
2703 6811 
6985 13267 
3886 9176 
472 9041 
10552 4268 
12760 6886 
16028 15203 
13192 14246 
7498 9572 
7324 13267 
8653 9743 
5161 14063 
16198 12232 
9490 12997 
15229 2796 
12471 11787 
8053 7182 
15399 6347 
9885 8233 
3645 1731 
11541 15334 
3179 13227 
16336 12514 
1763 3445 
10691 71 
14437 7420 
11980 9946 
4418 15701 
13781 8457 
15312 14313 
7987 8844 
8965 13873 
3563 6541 
7420 890 
14445 2102 
10059 13929 
6876 1946 
13690 6726 
10089 11766 
13306 13049 
4539 13051 
115 13929 
2115 14017 
10191 15276 
10682 12157 
14302 1736 
11077 3295 
8191 1177 
4207 1763 
7420 115 
115 14906 
12513 124 
6651 6075 
13192 101 
2601 1093 
2172 9722 
7570 12893 
472 7415 
338 14829 
10064 2102 
12389 8209 
8744 2707 
9946 16028 
728 10386 
7476 15498 
15171 915 
10089 9075 
13455 15963 
2048 4249 
15012 513 
6372 9743 
15223 14765 
11774 4270 
3277 3974 
7160 10446 
15308 14744 
14394 10586 
1769 14744 
1160 11734 
5187 392 
11457 13548 
466 7420 
10446 7460 
12248 1467 
13395 15354 
7778 12494 
5109 13227 
10374 8732 
12997 15980 
472 6121 
11879 4867 
1148 6638 
4215 12633 
8893 15223 
16188 11745 
15444 9940 
9594 5702 
15230 13227 
2228 6144 
15470 6215 
3449 7507 
12326 329 
10446 4569 
14437 8343 
1212 10435 
13267 3816 
10064 3449 
4937 1104 
13227 209 
6541 8916 
11023 11767 
14785 5244 
11377 9887 
16198 15928 
16093 5488 
12199 15354 
4788 15378 
2068 10265 
3287 1467 
7420 6335 
1467 15160 
6112 3567 
13306 3826 
1448 13667 
250 4222 
9946 1459 
2360 5613 
9124 14038 
5921 14641 
5865 10947 
11350 4669 
5750 7356 
14595 2830 
6317 15710 
8853 2981 
2544 3584 
14733 11045 
7984 5862 
1619 6541 
3287 15540 
10157 15488 
12157 11356 
15537 7420 
6464 5243 
2284 9802 
12570 9880 
13360 7471 
4801 9240 
13107 15283 
12342 4612 
6380 8062 
2071 15342 
14076 6006 
6859 13544 
13702 8832 
196 8300 
7420 4775 
5849 1008 
3804 1569 
12791 7420 
5122 12176 
4912 3246 
1262 7420 
4032 12962 
1391 1576 
3067 6177 
8916 9902 
14268 15160 
5163 5028 
12081 1894 
12466 472 
11591 13009 
394 2902 
7145 3583 
9860 1517 
15223 4382 
374 15501 
4215 7420 
10080 8163 
13231 7570 
14719 8628 
7480 8355 
7636 12791 
7420 4322 
5029 4207 
6015 16198 
6757 6064 
5461 6144 
4133 6859 
7570 12519 
15354 12760 
71 16289 
15332 13267 
2102 5125 
3357 12316 
4669 10157 
8193 4457 
3484 9743 
629 1046 
9947 10064 
15245 14755 
5984 1711 
16108 1890 
12960 9472 
5974 3936 
15354 13306 
4249 16062 
9269 4788 
4271 4863 
3110 11763 
7420 4207 
6703 6419 
7420 10691 
7959 382 
10386 4360 
6766 11341 
513 7895 
10955 1946 
14816 14091 
7515 4339 
11948 3226 
2283 2102 
13119 15758 
13771 13535 
9775 12760 
9313 2981 
6419 11325 
12119 12071 
11951 12962 
4669 7420 
9946 12176 
629 3300 
11980 6450 
15354 13401 
10469 14437 
2264 7061 
11461 8875 
12760 2925 
14212 7229 
5963 2102 
13636 1287 
12389 10778 
16028 12851 
10265 7824 
4453 13227 
7420 5428 
6107 9621 
12851 7420 
8193 785 
6504 12929 
4317 1619 
13306 4696 
4254 1785 
7620 11457 
11587 1735 
1763 8072 
15399 14719 
9743 394 
11325 8811 
337 10904 
10653 1488 
394 3307 
15488 5556 
13395 15289 
11023 2813 
12823 3391 
8596 9269 
4207 9238 
5276 1124 
11148 4091 
15175 5517 
9841 14357 
6464 11333 
2233 7476 
3595 7527 
14748 732 
14825 11980 
2301 1894 
3641 3645 
16028 10656 
4781 11077 
6701 5243 
10619 10446 
14755 12023 
1046 1124 
15767 11613 
1212 627 
4696 13679 
14646 12948 
2022 8754 
4863 1391 
3904 12903 
12071 3657 
9691 13267 
10374 2074 
11879 6686 
4922 13192 
5292 14246 
9624 5095 
6726 14408 
10904 1263 
13192 15308 
14063 12817 
15223 11045 
4612 14210 
11226 6486 
12130 16218 
7480 9621 
9946 10619 
9775 7653 
1517 6476 
7476 839 
13276 13395 
7906 13395 
11563 5670 
15074 5956 
14896 2284 
5064 12583 
3144 1946 
6121 10250 
8208 7984 
3974 1365 
13267 10080 
13996 7420 
7820 13683 
9231 3639 
4565 10822 
7691 9472 
3433 524 
9506 9583 
12061 8744 
15526 1607 
6985 2022 
7437 7420 
13192 9056 
2346 115 
1506 9766 
2054 2861 
5177 9743 
9019 954 
13556 10089 
6528 5363 
4207 10467 
9262 12130 
9716 1763 
15978 7229 
329 10446 
472 1803 
4879 9041 
10386 5876 
4605 9910 
11121 7204 
5125 743 
7813 4361 
1743 937 
9007 54 
2192 8965 
15470 9290 
10735 732 
9743 10357 
1375 14064 
5503 10144 
6343 2601 
13843 14419 
2054 13267 
10064 8853 
7277 7588 
14882 3974 
9743 2102 
10157 1428 
9263 11931 
8384 1038 
15180 9743 
6144 13352 
13929 8780 
2544 1467 
4953 7420 
15012 14505 
1038 3974 
7608 911 
726 3551 
8916 9953 
2102 10013 
9124 3721 
7095 15192 
4066 6036 
15689 71 
2022 288 
8832 1551 
12791 10064 
3589 9450 
15276 12929 
10304 1607 
6476 2871 
15561 7937 
911 4064 
12234 12429 
15223 13395 
406 10627 
9982 5125 
6439 11461 
6703 12555 
1212 11696 
4940 6568 
1706 13306 
329 6961 
6476 11246 
11767 9887 
11933 13267 
6770 5292 
3645 8118 
2981 226 
7078 12851 
5481 12248 
10056 2102 
115 4207 
6000 14146 
13227 743 
12728 2022 
4222 6541 
5933 1731 
12534 1046 
15571 10802 
16126 14946 
13861 7452 
14237 12823 
12997 9144 
9184 13872 
6889 1019 
7145 7420 
13306 9494 
6434 13207 
805 12790 
11297 12157 
7360 10446 
12891 4609 
7420 12919 
9145 10064 
3443 5004 
5382 123 
16327 3391 
5488 4207 
306 5187 
2284 16011 
13843 13192 
5054 3595 
11326 2074 
11560 9208 
7546 10250 
6075 5243 
15354 9332 
11591 7238 
629 3023 
8844 15488 
11980 13548 
2703 5054 
6726 12555 
10184 15293 
15103 12851 
1159 1569 
16000 13843 
368 13192 
8969 6177 
5309 2231 
9641 16028 
15223 10446 
12948 6477 
6703 9946 
9811 9953 
4360 12929 
14382 998 
6886 5779 
293 7945 
9598 15822 
3456 8297 
5741 4207 
7402 1551 
11333 10050 
13267 1655 
71 9741 
663 1391 
6985 7032 
15223 9841 
12791 12760 
13548 15985 
13360 2824 
3433 7032 
10028 10789 
1576 1795 
6299 14829 
4207 7016 
14709 15767 
6442 1046 
119 10683 
14159 11880 
329 6669 
16198 418 
8525 13554 
4589 4452 
13548 10857 
14063 1514 
308 15354 
6259 4672 
7420 9946 
13332 11457 
10936 115 
14922 4215 
7753 12157 
8831 11864 
1040 13670 
10064 10741 
1883 911 
2953 626 
12754 1551 
9259 12753 
5827 8343 
2589 663 
2170 3277 
3486 9097 
309 9572 
2871 4207 
15127 7719 
15795 15276 
12760 12095 
13267 5488 
10316 12851 
3548 4207 
839 12157 
14478 11715 
7420 559 
3411 2677 
14059 4092 
1464 663 
13395 3484 
11481 10691 
7420 10433 
7054 7420 
13396 11587 
3449 3913 
13360 9238 
9946 2703 
11575 7420 
1238 2048 
9946 9124 
3553 9953 
11246 12711 
226 11933 
10525 13045 
15354 7476 
5376 8119 
3721 13817 
6095 3117 
10619 8193 
7587 6075 
9743 4694 
5423 3551 
4370 472 
13227 1667 
1551 4912 
14445 7685 
12095 11560 
7452 443 
10726 14861 
12494 4612 
9904 3595 
1877 3445 
10057 1784 
14199 1551 
11461 5769 
1364 5865 
5530 9946 
9450 8640 
13401 1946 
5243 1896 
13880 15012 
11243 71 
8640 7420 
12656 12760 
6686 12199 
3639 8300 
2544 443 
8316 7274 
14823 10582 
15822 7078 
5996 15269 
9275 115 
11591 8640 
9494 15430 
15269 1104 
1405 7420 
2793 11819 
726 6537 
13227 10596 
3391 293 
4295 16381 
5608 15184 
9504 115 
5325 11879 
5381 12493 
9772 3144 
13754 1677 
9613 1731 
4331 15192 
4067 12791 
15223 5759 
15276 6534 
14807 15012 
12061 13306 
5088 12726 
9946 14437 
13360 5670 
663 12691 
12234 12760 
11164 13613 
8844 3117 
12760 7095 
15916 8118 
10499 12960 
6089 10475 
329 394 
14866 12831 
12559 9456 
8947 7420 
1536 3594 
13544 9953 
1212 13735 
10693 9953 
4207 5797 
14199 4665 
15223 7420 
10936 11980 
10446 1848 
8832 1281 
15809 15328 
10494 3433 
115 8231 
619 7263 
952 10882 
14382 4848 
1008 4600 
8119 10877 
472 6561 
7002 374 
12941 2794 
3645 12760 
13284 15223 
15498 7570 
9124 10477 
5301 4696 
2902 12803 
13227 15127 
15223 5469 
14237 14345 
160 6859 
11752 6667 
896 1212 
7984 69 
7476 8621 
3164 8788 
13227 12817 
3850 2203 
13771 10140 
13267 10446 
2703 12559 
4027 12760 
10519 4392 
5054 15399 
9471 308 
3449 6455 
115 4354 
12120 7054 
1519 15012 
13843 11461 
4302 4911 
115 2601 
4689 9545 
6827 6434 
5491 16188 
5378 12494 
13306 11767 
1290 16165 
9464 14420 
4612 12791 
13666 2283 
5315 5028 
13861 11333 
6055 9946 
5493 11121 
9615 2105 
14920 10176 
15192 3433 
15470 5623 
16198 205 
9492 8300 
15399 13256 
10955 1772 
3595 5250 
8289 3983 
1517 5088 
71 6522 
13639 15902 
5147 15498 
1519 14211 
15180 472 
1277 12429 
6834 10488 
973 3214 
5507 12248 
3121 16188 
5125 7470 
6912 9953 
12817 4981 
6769 4942 
7420 9887 
12613 4750 
4354 3117 
5125 13360 
4295 3563 
11488 1772 
3728 15223 
6036 13267 
13929 12760 
13267 4207 
3558 7452 
4879 13395 
12760 7452 
9124 11407 
14647 16028 
12504 3551 
5149 5389 
12851 16336 
69 15009 
1111 13306 
15963 15742 
10505 7702 
15824 12005 
2908 10656 
3476 726 
7071 13306 
11250 11879 
10446 12583 
7862 13426 
12429 5197 
10233 5309 
15192 7420 
10083 10013 
6645 14866 
10088 4968 
13754 222 
9641 2129 
13227 4981 
3915 2102 
1890 1104 
14468 8640 
15710 5876 
12234 4958 
10106 7420 
3833 13267 
4506 4215 
3305 13427 
6343 2440 
11121 13395 
8823 3305 
11552 8289 
12000 11475 
9743 69 
14530 11525 
15166 5517 
10064 11934 
15192 11525 
3107 663 
9124 123 
1946 8832 
15223 472 
1107 6000 
16108 3137 
13192 15175 
11148 10849 
11407 14781 
16028 1391 
3817 6834 
12617 6912 
9743 7420 
11565 8343 
12711 11655 
15830 12760 
6814 7344 
115 13227 
10422 15222 
2102 3433 
8583 298 
15706 15561 
9097 2305 
548 8656 
12466 10734 
9350 15978 
16198 8227 
14825 10735 
9472 15195 
1619 13156 
9946 7507 
7457 13996 
13192 1506 
5866 7452 
8744 15816 
12429 4615 
15824 9312 
12098 16028 
10691 13319 
10511 11980 
1908 69 
6144 15936 
9841 9765 
5488 5507 
8838 9426 
12760 115 
11752 133 
853 3391 
15883 7420 
15928 2102 
5004 15313 
12527 15268 
14966 1488 
16291 293 
1177 3735 
11980 1004 
13458 15283 
11203 3295 
15655 4323 
2129 4155 
3195 115 
9176 14239 
15354 13996 
11469 8575 
11246 16007 
3098 4207 
10933 10072 
6121 9124 
71 9723 
10446 5591 
12127 15992 
15795 4890 
4207 594 
12071 14836 
10446 12688 
5326 9953 
11015 11752 
1096 1104 
1619 13395 
12429 11924 
15529 13267 
12030 15945 
6476 15354 
6859 3536 
15074 13051 
14882 14922 
12760 14093 
15980 11461 
15684 5613 
5382 3226 
11461 6299 
77 11735 
13457 9674 
10540 472 
11457 3742 
5276 14719 
14796 8890 
9797 5727 
7229 15919 
2999 13306 
7936 4215 
7583 15354 
11946 443 
12110 5859 
9716 14807 
16226 7145 
10446 3117 
209 6036 
11734 5613 
15223 16339 
543 804 
15354 12494 
6726 2102 
4215 115 
10064 7420 
12948 5412 
16198 13306 
7288 9775 
7420 5996 
7945 12391 
3829 6361 
4404 3305 
13267 3488 
8490 4890 
11022 1148 
9203 10446 
12948 15797 
2763 14990 
5309 4244 
10260 6050 
15223 10479 
10374 3098 
2287 11525 
10087 4372 
10469 14623 
15508 15710 
9887 15223 
9545 14748 
16028 10679 
15623 7471 
1104 4215 
15103 16091 
12234 9562 
5863 13872 
5983 4270 
7124 2022 
3829 15993 
15410 4207 
3295 8721 
2981 4751 
783 9479 
2283 13992 
798 13140 
6806 2544 
3511 7866 
4845 7420 
13395 4981 
15530 15329 
6726 559 
7032 5586 
11945 7095 
15975 3833 
8807 14253 
10642 15223 
10889 11195 
4781 13996 
7460 4155 
15689 7420 
71 5513 
4699 14705 
9953 8621 
1272 6036 
4954 15354 
11064 2 
15501 13192 
3117 6541 
8156 1104 
15487 6439 
13267 15488 
6726 11275 
5019 3358 
1607 1104 
6287 10050 
3278 11413 
8811 816 
4018 12893 
7491 5122 
12316 3357 
7095 5938 
6036 1985 
5469 5491 
8763 472 
13295 8844 
10691 3117 
7420 9464 
9504 9072 
9572 5865 
5759 10577 
1350 5507 
663 1946 
14239 7420 
11457 11879 
12948 15937 
7021 12903 
13441 13019 
1890 14167 
7560 6901 
7461 5672 
10734 13192 
7420 13234 
4355 209 
8965 13395 
10083 13754 
15354 16007 
3436 2074 
4790 2995 
12534 6985 
6164 12760 
7801 15641 
4321 12429 
15329 8449 
15567 8472 
15219 2806 
2887 7021 
9652 3776 
15980 5352 
663 4207 
5797 9075 
8965 15745 
11250 11696 
2496 12791 
15671 9737 
293 8161 
10157 13342 
405 14697 
13771 6140 
9946 9997 
9450 10415 
4788 15928 
10169 4935 
14017 10691 
12527 14922 
10059 13036 
16188 14920 
10064 14780 
4890 2487 
14804 9504 
7420 10825 
15223 10446 
728 4321 
14680 9743 
239 14747 
14922 11673 
15980 6217 
3833 10849 
951 5915 
1046 6667 
5991 472 
1763 14807 
1518 12760 
15980 11722 
7420 8656 
1343 14347 
13395 11879 
14437 2703 
16188 15012 
14237 10479 
14376 12157 
1551 7071 
14741 7662 
15223 5125 
5638 3196 
14785 1619 
10627 10157 
7420 4207 
15470 14199 
15230 329 
4361 8216 
1946 2064 
4788 10080 
2703 14382 
5797 9394 
9075 16243 
3287 7507 
12429 4548 
1127 7570 
15684 3967 
16382 7420 
3245 8947 
9733 9946 
15978 10064 
9464 10955 
12110 5984 
11505 11325 
8490 5670 
5675 7420 
9946 6036 
10691 4788 
374 13450 
12926 2707 
13941 1082 
12791 7160 
11133 4137 
12119 7360 
11518 5216 
3305 8327 
14478 4669 
16336 8435 
2102 4900 
2703 2102 
16116 3117 
15171 876 
10384 1467 
4380 13227 
4448 16260 
14571 4067 
15528 1715 
10064 8193 
10050 9493 
3449 12948 
13591 1908 
5849 12472 
12565 8744 
5750 11160 
4896 705 
7983 14304 
7420 9464 
13688 15859 
10224 5149 
1239 11696 
7480 13306 
10479 15530 
7804 14128 
7476 3718 
14577 15526 
472 13227 
6509 8300 
14437 15858 
393 6447 
4314 11023 
11160 115 
9114 1576 
559 12157 
13401 421 
2831 13227 
3905 6782 
14866 115 
8356 16007 
11493 2102 
15223 1421 
10446 11267 
4688 14719 
394 12637 
14812 10089 
12234 15710 
11325 4064 
9953 12776 
9100 9464 
8551 8965 
5613 10047 
115 11484 
11939 8773 
5991 2861 
15610 1017 
2170 13045 
11163 9736 
11980 10920 
8754 3750 
3295 3461 
10329 5301 
2339 4032 
329 10747 
10427 15824 
14816 3433 
13754 8656 
7420 12833 
11445 4612 
6234 7420 
13548 10384 
5613 1012 
7420 13036 
11855 1667 
6426 15894 
12071 8289 
7723 10108 
9479 16301 
4050 2054 
4612 9072 
8188 10691 
2102 9946 
6686 12429 
13670 12628 
10446 6075 
8998 7508 
12760 1046 
13965 11879 
9953 11148 
13306 13306 
3335 9946 
3305 12005 
13360 3295 
1298 5273 
13890 2137 
8137 4310 
8735 16011 
8470 4707 
12110 10747 
765 14037 
4324 5352 
15537 472 
6023 7708 
1802 329 
13809 1280 
5069 2333 
5162 12429 
14859 13395 
14781 12023 
5875 16198 
11964 5342 
10068 4790 
98 13267 
10632 394 
1763 7420 
12379 12899 
6177 1743 
14199 4761 
3551 9041 
5911 12948 
15223 15223 
11457 3449 
472 13227 
11148 12555 
3041 5232 
6726 2589 
2 13794 
11563 13395 
16011 15223 
9585 12995 
1724 1212 
5991 14382 
594 705 
4207 7420 
8191 7967 
15160 5880 
783 12061 
10446 7471 
3466 6686 
5517 15919 
14780 12466 
12653 7777 
10386 10945 
14344 13094 
9794 12760 
12555 7420 
12248 115 
9504 13257 
6036 14382 
16237 13362 
15354 1467 
4790 14382 
15742 8844 
13267 642 
1735 5216 
8838 13189 
7550 3449 
9946 5031 
498 205 
9019 14922 
7657 466 
1343 6036 
7420 2646 
14829 6316 
5676 8640 
8062 10250 
12420 8131 
6985 15347 
808 13306 
594 7608 
8135 4320 
548 10446 
13817 12159 
4863 6486 
12929 15742 
14239 2981 
8289 5740 
15848 9240 
13066 4064 
4570 4600 
4207 1416 
15765 10446 
3721 11964 
472 4072 
1093 6985 
5517 4299 
14922 7705 
14687 6985 
11297 16317 
16333 12093 
654 472 
11522 15354 
5582 6177 
2687 12861 
3592 3639 
16381 13306 
15814 12266 
4800 12030 
2793 9953 
13395 2102 
3551 6519 
1731 6686 
12893 2808 
9743 6998 
1619 9946 
4919 7507 
5222 2205 
9313 15530 
9765 1696 
15767 14579 
11246 16028 
472 14093 
4515 2687 
15354 1769 
13227 6036 
15192 13992 
10307 7460 
9953 1437 
4529 1896 
8965 11715 
15734 9946 
11148 10013 
5983 6859 
14237 8233 
7356 14420 
5301 4879 
10324 7472 
4672 6279 
7507 14623 
12342 14199 
4530 12559 
7520 12415 
6901 10299 
12929 5197 
7356 13861 
13110 8233 
8289 7356 
15192 15894 
7360 10089 
9472 12935 
15797 5797 
14821 16007 
5125 16339 
7420 6450 
759 14719 
3583 5232 
13227 8231 
3117 12851 
13591 8965 
4067 15354 
11361 13192 
663 15529 
11268 115 
472 14128 
13411 10726 
5216 12851 
16188 13306 
15683 1607 
9041 13615 
9802 9041 
15074 10446 
2074 1500 
12744 2409 
9829 13276 
12791 6923 
472 328 
15711 14780 
12791 7420 
6036 10519 
6419 5875 
13395 1585 
1619 10983 
12010 4388 
11384 16243 
13267 9572 
9562 13267 
7420 2534 
14898 14781 
911 6859 
7095 3067 
10479 7776 
9325 14687 
1256 4249 
8801 3350 
10691 14402 
10083 6462 
6918 7095 
4689 2162 
9041 14780 
6541 13868 
10552 2461 
6112 9707 
5831 8965 
14808 10373 
4863 14662 
13192 13978 
15230 15354 
296 15223 
8580 3583 
11191 2703 
7095 14303 
119 5366 
5232 11093 
14437 7705 
472 11560 
338 9572 
12935 15710 
12948 4320 
12565 12760 
11964 1743 
15180 2301 
9946 3117 
13285 2926 
15566 7987 
14155 625 
13253 1148 
12584 11560 
9727 741 
5670 7452 
5986 7876 
13306 9804 
7420 9007 
15470 6600 
2054 7420 
8620 2270 
818 3594 
15338 115 
4207 13124 
12120 7476 
8300 2981 
3466 9545 
16188 12467 
5216 10108 
4790 4268 
8894 13342 
11148 14785 
14866 13996 
11924 11983 
13625 7570 
11864 2228 
5034 7176 
7420 6431 
14063 394 
4612 16007 
15798 2022 
3391 6036 
12009 11488 
14237 14755 
13361 3246 
8663 119 
9389 11992 
7017 548 
12760 13909 
13652 4788 
4419 6142 
8890 12466 
1708 8575 
4333 7420 
4207 6347 
3952 8965 
1212 13395 
14659 8083 
2102 1391 
5699 10427 
7983 2102 
15470 8625 
5608 4091 
7420 1551 
115 16360 
8649 115 
8853 11903 
12130 15470 
2039 10467 
1127 1551 
2687 4790 
14922 15354 
6923 13267 
3265 16250 
8467 15035 
12833 2102 
115 12071 
13457 9580 
15537 5991 
6344 3974 
10059 9314 
14432 5159 
12760 13306 
9580 14702 
11043 3551 
4067 13360 
12888 7570 
3584 13411 
15487 14199 
6439 2440 
11673 16007 
15580 5243 
1005 12929 
6304 10224 
6003 5352 
7095 9946 
7420 13189 
7402 1607 
5054 4677 
8251 14744 
13265 13457 
13227 7038 
16381 15767 
3433 6036 
15347 12804 
15283 5986 
1551 54 
7471 12851 
404 14237 
11121 3305 
12760 14821 
54 13360 
10059 15354 
14437 10446 
6901 15488 
8853 10108 
14967 10905 
15293 293 
13754 1569 
12061 394 
10679 5864 
6144 4529 
9238 5507 
2657 15223 
9545 3358 
15740 8140 
9946 11379 
4150 6055 
12061 11377 
8804 333 
5827 9946 
13510 4998 
10157 11461 
12342 1087 
6089 3983 
11497 7705 
11121 4207 
12893 9389 
4790 7471 
12760 15074 
629 14829 
12895 12159 
14966 15337 
6834 11934 
11734 14922 
2666 10619 
11121 15192 
1667 10603 
6726 12353 
705 5740 
14708 4790 
15223 7765 
2107 7765 
15814 5610 
1946 2380 
8233 4696 
8969 6739 
15192 3585 
13306 5670 
11015 12061 
16217 1203 
2980 14780 
8640 7903 
4696 16333 
12248 13843 
1467 4207 
7702 3643 
9881 10479 
8289 1212 
13395 5862 
2983 2088 
6714 15978 
6987 15223 
3184 8288 
4067 54 
5672 8352 
12466 8343 
6935 9976 
7457 341 
7075 16188 
3391 1046 
5087 2102 
14891 3144 
14471 3724 
1411 12429 
7655 9625 
11980 11880 
12551 12948 
15948 12929 
15749 6256 
8947 15012 
3639 15511 
14256 15710 
8886 10849 
7457 11931 
10064 10059 
14561 15474 
6036 10609 
16007 8490 
13787 9163 
10479 329 
12047 4361 
1862 1668 
4790 4207 
4912 14882 
7420 6075 
12429 13227 
6177 1667 
12730 8352 
4370 8548 
4333 7420 
10157 6859 
3257 12851 
13548 13227 
1467 9097 
3305 8050 
4253 613 
176 8811 
1769 1521 
5239 3705 
7279 13367 
8838 7420 
1886 11160 
6763 3466 
9824 15222 
6003 15859 
11093 7460 
1212 3595 
10064 2174 
7460 7900 
7457 12525 
3838 5862 
10679 15219 
4879 13094 
1046 13395 
13306 12248 
10050 4360 
4331 4916 
9641 7420 
12798 1619 
11980 8773 
7420 8838 
6358 3184 
6548 12929 
4696 4207 
16007 12833 
13395 11525 
15365 13267 
12234 2145 
394 10384 
5352 2928 
11574 9583 
9860 7420 
14709 11082 
291 12555 
2459 9641 
9946 13735 
9888 472 
4321 12130 
14650 1058 
6912 14144 
13267 6584 
8947 11461 
3595 13267 
1343 31 
1551 6272 
5461 5125 
15180 16052 
6003 16065 
8700 8620 
12760 5983 
9841 10849 
8422 12948 
8754 7014 
4355 1171 
4021 11651 
9743 13306 
7306 6700 
13319 1763 
12415 1908 
16333 11681 
1753 7420 
4912 13388 
2903 15223 
11879 8969 
7708 1263 
2672 16007 
13395 9007 
12176 7204 
952 1551 
12760 13541 
5197 2355 
16063 12030 
13395 6050 
1391 6217 
14199 10191 
4295 6455 
5481 4761 
6439 15852 
13531 7363 
6257 12880 
4562 15347 
9953 12342 
1082 10467 
14946 13227 
3783 4359 
14862 1715 
15171 7570 
1391 11148 
12000 14484 
14525 16243 
14146 4515 
9989 10446 
6212 3811 
8832 8135 
3983 222 
7182 11121 
3106 9454 
3433 11673 
16198 15859 
13306 472 
10446 1017 
5979 7083 
3142 11735 
11527 9946 
13045 8625 
1391 14705 
13227 9615 
3156 473 
6954 8965 
12030 8949 
15529 15767 
15710 9019 
6686 4334 
6272 8382 
9777 11313 
5444 4222 
8289 9953 
12047 24 
4672 11461 
1695 12535 
9007 11931 
5517 9314 
4912 12929 
15530 11407 
10563 11991 
11829 6552 
176 12997 
13267 16371 
4067 12342 
394 11933 
14823 4504 
4942 10446 
8965 7095 
12227 7471 
16158 8289 
1677 663 
8955 2228 
5670 1212 
8854 15074 
8762 16381 
11179 12061 
2102 12760 
10511 15710 
13667 5054 
12383 13100 
9946 3721 
15354 10479 
1769 15223 
12929 5989 
14485 705 
2703 11560 
2999 2283 
6293 9504 
8965 15858 
8208 7801 
1551 10735 
3886 2360 
6121 4435 
11980 7095 
11641 115 
14829 1100 
6729 11093 
3484 53 
1302 4310 
7476 4707 
1237 15758 
3155 4207 
10276 14211 
13227 2074 
8965 13036 
15223 2310 
11710 3419 
12552 3357 
12095 3991 
10177 1361 
11203 12291 
4021 7083 
15354 14241 
7420 13816 
9716 13194 
69 15036 
12702 16243 
10374 2635 
3144 11461 
1551 7751 
7932 12893 
9974 374 
7620 5507 
472 11614 
1391 4609 
8575 1109 
16088 15192 
4249 5023 
3563 2283 
4351 15488 
4609 6912 
329 11722 
10467 13781 
7420 6095 
1278 11493 
4268 12248 
1052 2301 
759 12547 
2753 3305 
9041 1012 
14744 15418 
16116 13605 
13605 13771 
1212 2468 
293 14367 
3329 13507 
12061 13192 
7945 11478 
10350 2215 
8274 3592 
9641 14384 
3246 7900 
1946 3728 
7420 10083 
12449 394 
12893 9019 
1711 5797 
6336 732 
3776 11133 
10954 1156 
7160 5250 
12429 15223 
9494 9777 
7420 7608 
6952 14092 
1946 10725 
8233 16260 
15570 9946 
374 6859 
3595 10064 
8941 726 
71 15328 
2673 7172 
4125 3272 
9351 101 
7688 10933 
15526 6144 
5991 12570 
12309 9442 
10316 2703 
13192 14093 
15677 13588 
10324 15223 
16080 9750 
9670 329 
3449 16150 
9743 2890 
8965 418 
15558 4207 
12598 12760 
12870 4357 
5216 15470 
9641 6726 
11246 5797 
11290 10246 
9641 14866 
7570 4612 
4032 8580 
1104 7636 
12616 1212 
10080 1086 
9940 14423 
6272 7099 
3563 8170 
6859 6177 
4295 7420 
10059 2534 
15354 6503 
4190 14199 
13950 3433 
10691 3466 
3697 10357 
8289 9674 
10059 8715 
10446 13036 
7476 7903 
5623 8832 
5079 537 
3433 7824 
9388 705 
16188 1607 
6316 250 
205 10083 
10419 6509 
7625 11980 
5765 2129 
13702 8287 
1852 3833 
9743 13992 
10857 9946 
13045 12760 
1171 15742 
12140 11457 
5529 8899 
9472 10470 
12139 10735 
5088 8969 
3643 6347 
115 2316 
7156 13395 
8656 11116 
11964 16007 
9472 12851 
9572 7476 
7078 6901 
12760 16028 
4788 3098 
8965 6170 
1894 13192 
1946 13843 
13033 11095 
4696 9041 
11767 9242 
9641 13395 
9162 11763 
1343 15223 
8965 9935 
4863 5670 
10458 9124 
1946 5637 
345 9075 
5670 4133 
785 1729 
14611 1715 
4295 1903 
13996 521 
9946 9722 
12093 11626 
12248 14821 
11477 15187 
14816 3391 
1551 124 
1391 16333 
15354 3790 
13395 16188 
10949 4947 
3144 3983 
4947 15671 
15470 8596 
15526 15859 
1965 15354 
12948 13400 
7420 2586 
11641 1639 
5382 16317 
5177 2236 
1946 13306 
2629 2283 
16336 14495 
7756 11250 
16007 5864 
7171 11980 
1315 15436 
13947 12851 
10734 4373 
9743 10475 
7182 4790 
11641 13360 
6541 5637 
12248 12342 
12478 12791 
6036 5955 
2203 308 
16150 16007 
3866 9328 
5152 15187 
7420 6036 
11121 13395 
14038 1735 
2102 15354 
13097 9546 
8449 4696 
10083 14848 
7814 10691 
13360 1467 
12527 9743 
1101 1104 
13227 7420 
5028 3155 
5507 12903 
11626 2735 
7584 7422 
14525 466 
3305 13306 
12948 15354 
14114 9479 
9269 6726 
11964 9605 
263 9013 
13401 7041 
6267 7022 
1946 6419 
115 6859 
14744 11991 
7888 4376 
12997 9775 
9926 7420 
2601 15958 
15470 5983 
15012 16184 
15894 15186 
9641 10040 
15223 1148 
5020 758 
7420 1046 
15710 580 
5289 13605 
12929 382 
8969 3740 
9212 12255 
8965 12157 
4207 15824 
9802 360 
12157 9235 
976 16028 
11560 2035 
3151 13360 
12558 5276 
10446 11093 
11883 115 
3449 1160 
16028 12711 
13974 5488 
9743 472 
13189 14144 
13819 14382 
3589 9743 
11457 13641 
9641 13395 
6142 5451 
6637 15429 
9238 15192 
16007 365 
14785 11571 
10176 10090 
9410 3699 
11461 16198 
10983 11924 
2102 16150 
10797 9555 
9743 15368 
10834 3991 
293 14471 
3449 9572 
15365 7182 
5979 2703 
7420 6985 
2928 6439 
4204 3776 
4386 4612 
4804 2862 
1263 2953 
6036 2468 
13267 7201 
11929 12851 
5382 10747 
12760 12891 
4249 15742 
15347 3121 
890 12929 
7476 5597 
3274 7420 
5805 10668 
3287 9504 
7620 13450 
1212 4067 
1708 10511 
13360 3488 
11213 6375 
15223 619 
14159 15710 
6177 1735 
293 13227 
1093 6568 
4911 16333 
222 14825 
14237 7058 
7723 727 
4207 9389 
619 15488 
15490 10064 
4896 10132 
14882 7562 
10176 12808 
14922 9041 
16028 12065 
16198 9743 
115 15223 
16169 12760 
7041 309 
14437 1727 
5670 10028 
5699 12504 
10642 13941 
15742 2703 
7919 14750 
11133 2626 
14611 9946 
12760 663 
13227 11457 
15299 510 
11430 6541 
3549 2544 
10479 11525 
7420 3635 
15685 10658 
10725 13306 
12223 13457 
10059 5579 
10446 1393 
14990 7708 
7476 1551 
9887 15988 
15974 8628 
12893 2203 
12255 2544 
13843 9978 
5477 8965 
5323 5797 
10059 12071 
3461 13045 
12429 759 
9624 4305 
2060 10691 
13272 374 
11246 6476 
16312 11518 
7420 15223 
115 7827 
11167 8969 
1897 5074 
10691 4706 
9041 12893 
13367 3111 
5232 8353 
9764 16198 
8811 13124 
12791 619 
3551 12248 
15203 7279 
15354 9450 
15005 14419 
11246 16198 
12496 594 
15276 15219 
11148 10908 
12157 5765 
2902 15103 
14888 9238 
1450 5469 
4571 12760 
1008 12020 
8208 15818 
6234 14382 
14394 472 
1104 8527 
14367 6686 
15528 208 
394 5243 
1908 4244 
15223 101 
115 5243 
15899 4137 
6235 3728 
2793 5216 
9886 4728 
14036 13306 
8131 11931 
1747 7357 
1849 1052 
12565 9194 
10089 4215 
9953 12482 
14167 13267 
7420 16108 
4155 8969 
3804 12791 
8688 12988 
3321 7229 
14922 10080 
5797 5797 
14802 4207 
623 15230 
14755 1445 
3433 115 
2215 9577 
9389 2073 
13134 13189 
5079 9946 
11325 14729 
472 6912 
11077 10050 
3252 14472 
14501 10157 
160 6541 
2981 8233 
4207 10475 
3057 5613 
15635 3335 
13306 8558 
450 10619 
15180 14781 
1124 4320 
3029 12030 
13387 12157 
15354 13267 
7402 4696 
5243 2102 
12948 9777 
14212 11980 
12798 13362 
5087 14785 
1171 12791 
11185 7095 
13306 7570 
2102 1145 
5619 1467 
8916 2731 
4270 663 
10863 1786 
15530 15187 
5451 4877 
4788 15288 
11681 10411 
10479 8140 
5517 1046 
11121 13306 
15354 5074 
9982 2054 
3645 6272 
3703 8969 
7420 7420 
15269 5670 
472 2102 
2278 11461 
11980 9957 
8496 3433 
15470 12346 
115 12449 
8575 8838 
16198 6036 
8343 13681 
7751 5661 
11560 472 
16333 2192 
1946 3551 
12551 5672 
10710 13843 
4696 1093 
15088 2846 
13036 16055 
5243 9388 
4726 9621 
4981 1782 
15765 9743 
4917 9124 
15074 15289 
8773 13227 
9743 6839 
11641 10059 
14866 14061 
560 4050 
13267 11589 
3351 11917 
13306 4887 
16198 14793 
12030 15347 
2067 8969 
9585 9946 
5641 5336 
3287 14199 
11320 698 
10094 4696 
8965 2429 
15992 15488 
4506 1212 
6486 15963 
12162 5125 
12760 7420 
10177 9166 
1842 10479 
15507 5797 
7152 9743 
13395 5368 
9641 466 
10691 124 
312 11779 
6144 4612 
4696 14898 
663 9014 
7336 10825 
13395 4331 
4155 13395 
9224 4981 
5309 1259 
7420 3584 
13306 1004 
13437 12234 
10479 4295 
1772 8847 
11933 16007 
11297 2102 
7636 394 
1946 4207 
15347 3910 
10517 15824 
10848 3246 
5488 11601 
15107 12791 
4707 15347 
3383 16126 
15992 7420 
3724 12011 
12157 705 
14076 16198 
11569 2988 
4155 16116 
8965 11393 
14579 2022 
15710 11229 
13227 15913 
14866 15222 
15195 15671 
2784 14382 
3833 743 
13306 3983 
7003 15192 
5292 9504 
732 13160 
13222 7420 
7620 1731 
5071 2219 
15015 633 
12997 11980 
3391 14445 
329 14472 
2192 2283 
5670 8300 
71 7608 
10467 10050 
5145 3305 
7099 1551 
4066 16243 
15192 15276 
6726 3941 
7420 4612 
4215 7377 
15710 10089 
7071 9743 
11980 5087 
2054 2753 
9589 13227 
5358 7340 
5438 6985 
9621 9982 
9295 10038 
3764 13227 
3257 13267 
2283 1171 
5613 10064 
15365 4781 
4299 1201 
10064 8227 
10050 7712 
13227 9946 
4947 4207 
13227 13567 
3433 14437 
6270 11246 
8711 9141 
14525 7594 
15773 14922 
9743 2292 
12948 2706 
4696 10446 
4612 6797 
7583 15529 
5315 2533 
9946 1896 
16122 12130 
12030 6086 
8490 705 
82 5463 
9775 11823 
8208 8735 
15809 10080 
1869 3869 
10446 2020 
9584 11246 
9504 5054 
2703 5535 
10020 2707 
10691 2172 
7967 12760 
5054 9841 
15599 14034 
16063 13395 
10089 705 
3449 13395 
2981 16336 
8754 15354 
7420 12891 
11991 13369 
5613 8969 
10316 5849 
4656 12429 
15530 1251 
16014 4268 
3144 11933 
16294 10059 
5797 12071 
14485 14781 
14765 9212 
2102 11767 
12034 1467 
5292 2102 
10177 9124 
2928 5074 
4032 4207 
1859 12997 
208 2687 
4302 115 
10059 5759 
13272 15462 
543 2534 
10064 2496 
7039 1724 
13267 12130 
13332 10446 
10735 16294 
7420 7420 
71 11077 
13771 11246 
10137 7420 
1093 15870 
4099 12365 
15036 4696 
4321 14859 
14268 4790 
6701 4207 
7134 6826 
13690 7801 
1763 10857 
5654 6738 
15488 6112 
16198 10469 
15530 3794 
559 4207 
9124 7420 
9621 10287 
9124 12047 
3433 2170 
7038 10561 
15496 8343 
1772 1898 
12481 2687 
14199 3214 
7095 1619 
9743 1051 
14174 15223 
4404 7420 
7588 10287 
11879 6826 
6036 9881 
15354 3974 
7307 10918 
3110 12851 
5071 14859 
7881 13735 
15543 13306 
12760 9456 
8188 15824 
15354 9641 
629 4882 
10446 16381 
6404 8580 
7570 14821 
957 6901 
15283 4152 
14418 3721 
14667 12326 
3897 2102 
4912 14465 
1896 15229 
5074 16116 
9198 9242 
1093 11461 
3307 10849 
9765 12132 
13556 7182 
9127 16240 
16333 6036 
9525 472 
5510 5488 
381 2792 
4207 1212 
3433 13227 
4928 1639 
1890 12791 
10682 7588 
5466 12760 
16198 7562 
15166 10177 
15354 13395 
15481 14780 
10632 8844 
9641 3322 
8068 7813 
4249 1896 
15470 9743 
9583 7334 
5232 8969 
3295 12565 
2468 8969 
15470 12429 
1428 13227 
4207 10769 
14076 9743 
11591 15223 
6217 551 
3449 12760 
5744 12760 
12948 13858 
1093 11826 
12073 5187 
2203 4050 
6859 6726 
1619 2703 
2988 15530 
1124 13267 
10582 12851 
9953 3415 
6764 8965 
9765 2102 
7984 9584 
12851 6645 
10446 13868 
2414 4666 
10552 4696 
12429 13267 
6837 9314 
5759 15354 
12248 6121 
13267 15283 
4846 9860 
3584 6859 
3728 12929 
1619 7420 
472 9143 
15710 548 
9935 14437 
11803 5507 
15444 4155 
15289 13227 
13556 6177 
7476 11457 
3117 6985 
13030 15488 
472 8910 
8300 9343 
4883 10064 
4775 3724 
15774 6390 
14199 5613 
2189 1104 
4565 4072 
5090 584 
3449 5336 
9504 1016 
12248 4406 
15694 3595 
3433 6726 
5187 9224 
1486 805 
5118 7420 
8969 4672 
13360 1711 
9743 1781 
12030 12157 
1464 12552 
15192 10433 
3549 14672 
374 10691 
6177 6036 
4222 16105 
15223 13425 
15488 12929 
6801 11441 
3592 7678 
2102 10089 
3433 2703 
12808 14360 
12988 8754 
7165 7257 
5170 1148 
10849 12760 
629 14442 
15488 2769 
594 14747 
15992 14922 
562 13267 
10185 16208 
9577 2981 
10446 12069 
14985 13227 
6738 16150 
15554 12248 
2495 4600 
4302 6859 
3466 1472 
16175 3020 
12157 2470 
9504 11795 
4655 6036 
7171 15818 
472 11855 
4244 1890 
13992 14382 
11325 5670 
5477 6144 
10505 882 
6849 4893 
8566 4302 
2102 11077 
5272 2319 
2172 1681 
11781 14237 
9124 3551 
5744 1735 
10260 4612 
14807 4207 
5670 8909 
6519 14199 
14159 9124 
13810 2790 
15920 12277 
16198 15223 
13723 6121 
13395 14859 
115 10479 
13388 10089 
14780 2048 
7420 8656 
16266 3144 
13781 15175 
16198 16336 
5876 4066 
6539 15162 
9946 12551 
954 5479 
15309 11148 
10083 6726 
594 6701 
15796 2102 
3107 6132 
9946 5162 
15413 9841 
6726 5634 
16243 8490 
4207 2981 
14734 14922 
6434 1359 
5125 14063 
4207 4220 
11774 513 
3030 253 
594 11591 
5638 9585 
12494 9124 
6764 1551 
9072 2102 
16028 12598 
1094 8965 
5292 1763 
14132 12851 
9743 1501 
9946 8208 
1715 2022 
13996 4032 
13401 13227 
14092 16333 
472 9123 
1682 2928 
11093 4439 
1046 13996 
5517 1391 
10479 10446 
9919 12058 
16155 11077 
13754 13735 
4846 10059 
3941 14423 
6343 6439 
2568 15354 
11734 6726 
5310 14437 
1711 6468 
15223 7078 
8969 2485 
12742 13306 
14437 13973 
3811 7356 
13702 293 
166 5613 
13267 15230 
5336 7078 
1518 8734 
15187 5517 
7420 4207 
14436 15378 
47 14882 
8941 9124 
6826 8734 
1689 1104 
3111 5163 
4360 15710 
6112 12617 
5859 4800 
12100 15824 
7526 8455 
10089 4890 
13395 466 
16284 14539 
8965 1896 
1127 876 
2925 10656 
256 11070 
613 3154 
16093 1903 
10852 101 
9743 10776 
14986 16382 
16011 3897 
16198 15582 
7613 4804 
6726 9184 
13714 13426 
11879 7422 
6834 8367 
9535 98 
12843 6270 
11767 4207 
11611 9585 
15710 9545 
727 7570 
10691 7653 
3864 7171 
4569 16108 
9545 11752 
6346 10177 
13306 9200 
8300 5008 
11391 13605 
15354 6509 
7071 10641 
13306 6901 
12760 16188 
9198 8965 
6552 11859 
4983 13382 
16000 11095 
11045 12691 
16088 12760 
472 14603 
1217 14821 
1046 15530 
16198 10446 
7183 14331 
810 11572 
4440 7470 
6380 14946 
4876 9743 
5243 115 
2144 16381 
15530 3315 
14167 1890 
10680 4249 
13227 11051 
12995 6509 
13227 663 
1619 9699 
293 15992 
1715 14922 
2586 6439 
12466 6144 
5215 8300 
15354 14212 
14913 15354 
3974 115 
10691 296 
13395 10185 
2830 15223 
1735 15470 
3445 15566 
9743 14484 
13735 4612 
14382 3589 
14088 8131 
13900 13395 
11532 16188 
9114 14850 
13045 804 
3295 13267 
1908 15583 
8886 5956 
4879 10658 
5285 3764 
8287 10782 
3829 14172 
381 13395 
14159 14780 
11707 13284 
14093 1576 
15192 15354 
10177 3305 
115 7636 
115 6147 
10691 293 
14525 2731 
1551 329 
8890 6764 
15710 2022 
6177 6177 
5996 9728 
4207 10632 
9953 12543 
2170 1711 
13395 12808 
8473 4215 
2752 12929 
12760 9743 
1046 9886 
4239 394 
13457 15470 
10844 8621 
4557 9094 
15710 4021 
15223 1046 
9946 7570 
9946 472 
7625 7039 
10083 10446 
663 7420 
13395 6036 
490 5700 
15710 14816 
9999 1093 
5517 9472 
7476 4600 
3231 8965 
13781 5864 
293 15373 
5972 9946 
8858 6304 
6726 13045 
4977 11641 
11851 6059 
11475 4863 
13267 13591 
11246 15745 
10867 12929 
640 11879 
6144 10935 
13395 2897 
13348 9946 
4696 13175 
10427 15916 
2890 10467 
11107 6144 
10546 5797 
3618 1521 
7420 6645 
8744 543 
938 4696 
895 8455 
13802 11043 
13227 16331 
13973 418 
15354 11457 
804 7608 
4382 16108 
2792 12862 
6144 15354 
2058 15535 
6541 2192 
4360 11980 
6726 13128 
14765 9889 
6509 1298 
11133 8289 
94 101 
12851 14757 
69 12948 
15074 8807 
15005 13961 
16188 9289 
9450 12248 
13189 115 
7452 8289 
1763 11082 
9472 9032 
12359 3391 
14821 10287 
3466 12948 
12952 9946 
6859 6985 
12071 12851 
12960 12061 
15175 1517 
1711 3729 
13134 7420 
6826 7438 
14525 3081 
7562 705 
14437 15107 
7356 7420 
7095 2284 
1017 4612 
11267 9289 
13094 9946 
9946 5765 
8928 7824 
6638 15470 
11654 10316 
9641 11025 
12948 4914 
14199 6519 
11290 6036 
13652 1467 
13045 369 
4612 13151 
1263 10050 
10083 14296 
5619 10467 
14382 10637 
4790 2793 
7171 2192 
15710 15102 
5125 10384 
9772 329 
2102 14146 
12005 9691 
14891 13352 
2102 11587 
2115 5258 
16339 8965 
4207 3718 
15902 4226 
9464 5469 
10646 3433 
10691 14920 
13062 7420 
10467 7056 
11601 9743 
5979 6916 
14765 8343 
16382 3551 
1177 10177 
5481 6036 
5817 5670 
8838 14302 
3910 9181 
3305 124 
7952 13395 
1894 9953 
3298 6272 
726 10260 
7620 9270 
8844 12027 
13168 10446 
6753 9413 
13160 12159 
12786 12098 
5735 3762 
8193 1177 
14059 8700 
1302 8965 
293 12421 
10380 13109 
7204 14423 
6177 12155 
3187 3433 
839 16333 
7491 8965 
164 10177 
71 7176 
293 12248 
911 15962 
13267 10083 
12555 14922 
8844 4215 
9935 9242 
11466 6552 
1536 732 
7194 12903 
12917 9743 
7270 15195 
2283 12453 
13227 12 
4987 10750 
329 2793 
4215 13027 
4269 1467 
7420 8122 
8640 7420 
7420 3039 
15824 4967 
12248 12572 
9743 15521 
394 12760 
3528 15223 
13332 12929 
1094 11015 
13360 1890 
8209 11435 
8208 14708 
15466 7356 
3645 705 
2102 1668 
7452 2102 
329 12065 
4656 15746 
9906 10691 
663 13395 
13816 7420 
13385 6541 
13045 5292 
11457 3226 
13267 1124 
494 9124 
8305 13267 
12824 7324 
11903 5996 
1104 15223 
7516 329 
9238 8331 
7420 12139 
10632 13601 
6770 15399 
11522 1148 
16250 6558 
14253 4321 
2891 5517 
15894 1278 
11564 8936 
10843 10337 
1423 2330 
12760 9450 
15618 12893 
9547 1364 
7476 329 
8965 3960 
13306 7204 
9946 13045 
14423 1359 
3838 394 
441 14437 
6726 11093 
1212 10089 
15329 2003 
9940 7457 
16333 8289 
4373 9041 
6509 8670 
4587 2586 
2903 4665 
8705 14866 
11226 164 
6912 11961 
472 5382 
16284 1104 
9504 2102 
4880 2703 
16206 9910 
14953 2674 
7487 10479 
15530 1896 
11415 13276 
13227 14587 
12061 7705 
329 8629 
9095 13702 
1104 9513 
3305 12791 
1391 2165 
10386 14063 
13192 15919 
7420 16036 
5087 2054 
14744 11344 
14437 5707 
12760 15464 
4556 9995 
7420 2617 
5507 2426 
14360 11294 
16171 12065 
3635 8492 
9743 4207 
2283 16354 
4496 10957 
4418 14183 
13395 14418 
10064 13036 
1302 6834 
3391 7420 
14980 10828 
7420 16188 
14268 10177 
6003 13507 
4506 6419 
9572 14423 
12061 1464 
14445 2090 
15859 16028 
13967 14781 
4749 9704 
8844 4655 
9722 1425 
10656 5276 
9743 15223 
7200 8744 
12903 16155 
7420 12255 
10479 3657 
7377 10446 
15354 1486 
4018 2707 
2586 12734 
3081 11833 
6527 9641 
4207 9940 
10191 13227 
13192 5797 
7132 11246 
8734 9765 
13843 473 
12498 1849 
3728 10176 
8300 14410 
4207 9841 
6177 8053 
15222 8969 
10491 1619 
10446 6036 
13890 4554 
12760 8300 
3287 4804 
13267 13605 
4207 1391 
1426 11734 
13192 12248 
3869 9124 
13992 3466 
3335 472 
2707 6317 
8642 10910 
11819 7420 
2174 7570 
10782 7191 
13735 4688 
13973 543 
2102 5619 
13758 6003 
11933 10904 
3405 15250 
7420 12277 
2629 3117 
3838 14807 
1849 13360 
15380 13306 
7194 4165 
16011 15436 
6217 7765 
1890 15308 
2102 7664 
8709 16028 
4696 9005 
13408 9733 
11331 7476 
2230 5430 
9464 16198 
15223 4655 
2074 4655 
1168 12157 
16068 13306 
8203 10089 
7900 3667 
10064 196 
12466 1607 
1551 4669 
12139 4270 
7516 698 
15765 9494 
7420 8754 
14510 12948 
810 3257 
3039 472 
5276 11148 
8754 1281 
537 5216 
10089 15223 
8370 13360 
11879 1862 
13267 7420 
11407 13306 
1046 11456 
6390 12552 
11735 14199 
15127 12851 
12061 472 
13735 7787 
10076 7420 
479 4207 
293 7651 
663 4879 
12466 9457 
2380 4207 
4386 12929 
5266 11160 
15347 16011 
10040 14755 
13267 16365 
9504 9887 
7420 13045 
14231 2903 
6703 11481 
13359 3272 
2048 4968 
3391 10691 
12817 2415 
8965 12061 
9674 10735 
6893 8343 
5658 12903 
7360 9775 
10734 10551 
293 10276 
10446 7420 
5451 10467 
16198 10899 
9005 11587 
3121 5125 
5759 11148 
115 13422 
14780 4010 
12061 5214 
14419 15192 
11879 115 
2494 2284 
3003 6217 
7420 15824 
9743 8137 
9007 9946 
11478 12929 
5232 2971 
14525 12100 
5074 12248 
8869 4418 
13690 4947 
5187 5125 
15129 6036 
12870 16036 
1391 9004 
6122 3830 
663 9124 
14785 15530 
10446 5469 
10168 3645 
663 10446 
5289 8876 
371 10486 
8300 15223 
15487 7028 
3280 2228 
16303 16062 
2694 1656 
5071 5862 
13306 12416 
9512 10744 
14639 5876 
1281 2192 
15354 14199 
14212 15916 
7420 115 
6217 3639 
11591 3584 
9444 15192 
7420 9389 
12760 1086 
6920 15192 
5864 2284 
4937 12760 
6439 5356 
4669 13401 
16022 14719 
222 14867 
13843 6541 
7570 6060 
6897 16028 
9946 15767 
5384 4951 
5613 2544 
12948 4930 
1433 6272 
7570 5488 
9827 1551 
10047 15470 
856 15192 
2980 11774 
5423 2822 
11752 9953 
9212 12997 
13306 11461 
4064 9072 
13306 7095 
360 13589 
5152 7420 
15993 4922 
10089 2251 
16063 7021 
5873 472 
12832 12424 
8754 13425 
5770 10446 
11711 10250 
7091 4215 
11160 4443 
71 15701 
14525 9605 
5177 8965 
16011 7643 
12997 14382 
1263 13033 
2409 8878 
9737 1551 
5008 5727 
15187 13189 
15529 1896 
12760 11401 
5364 11720 
2589 5707 
13022 1862 
1896 14821 
4207 7164 
2853 4050 
124 7546 
71 15963 
11043 6003 
7151 3122 
1826 7919 
6380 15223 
16198 5125 
510 16260 
1104 9007 
16198 11217 
4981 4067 
3643 7021 
181 1667 
6162 15166 
9910 1046 
11314 12558 
12248 8823 
12771 12791 
10619 15481 
13441 11980 
605 10177 
890 2854 
9697 15192 
14850 12929 
5149 11681 
374 4536 
12617 4215 
1212 13306 
7420 8131 
14511 11787 
3008 13173 
4155 8133 
7439 15354 
6177 4890 
12634 4064 
15223 7852 
1619 5019 
8832 115 
14199 4612 
3257 15354 
1391 7911 
7420 1551 
4896 5831 
12840 12997 
14525 7095 
15795 11924 
11121 12760 
5125 6217 
10446 12163 
9946 4073 
6726 8397 
9739 1
Download .txt
gitextract_433gbfev/

├── .github/
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.md
│       └── feature_request.md
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── Makefile
├── README.md
├── ThunderGP.mk
├── application/
│   ├── ar/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── bfs/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── casair/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── customized_apply.cpp
│   │   ├── dataPrepare.cpp
│   │   ├── host_vertex_apply.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── casir/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── customized_apply.cpp
│   │   ├── dataPrepare.cpp
│   │   ├── host_vertex_apply.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── cc/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   ├── l2.h
│   │   └── main.cpp
│   ├── common.mk
│   ├── global_config.h
│   ├── para_check.h
│   ├── pr/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   └── l2.h
│   ├── spmv/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   └── l2.h
│   ├── sssp/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── dataPrepare.cpp
│   │   └── l2.h
│   ├── template/
│   │   ├── apply_kernel.mk
│   │   ├── build.mk
│   │   ├── config.mk
│   │   ├── host_vertex_apply.cpp
│   │   ├── l2.h
│   │   └── vertex_apply.cpp
│   └── wcc/
│       ├── apply_kernel.mk
│       ├── build.mk
│       ├── config.mk
│       ├── dataPrepare.cpp
│       └── l2.h
├── automation/
│   ├── auto_gen_code.mk
│   ├── auto_gen_makefile.mk
│   ├── auto_gen_parameters.mk
│   ├── devices/
│   │   ├── device_common.h
│   │   ├── xilinx_u200_xdma_201830_2.h
│   │   ├── xilinx_u250_xdma_201830_2.h
│   │   └── xilinx_vcu1525_xdma_201830_1.h
│   ├── makefile_gen.cpp
│   ├── para_gen.cpp
│   ├── parser/
│   │   ├── customize.cpp
│   │   ├── customize.h
│   │   ├── customize_str.h
│   │   ├── kernel_interface.cpp
│   │   ├── kernel_interface.h
│   │   ├── makefile.cpp
│   │   ├── makefile.h
│   │   ├── mem_interface.cpp
│   │   └── mem_interface.h
│   ├── parser.cpp
│   ├── parser.h
│   ├── parser_debug.cpp
│   └── parser_debug.h
├── dataset/
│   ├── README.md
│   ├── kronecker_generator.m
│   ├── rmat-14-32.txt
│   └── rmat.m
├── docs/
│   ├── algorithm_mapping.md
│   ├── api_details.md
│   ├── compile_arch.md
│   ├── memory.md
│   ├── results.md
│   ├── scheduling.md
│   └── verification.md
├── libfpga/
│   ├── common_template/
│   │   ├── apply_kernel.mk
│   │   ├── apply_top.cpp
│   │   └── scatter_gather_top.cpp
│   ├── customize_template/
│   │   ├── customize_apply_cl_kernel.h
│   │   ├── customize_apply_kernel.mk
│   │   ├── customize_apply_top.cpp
│   │   └── customize_mem.h
│   ├── fpga_application.h
│   ├── fpga_apply.h
│   ├── fpga_cache.h
│   ├── fpga_decoder.h
│   ├── fpga_edge_prop.h
│   ├── fpga_filter.h
│   ├── fpga_gather.h
│   ├── fpga_global_mem.h
│   ├── fpga_gs_top.h
│   ├── fpga_process_edge.h
│   ├── fpga_raw_solver.h
│   ├── fpga_slice.h
│   └── graph_fpga.h
├── libgraph/
│   ├── common.h
│   ├── default_entry.cpp
│   ├── host_graph_api.h
│   ├── host_graph_data_structure.h
│   ├── host_graph_dataflow.cpp
│   ├── host_graph_partition.cpp
│   ├── host_graph_sw.h
│   ├── kernel/
│   │   ├── host_graph_kernel.cpp
│   │   └── host_graph_kernel.h
│   ├── memory/
│   │   ├── he_mapping.cpp
│   │   ├── he_mem.cpp
│   │   ├── he_mem.h
│   │   ├── he_mem_attr.h
│   │   ├── he_mem_config.h
│   │   └── he_mem_id.h
│   ├── misc/
│   │   ├── data_helper.cpp
│   │   ├── graph.cpp
│   │   ├── graph.h
│   │   ├── host_graph_csv.hpp
│   │   ├── host_graph_mem.cpp
│   │   ├── host_graph_mem.h
│   │   └── host_graph_misc_inner.h
│   ├── scheduler/
│   │   ├── host_graph_scheduler.cpp
│   │   ├── host_graph_scheduler.h
│   │   ├── normal/
│   │   │   └── scheduler.cpp
│   │   └── secondOrderEstimator/
│   │       └── scheduler.cpp
│   ├── test/
│   │   └── test_col.c
│   └── verification/
│       ├── host_graph_cmodel.cpp
│       ├── host_graph_verification.h
│       ├── host_graph_verification_apply.cpp
│       ├── host_graph_verification_gs.cpp
│       └── host_graph_verification_inner.h
└── utils/
    ├── bitstream.mk
    ├── clean.mk
    ├── help.mk
    ├── main.mk
    ├── opencl.mk
    ├── report_usage.tcl
    ├── utils.mk
    └── xcl/
        ├── xcl.c
        ├── xcl.h
        └── xcl.mk
Download .txt
SYMBOL INDEX (268 symbols across 80 files)

FILE: application/ar/dataPrepare.cpp
  function dataPrepareGetArg (line 7) | unsigned int dataPrepareGetArg(graphInfo *info)
  function dataPrepareProperty (line 12) | int dataPrepareProperty(graphInfo *info)

FILE: application/ar/l2.h
  function prop_t (line 12) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 18) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 24) | inline prop_t gatherFunc(prop_t ori, prop_t update)
  function prop_t (line 29) | inline prop_t applyFunc( prop_t tProp,

FILE: application/ar/main.cpp
  function main (line 13) | int main(int argc, char **argv) {

FILE: application/bfs/dataPrepare.cpp
  function dataPrepareGetArg (line 8) | unsigned int dataPrepareGetArg(graphInfo *info)
  function dataPrepareProperty (line 13) | int dataPrepareProperty(graphInfo *info)

FILE: application/bfs/l2.h
  function prop_t (line 11) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 17) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 23) | inline prop_t gatherFunc(prop_t ori, prop_t update)
  function prop_t (line 36) | inline prop_t applyFunc( prop_t tProp,

FILE: application/bfs/main.cpp
  function main (line 13) | int main(int argc, char **argv) {

FILE: application/casair/customized_apply.cpp
  function applyFunc (line 8) | int applyFunc( ... )

FILE: application/casair/dataPrepare.cpp
  function dataPrepareProperty (line 13) | int dataPrepareProperty(graphInfo *info)
  function dataPrepareGetArg (line 65) | unsigned int dataPrepareGetArg(graphInfo *info)

FILE: application/casair/host_vertex_apply.cpp
  function partitionApplyCModel (line 15) | void partitionApplyCModel(

FILE: application/casair/l2.h
  function prop_t (line 9) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 15) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 21) | inline prop_t gatherFunc(prop_t ori, prop_t update)

FILE: application/casair/main.cpp
  function main (line 14) | int main(int argc, char **argv) {

FILE: application/casir/customized_apply.cpp
  function applyFunc (line 8) | int applyFunc( ... )

FILE: application/casir/dataPrepare.cpp
  function dataPrepareProperty (line 10) | int dataPrepareProperty(graphInfo *info)
  function dataPrepareGetArg (line 65) | unsigned int dataPrepareGetArg(graphInfo *info)

FILE: application/casir/host_vertex_apply.cpp
  function partitionApplyCModel (line 15) | void partitionApplyCModel(

FILE: application/casir/l2.h
  function prop_t (line 9) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 15) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 21) | inline prop_t gatherFunc(prop_t ori, prop_t update)

FILE: application/casir/main.cpp
  function main (line 12) | int main(int argc, char **argv) {

FILE: application/cc/dataPrepare.cpp
  function dataPrepareGetArg (line 9) | unsigned int dataPrepareGetArg(graphInfo *info)
  function dataPrepareProperty (line 14) | int dataPrepareProperty(graphInfo *info)

FILE: application/cc/l2.h
  function prop_t (line 11) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 17) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 23) | inline prop_t gatherFunc(prop_t ori, prop_t update)
  function prop_t (line 28) | inline prop_t applyFunc( prop_t tProp,

FILE: application/cc/main.cpp
  function main (line 13) | int main(int argc, char **argv) {

FILE: application/global_config.h
  type prop_t (line 9) | typedef  unsigned int       prop_t;
  type prop_t (line 11) | typedef  int                prop_t;

FILE: application/pr/dataPrepare.cpp
  function float2int (line 6) | int float2int(float a) {
  function int2float (line 10) | float int2float(int a) {
  function dataPrepareGetArg (line 14) | unsigned int dataPrepareGetArg(graphInfo *info)
  function dataPrepareProperty (line 19) | int dataPrepareProperty(graphInfo *info)

FILE: application/pr/l2.h
  function prop_t (line 9) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 15) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 21) | inline prop_t gatherFunc(prop_t ori, prop_t update)
  function prop_t (line 26) | inline prop_t applyFunc( prop_t tProp,

FILE: application/spmv/dataPrepare.cpp
  function dataPrepareGetArg (line 4) | unsigned int dataPrepareGetArg(graphInfo *info)
  function dataPrepareProperty (line 9) | int dataPrepareProperty(graphInfo *info)

FILE: application/spmv/l2.h
  function prop_t (line 5) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 11) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 17) | inline prop_t gatherFunc(prop_t ori, prop_t update)
  function prop_t (line 22) | inline prop_t applyFunc( prop_t tProp,

FILE: application/sssp/dataPrepare.cpp
  function dataPrepareGetArg (line 4) | unsigned int dataPrepareGetArg(graphInfo *info)
  function dataPrepareProperty (line 9) | int dataPrepareProperty(graphInfo *info)

FILE: application/sssp/l2.h
  function prop_t (line 11) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 17) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 26) | inline prop_t gatherFunc(prop_t ori, prop_t update)
  function prop_t (line 39) | inline prop_t applyFunc( prop_t tProp,

FILE: application/template/host_vertex_apply.cpp
  function setApplyKernel (line 8) | void setApplyKernel(cl_kernel &kernel_apply, int partId, int vertexNum)
  function partitionApplyCModel (line 14) | void partitionApplyCModel(

FILE: application/template/l2.h
  function prop_t (line 5) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 11) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 17) | inline prop_t updateMergeInRAWSolver(prop_t ori, prop_t update)
  function prop_t (line 23) | inline prop_t gatherFunc(prop_t ori, prop_t update)

FILE: application/template/vertex_apply.cpp
  function apply (line 9) | void apply(
  function vertexApply (line 78) | void  vertexApply(

FILE: application/wcc/dataPrepare.cpp
  function dataPrepareGetArg (line 8) | unsigned int dataPrepareGetArg(graphInfo *info)
  function dataPrepareProperty (line 13) | int dataPrepareProperty(graphInfo *info)

FILE: application/wcc/l2.h
  function prop_t (line 17) | inline prop_t preprocessProperty(prop_t srcProp)
  function prop_t (line 23) | inline prop_t scatterFunc(prop_t srcProp, prop_t edgeProp)
  function prop_t (line 29) | inline prop_t gatherFunc(prop_t ori, prop_t update)
  function prop_t (line 35) | inline prop_t applyFunc( prop_t tProp,

FILE: automation/devices/device_common.h
  type slr_resource_info_t (line 4) | typedef struct

FILE: automation/makefile_gen.cpp
  function main (line 15) | int main(int argc, char **argv) {

FILE: automation/para_gen.cpp
  function main (line 44) | int main(int argc, char **argv) {

FILE: automation/parser.cpp
  function parser_init (line 33) | int parser_init(void)
  function find_arg (line 53) | std::string find_arg(void * context, std::string &line, int ln)
  function identify_pragmas (line 68) | int identify_pragmas(std::string file_name, std::string &current_line, s...
  function file_input (line 102) | int file_input(const std::string& input)
  function register_output_method (line 128) | int register_output_method(output_method_t method)
  function file_output (line 136) | int file_output(const std::string& input, const std::string& output)
  function main (line 240) | int main(int argc, char **argv) {

FILE: automation/parser.h
  type arg_instance_t (line 48) | typedef struct
  type parser_item_t (line 61) | typedef struct
  type reg_parser_item_t (line 71) | typedef struct
  type output_method_t (line 80) | typedef struct
  function replace_all (line 89) | inline int replace_all(std::string &object, std::string sub, std::string...

FILE: automation/parser/customize.cpp
  function output_to_file (line 117) | static int output_to_file(std::ofstream * of, int ln, int fileid, int gn)
  function def_arg_instance_t (line 400) | static def_arg_instance_t * get_def_arg(std::string arg)
  function register_base_type (line 412) | int register_base_type(arg_instance_t item)
  function register_USER_APPLY_CODE_START (line 419) | int register_USER_APPLY_CODE_START(arg_instance_t item)
  function register_USER_APPLY_CODE_END (line 434) | int register_USER_APPLY_CODE_END(arg_instance_t item)
  function register_def_scalar (line 449) | int register_def_scalar(arg_instance_t item)
  function register_def_input_only_array (line 467) | int register_def_input_only_array(arg_instance_t item)
  function register_def_dou_array (line 486) | int register_def_dou_array(arg_instance_t item)
  function get_of_number (line 506) | static int get_of_number(void)

FILE: automation/parser/kernel_interface.cpp
  function kernel_arg_instance_t (line 24) | static kernel_arg_instance_t * get_kernel_arg(std::string arg)
  function register_kernel_arg (line 36) | int register_kernel_arg(arg_instance_t item)
  function get_of_number (line 51) | static int get_of_number(void)
  function output_to_file (line 59) | static int output_to_file(std::ofstream * of, int ln, int fileid, int gn)

FILE: automation/parser/makefile.cpp
  function register_makefile_instance (line 21) | int register_makefile_instance(arg_instance_t item)
  function get_of_number (line 29) | static int get_of_number(void)
  function output_to_file (line 34) | static int output_to_file(std::ofstream * of, int ln, int fileid, int gn)

FILE: automation/parser/mem_interface.cpp
  function mem_arg_instance_t (line 36) | static mem_arg_instance_t * get_mem_arg(std::string arg)
  function find_in_dependency (line 48) | int find_in_dependency(int id)
  function get_dependency_mask (line 60) | unsigned int get_dependency_mask(int id)
  function register_mem_arg (line 75) | int register_mem_arg(arg_instance_t item)
  function register_mem_attr (line 100) | int register_mem_attr(arg_instance_t item)
  function register_mem_instance (line 135) | int register_mem_instance(arg_instance_t item)
  function get_of_number (line 169) | static int get_of_number(void)
  function output_to_file (line 174) | static int output_to_file(std::ofstream * of, int ln, int fileid, int gn)

FILE: automation/parser_debug.cpp
  function logger (line 4) | void logger (char *fmt, ...)
  function replace (line 14) | bool replace(std::string& str, const std::string& from, const std::strin...

FILE: libfpga/common_template/apply_top.cpp
  function vertexApply (line 11) | void  vertexApply(

FILE: libfpga/customize_template/customize_apply_cl_kernel.h
  function setApplyKernel (line 4) | void setApplyKernel(int partId, int superStep, graphInfo *info)

FILE: libfpga/customize_template/customize_apply_top.cpp
  function vertexApply (line 15) | void  vertexApply(

FILE: libfpga/customize_template/customize_mem.h
  type scalar_t (line 5) | typedef struct

FILE: libfpga/fpga_apply.h
  function applyFunction (line 64) | void applyFunction(

FILE: libfpga/fpga_cache.h
  type cache_line (line 22) | typedef  struct
  type cache_command (line 29) | typedef  struct
  type edgeBlock (line 36) | typedef struct
  type address_token (line 44) | typedef struct {
  type filtered_token (line 50) | typedef struct {
  function writeTuples (line 92) | void writeTuples( hls::stream<edge_tuples_t>  &edgeTuplesBuffer, edge_tu...
  function uint_raw (line 105) | inline uint_raw cacheUpdateByAddr(
  function streamFilter (line 153) | void streamFilter(hls::stream<burst_token>         &mapStream,
  function streamRemoveBubble (line 209) | void streamRemoveBubble(hls::stream<filtered_token> &in,
  function updateVertexCacheNarrow (line 347) | void updateVertexCacheNarrow(uint16                          * input,
  function stream2Command (line 423) | void stream2Command(hls::stream<burst_token>        &mapStream,
  function streamDelayScheme1 (line 476) | void streamDelayScheme1(hls::stream<burst_raw>  &in, hls::stream<burst_r...
  function streamDelayScheme2 (line 510) | void streamDelayScheme2(hls::stream<burst_token>  &in, hls::stream<burst...
  function updateVertexCache (line 582) | void updateVertexCache(uint16                          * input,
  function readEdgesStage (line 636) | void  readEdgesStage(
  function srcPropertyProcess (line 738) | void srcPropertyProcess( uint16                             * vertexPush...

FILE: libfpga/fpga_decoder.h
  function shuffled_type (line 6) | inline shuffled_type shuffleDecoder(uchar opcode) {

FILE: libfpga/fpga_edge_prop.h
  function halfEdgeProp (line 8) | void halfEdgeProp(
  function edgePropCouple (line 30) | void edgePropCouple (
  function propProcess (line 62) | void propProcess( hls::stream<burst_token>     &propInput,
  function propProcessSelf (line 78) | void propProcessSelf( hls::stream<edge_tuples_t>   &tupleInput,

FILE: libfpga/fpga_filter.h
  function tupleFilter (line 7) | void tupleFilter(

FILE: libfpga/fpga_gather.h
  function shuffleDispatcher (line 8) | void shuffleDispatcher(
  function shuffleEntry (line 22) | void shuffleEntry (

FILE: libfpga/fpga_global_mem.h
  function writeBack (line 79) | void writeBack(int idx, uint16 *addr, hls::stream<burst_raw>  &input)
  function writeBackLite (line 164) | void writeBackLite(int totalSize, uint16 *addr, hls::stream<burst_raw>  ...

FILE: libfpga/fpga_process_edge.h
  function processEdgeWrite (line 17) | void processEdgeWrite(
  function dstPropertyProcess (line 82) | void dstPropertyProcess(

FILE: libfpga/fpga_raw_solver.h
  function processEdgesReorderStreamScheme1 (line 12) | void processEdgesReorderStreamScheme1(hls::stream<int2>  &in , hls::stre...
  function rawSolver (line 71) | void rawSolver(hls::stream<int2_token>  &in , hls::stream<int2_token> &out)

FILE: libfpga/fpga_slice.h
  function processEdgesBuildSlice (line 98) | void processEdgesBuildSlice(hls::stream<int2_token>  &in , hls::stream<i...
  function processEdgesSlice (line 115) | void processEdgesSlice(hls::stream<uint_uram>  &input, hls::stream<uint_...
  function filterSlice (line 128) | void filterSlice(

FILE: libfpga/graph_fpga.h
  type ap_uint (line 35) | typedef ap_uint<8>                 ushort_raw;
  type ap_uint (line 38) | typedef ap_uint<32>                 uint_raw;
  type ap_uint (line 40) | typedef ap_uint<DATA_WIDTH>         uint16;
  type ap_uint (line 42) | typedef ap_uint<128>                uint4_raw;
  type ap_uint (line 45) | typedef ap_uint<BURST_ALL_BITS>     burst_raw;
  type burst_token (line 48) | typedef struct {
  type ap_uint (line 53) | typedef ap_uint<BURST_ALL_BITS/2>   burst_half;
  type ap_uint (line 55) | typedef ap_uint<64>                 uint_uram;
  type int2 (line 81) | typedef struct __int2__
  type int2_token (line 92) | typedef struct
  type edge_tuples_t (line 98) | typedef struct EdgeInfo {
  type shuffled_type (line 103) | typedef struct shuffledData {
  type filter_type (line 108) | typedef struct filterData {
  type process_type (line 114) | typedef struct processinfo {
  function clear_stream (line 156) | int clear_stream (hls::stream<T> &stream)
  function empty_stream (line 179) | int empty_stream (hls::stream<T> &stream)
  function write_to_stream (line 206) | int write_to_stream (hls::stream<T> &stream, T const& value)
  function read_from_stream (line 216) | int read_from_stream (hls::stream<T> &stream, T & value)
  function read_from_stream_nb (line 235) | int read_from_stream_nb (hls::stream<T> &stream, T & value)

FILE: libgraph/common.h
  function get_aligned_size (line 48) | inline unsigned int get_aligned_size(unsigned int in, unsigned int align)

FILE: libgraph/default_entry.cpp
  function main (line 16) | int main(int argc, char **argv) {

FILE: libgraph/host_graph_api.h
  type graphInfo (line 10) | typedef struct

FILE: libgraph/host_graph_data_structure.h
  type profileLog (line 9) | typedef struct
  type subPartitionDescriptor (line 17) | typedef struct
  type partitionDescriptor (line 36) | typedef struct
  type gatherScatterDescriptor (line 47) | typedef struct
  type applyDescriptor (line 58) | typedef struct
  type graphAccelerator (line 64) | typedef struct
  function getCuIDbyInterface (line 100) | inline int getCuIDbyInterface(int order)

FILE: libgraph/host_graph_dataflow.cpp
  function graphAccelerator (line 8) | graphAccelerator * getAccelerator(void)
  function subPartitionDescriptor (line 13) | subPartitionDescriptor * getSubPartition(int partID)
  function partitionDescriptor (line 18) | partitionDescriptor * getPartition(int partID)
  function acceleratorInit (line 24) | int acceleratorInit(const char * name, char *file_name)
  function acceleratorSuperStep (line 50) | int acceleratorSuperStep(int superStep, graphInfo *info)
  function acceleratorDeinit (line 91) | int acceleratorDeinit(void)
  function prop_t (line 109) | prop_t* acceleratorQueryProperty(int step)

FILE: libgraph/host_graph_partition.cpp
  function acceleratorDataLoad (line 13) | int acceleratorDataLoad(const std::string &gName, const std::string &mod...
  function partitionTransfer (line 79) | static void partitionTransfer(graphInfo *info)
  function reTransferProp (line 119) | void reTransferProp(graphInfo *info)
  function partitionFunction (line 151) | void partitionFunction(graphInfo *info)
  function acceleratorDataPreprocess (line 329) | int acceleratorDataPreprocess(graphInfo *info)

FILE: libgraph/kernel/host_graph_kernel.cpp
  function gatherScatterDescriptor (line 30) | gatherScatterDescriptor * getGatherScatter(int kernelID)
  function applyDescriptor (line 35) | applyDescriptor * getApply(void)
  function kernelInit (line 40) | void kernelInit(graphAccelerator * acc)
  function setGsKernel (line 67) | void setGsKernel(int partId, int superStep, graphInfo *info)
  function setApplyKernel (line 103) | void setApplyKernel(int partId, int superStep, graphInfo *info)

FILE: libgraph/memory/he_mapping.cpp
  function he_get_mem_attr (line 48) | int he_get_mem_attr(int attr_id)
  function he_get_interface_id (line 66) | int he_get_interface_id(int cu_id)
  function he_get_attr_by_cu (line 79) | int he_get_attr_by_cu(int cu_id)

FILE: libgraph/memory/he_mem.cpp
  function he_set_dirty (line 16) | int he_set_dirty(int id)
  function he_set_clean (line 29) | int he_set_clean(int id)
  function he_get_dirty_flag (line 41) | int he_get_dirty_flag(int id)
  function register_size_attribute (line 54) | int register_size_attribute(unsigned int attr_id, int value)
  function get_size_attribute (line 67) | unsigned int get_size_attribute(unsigned int attr_id)
  function he_mem_init (line 83) | int he_mem_init(cl_context &dev_context, he_mem_t * item)
  function he_mem_t (line 153) | he_mem_t* get_he_mem(unsigned int id)
  function clear_host_mem (line 176) | void clear_host_mem(int id)
  function cl_mem (line 187) | cl_mem* get_cl_mem_pointer(int id)
  function transfer_data_to_pl (line 203) | int transfer_data_to_pl(cl_context &dev_context, cl_device_id device_id,...
  function transfer_data_from_pl (line 236) | int transfer_data_from_pl(cl_context &dev_context, cl_device_id device_i...
  function he_mem_from_bin (line 267) | int he_mem_from_bin(std::string file_name, int he_id, int mem_id)

FILE: libgraph/memory/he_mem.h
  type size_attr_ctrl_t (line 15) | typedef struct
  type he_mem_t (line 24) | typedef struct
  type he_mem_lookup_t (line 40) | typedef struct

FILE: libgraph/misc/data_helper.cpp
  function Graph (line 5) | Graph* createGraph(const std::string &gName, const std::string &mode) {
  function getCurrentTimestamp (line 94) | double getCurrentTimestamp(void) {

FILE: libgraph/misc/graph.h
  function class (line 17) | class Vertex {
  function class (line 36) | class Graph{
  function class (line 62) | class CSR{
  function class (line 78) | class CSR_BLOCK{

FILE: libgraph/misc/host_graph_csv.hpp
  function T (line 12) | T * load_from_csv(std::string file_name, int he_id, int mem_id)
  function output_init (line 66) | int output_init(int he_id, int mem_id, int ref_he_id)
  function write_back_csv (line 98) | int write_back_csv(std::string file_name, int he_id)

FILE: libgraph/misc/host_graph_mem.cpp
  function base_mem_init (line 9) | void base_mem_init(cl_context &context)
  function gs_mem_init (line 17) | static void gs_mem_init(cl_context &context, gatherScatterDescriptor *gs...
  function process_mem_init (line 44) | void process_mem_init(cl_context &context)
  function partition_mem_init (line 53) | void partition_mem_init(cl_context &context, int blkIndex, int size, int...

FILE: libgraph/scheduler/host_graph_scheduler.cpp
  function registerScheduler (line 9) | int registerScheduler(graphStaticScheduler * pItem)
  function getArrangedPartitionID (line 21) | int getArrangedPartitionID(int step)
  function schedulerInit (line 26) | int schedulerInit(void *arg)
  function schedulerSubPartitionArrangement (line 34) | int schedulerSubPartitionArrangement(int partIndex)
  function schedulerPartitionArrangement (line 49) | int schedulerPartitionArrangement(int size)

FILE: libgraph/scheduler/host_graph_scheduler.h
  type graphStaticScheduler (line 13) | typedef struct{

FILE: libgraph/scheduler/normal/scheduler.cpp
  function normalInitHanlder (line 8) | int normalInitHanlder(void *arg)
  function soeSubPartitionArrangementHandler (line 14) | int soeSubPartitionArrangementHandler(int partIndex)
  function normalSchedulerPartitionArrangement (line 35) | int normalSchedulerPartitionArrangement(int * table, int size)
  function schedulerRegister (line 53) | int schedulerRegister(void)

FILE: libgraph/scheduler/secondOrderEstimator/scheduler.cpp
  function performanceEstimator (line 11) | double performanceEstimator(double vertex, double edge)
  function soeInitHanlder (line 25) | int soeInitHanlder(void *arg)
  function soeSubPartitionArrangementHandler (line 35) | int soeSubPartitionArrangementHandler(int partIndex)
  function soeSchedulerPartitionArrangement (line 109) | int soeSchedulerPartitionArrangement(int * table, int size)
  function schedulerRegister (line 138) | int schedulerRegister(void)

FILE: libgraph/test/test_col.c
  function main (line 8) | int main(int argc,  char **argv)

FILE: libgraph/verification/host_graph_cmodel.cpp
  function acceleratorProfile (line 11) | int acceleratorProfile (int superStep, int runCounter, graphInfo *info, ...
  function acceleratorCModelDataPreprocess (line 90) | int acceleratorCModelDataPreprocess(graphInfo *info)
  function acceleratorCModelSuperStep (line 100) | int acceleratorCModelSuperStep(int superStep, graphInfo *info)

FILE: libgraph/verification/host_graph_verification_apply.cpp
  function partitionApplyCModel (line 13) | void partitionApplyCModel(

FILE: libgraph/verification/host_graph_verification_gs.cpp
  function partitionGatherScatterCModel (line 9) | void partitionGatherScatterCModel(

FILE: utils/xcl/xcl.c
  function load_file_to_memory (line 55) | static int load_file_to_memory(const char *filename, char **result) {
  function xcl_world (line 95) | xcl_world xcl_world_single_vendor(const char* vendor_name) {
  function xcl_world (line 230) | xcl_world xcl_world_single() {
  function xcl_release_world (line 234) | void xcl_release_world(xcl_world world) {
  function cl_program (line 241) | cl_program xcl_import_binary_file(xcl_world world,
  function cl_program (line 360) | cl_program xcl_import_binary(xcl_world world,
  function cl_program (line 381) | cl_program xcl_import_source(xcl_world world,
  function cl_kernel (line 417) | cl_kernel xcl_get_kernel(cl_program program,
  function xcl_free_kernel (line 431) | void xcl_free_kernel(cl_kernel krnl) {
  function xcl_set_kernel_arg (line 441) | void xcl_set_kernel_arg(cl_kernel krnl,
  function cl_mem (line 454) | cl_mem xcl_malloc(xcl_world world, cl_mem_flags flags, size_t size) {
  function xcl_free (line 465) | void xcl_free(cl_mem mem) {
  function xcl_memcpy_to_device (line 474) | void xcl_memcpy_to_device(xcl_world world, cl_mem dest, void* src,
  function xcl_memcpy_from_device (line 484) | void xcl_memcpy_from_device(xcl_world world, void* dest,
  function xcl_get_event_duration (line 495) | unsigned long xcl_get_event_duration(cl_event event) {
  function xcl_run_kernel3d (line 506) | unsigned long xcl_run_kernel3d(xcl_world world, cl_kernel krnl,
  function xcl_run_kernel3d_nb (line 525) | void xcl_run_kernel3d_nb(xcl_world world, cl_kernel krnl,cl_event *event,

FILE: utils/xcl/xcl.h
  type xcl_world (line 36) | typedef struct {
Condensed preview — 166 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,041K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 834,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 595,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".gitignore",
    "chars": 202,
    "preview": "*.diff\n*.log\nhost_graph_fpga*\n_x\nxclbin\n.Xil\n*.str\nsdx_*\n*.json\n*.jou\nrelease*\ntest_log*\nxclbin*\n*.protoinst\n*.csv\nsdacc"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3363,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "Makefile",
    "chars": 80,
    "preview": "include ThunderGP.mk\n\n.PHONY: all clean exe hwemuprepare\n\n\ninclude utils/main.mk"
  },
  {
    "path": "README.md",
    "chars": 12093,
    "preview": "![logo](docs/images/ThunderGP.png)\n\n[![GitHub license](https://img.shields.io/badge/license-apache2-yellowgreen)](./LICE"
  },
  {
    "path": "ThunderGP.mk",
    "chars": 344,
    "preview": "TARGETS := hw\n# emu or acc:\n#   hw\n#   hw_emu\n\nAPP := \n# pass in by app=\n\nTARGET_BANDWIDTH := 77\n# target memory bandwid"
  },
  {
    "path": "application/ar/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/ar/build.mk",
    "chars": 217,
    "preview": "\n#scatter-gather kernel\nHAVE_EDGE_PROP=false\nHAVE_UNSIGNED_PROP=false\n\n#apply kernel\nHAVE_APPLY=true\nCUSTOMIZE_APPLY=fal"
  },
  {
    "path": "application/ar/config.mk",
    "chars": 109,
    "preview": "FREQ=250\n\nQUEUE_SIZE_FILTER=16\nQUEUE_SIZE_MEMORY=512\n\nLOG_SCATTER_CACHE_BURST_SIZE=6\n\nAPPLY_REF_ARRAY_SIZE=1\n"
  },
  {
    "path": "application/ar/dataPrepare.cpp",
    "chars": 851,
    "preview": "#include \"host_graph_api.h\"\n#include \"fpga_application.h\"\n\n\nstatic unsigned int avg_outdegree;\n\nunsigned int dataPrepare"
  },
  {
    "path": "application/ar/l2.h",
    "chars": 1278,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n\n#define kDamp               (0.85f)\n#define kDampFixPoint       108//(0.85 << 7)  //"
  },
  {
    "path": "application/ar/main.cpp",
    "chars": 1077,
    "preview": "#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <fstream>\n\n#include \"host_graph_api.h\"\n#include \"hos"
  },
  {
    "path": "application/bfs/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/bfs/build.mk",
    "chars": 218,
    "preview": "\n#scatter-gather kernel\nHAVE_EDGE_PROP=false\nHAVE_UNSIGNED_PROP=true\n\n#apply kernel\nHAVE_APPLY=true\nCUSTOMIZE_APPLY=fals"
  },
  {
    "path": "application/bfs/config.mk",
    "chars": 109,
    "preview": "FREQ=250\n\nQUEUE_SIZE_FILTER=32\nQUEUE_SIZE_MEMORY=512\n\nLOG_SCATTER_CACHE_BURST_SIZE=7\n\nAPPLY_REF_ARRAY_SIZE=1\n"
  },
  {
    "path": "application/bfs/dataPrepare.cpp",
    "chars": 606,
    "preview": "#include \"host_graph_api.h\"\n#include \"fpga_application.h\"\n\n#include <cstdlib>\n#include <iostream>\n#include <ctime>\n\nunsi"
  },
  {
    "path": "application/bfs/l2.h",
    "chars": 1489,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n\n#define MAX_PROP                  (INT_MAX - 1)\n\n#define VERTEX_ACTIVE_BIT_MASK    ("
  },
  {
    "path": "application/bfs/main.cpp",
    "chars": 1274,
    "preview": "#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <fstream>\n\n#include \"host_graph_api.h\"\n#include \"hos"
  },
  {
    "path": "application/casair/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/casair/build.mk",
    "chars": 315,
    "preview": "\n#scatter-gather kernel\nHAVE_EDGE_PROP=true\nHAVE_UNSIGNED_PROP=false\n\n#apply kernel\nHAVE_APPLY=true\nCUSTOMIZE_APPLY=true"
  },
  {
    "path": "application/casair/config.mk",
    "chars": 109,
    "preview": "FREQ=300\n\nQUEUE_SIZE_FILTER=32\nQUEUE_SIZE_MEMORY=512\n\nLOG_SCATTER_CACHE_BURST_SIZE=7\n\nAPPLY_REF_ARRAY_SIZE=1\n"
  },
  {
    "path": "application/casair/customized_apply.cpp",
    "chars": 1221,
    "preview": "\n// pre-define:\n//                  uProp = theta_i * N\n//                  tProp = sum(sourceVertexProp * w) in scatter"
  },
  {
    "path": "application/casair/dataPrepare.cpp",
    "chars": 2351,
    "preview": "#include \"host_graph_api.h\"\n#include \"fpga_application.h\"\n#include \"customize_mem_1.h\"\n\n\nconst float epsilion = 0.077;\nc"
  },
  {
    "path": "application/casair/host_vertex_apply.cpp",
    "chars": 393,
    "preview": "#include \"host_graph_sw.h\"\n\n#include \"fpga_application.h\"\n\n#include \"host_graph_verification.h\"\n\n\n#include \"customize_me"
  },
  {
    "path": "application/casair/l2.h",
    "chars": 578,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n\n#define FIXED_SCALE                    (1000000)\n\n\n/* source vertex property process"
  },
  {
    "path": "application/casair/main.cpp",
    "chars": 1126,
    "preview": "#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <fstream>\n\n\n#include \"customize_mem_1.h\"\n#include \"h"
  },
  {
    "path": "application/casir/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/casir/build.mk",
    "chars": 315,
    "preview": "\n#scatter-gather kernel\nHAVE_EDGE_PROP=true\nHAVE_UNSIGNED_PROP=false\n\n#apply kernel\nHAVE_APPLY=true\nCUSTOMIZE_APPLY=true"
  },
  {
    "path": "application/casir/config.mk",
    "chars": 109,
    "preview": "FREQ=300\n\nQUEUE_SIZE_FILTER=32\nQUEUE_SIZE_MEMORY=512\n\nLOG_SCATTER_CACHE_BURST_SIZE=7\n\nAPPLY_REF_ARRAY_SIZE=1\n"
  },
  {
    "path": "application/casir/customized_apply.cpp",
    "chars": 1317,
    "preview": "\n// pre-define:\n//                  uProp = theta_i * N\n//                  tProp = sum(sourceVertexProp * w) in scatter"
  },
  {
    "path": "application/casir/dataPrepare.cpp",
    "chars": 2154,
    "preview": "#include \"host_graph_api.h\"\n#include \"fpga_application.h\"\n#include \"customize_mem_1.h\"\n\n\n#define DATA_PATH              "
  },
  {
    "path": "application/casir/host_vertex_apply.cpp",
    "chars": 393,
    "preview": "#include \"host_graph_sw.h\"\n\n#include \"fpga_application.h\"\n\n#include \"host_graph_verification.h\"\n\n\n#include \"customize_me"
  },
  {
    "path": "application/casir/l2.h",
    "chars": 578,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n\n#define FIXED_SCALE                    (1000000)\n\n\n/* source vertex property process"
  },
  {
    "path": "application/casir/main.cpp",
    "chars": 1064,
    "preview": "#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <fstream>\n\n#include \"customize_mem_1.h\"\n#include \"ho"
  },
  {
    "path": "application/cc/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/cc/build.mk",
    "chars": 218,
    "preview": "\n#scatter-gather kernel\nHAVE_EDGE_PROP=false\nHAVE_UNSIGNED_PROP=true\n\n#apply kernel\nHAVE_APPLY=true\nCUSTOMIZE_APPLY=fals"
  },
  {
    "path": "application/cc/config.mk",
    "chars": 110,
    "preview": "FREQ=250\n\nQUEUE_SIZE_FILTER=16\nQUEUE_SIZE_MEMORY=512\n\nLOG_SCATTER_CACHE_BURST_SIZE=7\n\nAPPLY_REF_ARRAY_SIZE=32\n"
  },
  {
    "path": "application/cc/dataPrepare.cpp",
    "chars": 713,
    "preview": "#include \"host_graph_api.h\"\n#include \"fpga_application.h\"\n\n#include <cstdlib>\n#include <iostream>\n#include <ctime>\n\n\nuns"
  },
  {
    "path": "application/cc/l2.h",
    "chars": 1145,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n\n#define MAX_PROP                  (INT_MAX - 1)\n\n#define VERTEX_ACTIVE_BIT_MASK    ("
  },
  {
    "path": "application/cc/main.cpp",
    "chars": 2020,
    "preview": "#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <fstream>\n\n#include \"host_graph_api.h\"\n#include \"hos"
  },
  {
    "path": "application/common.mk",
    "chars": 5130,
    "preview": "VAR_TRUE=true\n\nCP = cp -rf\nXCLBIN := ./xclbin_$(APP)\nDSA := $(call device2sandsa, $(DEVICE))\n\nCXX := $(XILINX_SDX)/bin/x"
  },
  {
    "path": "application/global_config.h",
    "chars": 662,
    "preview": "#ifndef __GLOBAL_CONFIG_H__\n#define __GLOBAL_CONFIG_H__\n\n#include <climits>\n#include <math.h>\n\n\n#if HAVE_UNSIGNED_PROP\nt"
  },
  {
    "path": "application/para_check.h",
    "chars": 295,
    "preview": "#ifndef __PARA_CHECK__\n#define __PARA_CHECK__\n\n#ifndef SUB_PARTITION_NUM\n#error \"SUB_PARTITION_NUM is not define! please"
  },
  {
    "path": "application/pr/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/pr/build.mk",
    "chars": 216,
    "preview": "\n#scatter-gather kernel\nHAVE_EDGE_PROP=false\nHAVE_UNSIGNED_PROP=false\n\n#apply kernel\nHAVE_APPLY=true\nCUSTOMIZE_APPLY=fal"
  },
  {
    "path": "application/pr/config.mk",
    "chars": 109,
    "preview": "FREQ=280\n\nQUEUE_SIZE_FILTER=16\nQUEUE_SIZE_MEMORY=512\n\nLOG_SCATTER_CACHE_BURST_SIZE=6\n\nAPPLY_REF_ARRAY_SIZE=1\n"
  },
  {
    "path": "application/pr/dataPrepare.cpp",
    "chars": 1236,
    "preview": "#include \"host_graph_api.h\"\n#include \"fpga_application.h\"\n\n#define INT2FLOAT                   (pow(2,30))\n\nint float2in"
  },
  {
    "path": "application/pr/l2.h",
    "chars": 1152,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n\n#define kDamp               (0.85f)\n#define kDampFixPoint       108//(0.85 << 7)  //"
  },
  {
    "path": "application/spmv/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/spmv/build.mk",
    "chars": 217,
    "preview": "\n#scatter-gather kernel\nHAVE_EDGE_PROP=true\nHAVE_UNSIGNED_PROP=false\n\n#apply kernel\nHAVE_APPLY=false\nCUSTOMIZE_APPLY=fal"
  },
  {
    "path": "application/spmv/config.mk",
    "chars": 109,
    "preview": "FREQ=250\n\nQUEUE_SIZE_FILTER=32\nQUEUE_SIZE_MEMORY=512\n\nLOG_SCATTER_CACHE_BURST_SIZE=7\n\nAPPLY_REF_ARRAY_SIZE=1\n"
  },
  {
    "path": "application/spmv/dataPrepare.cpp",
    "chars": 634,
    "preview": "#include \"host_graph_api.h\"\n\n\nunsigned int dataPrepareGetArg(graphInfo *info)\n{\n\treturn 0;\n}\n\nint dataPrepareProperty(gr"
  },
  {
    "path": "application/spmv/l2.h",
    "chars": 771,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n/* source vertex property process */\ninline prop_t preprocessProperty(prop_t srcProp)"
  },
  {
    "path": "application/sssp/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/sssp/build.mk",
    "chars": 215,
    "preview": "\n#scatter-gather kernel\nHAVE_EDGE_PROP=true\nHAVE_UNSIGNED_PROP=true\n\n#apply kernel\nHAVE_APPLY=true\nCUSTOMIZE_APPLY=false"
  },
  {
    "path": "application/sssp/config.mk",
    "chars": 109,
    "preview": "FREQ=250\n\nQUEUE_SIZE_FILTER=16\nQUEUE_SIZE_MEMORY=512\n\nLOG_SCATTER_CACHE_BURST_SIZE=6\n\nAPPLY_REF_ARRAY_SIZE=1\n"
  },
  {
    "path": "application/sssp/dataPrepare.cpp",
    "chars": 857,
    "preview": "#include \"host_graph_api.h\"\n#include \"fpga_application.h\"\n\nunsigned int dataPrepareGetArg(graphInfo *info)\n{\n    return "
  },
  {
    "path": "application/sssp/l2.h",
    "chars": 1726,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n\n#define MAX_PROP                  (INT_MAX - 1)\n\n#define VERTEX_ACTIVE_BIT_MASK    ("
  },
  {
    "path": "application/template/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/template/build.mk",
    "chars": 266,
    "preview": "# Need modification !\n\n#scatter-gather kernel\nHAVE_EDGE_PROP=true/false\nHAVE_UNSIGNED_PROP=true/false\n\n#apply kernel\nHAV"
  },
  {
    "path": "application/template/config.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/template/host_vertex_apply.cpp",
    "chars": 360,
    "preview": "#include \"host_graph_sw.h\"\n\n#include \"fpga_application.h\"\n\n#include \"host_graph_verification.h\"\n\n\nvoid setApplyKernel(cl"
  },
  {
    "path": "application/template/l2.h",
    "chars": 540,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n/* source vertex property process */\ninline prop_t preprocessProperty(prop_t srcProp)"
  },
  {
    "path": "application/template/vertex_apply.cpp",
    "chars": 7144,
    "preview": "#include <hls_stream.h>\n#include <string.h>\n#include \"graph_fpga.h\"\n\n\n#include \"fpga_global_mem.h\"\n\n\nvoid apply(\n    int"
  },
  {
    "path": "application/wcc/apply_kernel.mk",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "application/wcc/build.mk",
    "chars": 217,
    "preview": "\n#scatter-gather kernel\nHAVE_EDGE_PROP=false\nHAVE_UNSIGNED_PROP=true\n\n#apply kernel\nHAVE_APPLY=true\nCUSTOMIZE_APPLY=fals"
  },
  {
    "path": "application/wcc/config.mk",
    "chars": 109,
    "preview": "FREQ=250\n\nQUEUE_SIZE_FILTER=32\nQUEUE_SIZE_MEMORY=512\n\nLOG_SCATTER_CACHE_BURST_SIZE=7\n\nAPPLY_REF_ARRAY_SIZE=1\n"
  },
  {
    "path": "application/wcc/dataPrepare.cpp",
    "chars": 621,
    "preview": "#include \"host_graph_api.h\"\n#include \"fpga_application.h\"\n\n#include <cstdlib>\n#include <iostream>\n#include <ctime>\n\nunsi"
  },
  {
    "path": "application/wcc/l2.h",
    "chars": 1233,
    "preview": "#ifndef __L2_H__\n#define __L2_H__\n\n\n/*\n    Reference the mapping method in TABLE 1 from hitgraph:\n    Zhou, Shijie, et a"
  },
  {
    "path": "automation/auto_gen_code.mk",
    "chars": 1592,
    "preview": "include ThunderGP.mk\n\nCODE_GEN_PATH   =./automation\nCODE_GEN_PARSER_PATH  = $(CODE_GEN_PATH)/parser\nCODE_GEN_FILE =  $(C"
  },
  {
    "path": "automation/auto_gen_makefile.mk",
    "chars": 809,
    "preview": "include ThunderGP.mk\n\nCODE_GEN_PATH  =./automation\nCODE_GEN_FILE  =  $(CODE_GEN_PATH)/makefile_gen.cpp\nCODE_GEN_FILE += "
  },
  {
    "path": "automation/auto_gen_parameters.mk",
    "chars": 613,
    "preview": "include ThunderGP.mk\n\nCODE_GEN_PATH  =./automation\nPARA_GEN_CFLAGS := -I $(CODE_GEN_PATH)/devices\nPARA_GEN_CFLAGS += -DD"
  },
  {
    "path": "automation/devices/device_common.h",
    "chars": 214,
    "preview": "#ifndef __DEVICE_COMMON_H__\n#define __DEVICE_COMMON_H__\n\ntypedef struct \n{\n\tint slr_id;\n\tint luts;\n\tint ffs;\n\tint dsp;\n\t"
  },
  {
    "path": "automation/devices/xilinx_u200_xdma_201830_2.h",
    "chars": 756,
    "preview": "#include \"device_common.h\"\n\nconst char * board_name = \"u200\";\n\nconst slr_resource_info_t slrs[] =\n{\n    {\n        .slr_i"
  },
  {
    "path": "automation/devices/xilinx_u250_xdma_201830_2.h",
    "chars": 940,
    "preview": "#include \"device_common.h\"\n\nconst char * board_name = \"u250\";\n\nconst slr_resource_info_t slrs[] =\n{\n    {\n        .slr_i"
  },
  {
    "path": "automation/devices/xilinx_vcu1525_xdma_201830_1.h",
    "chars": 759,
    "preview": "#include \"device_common.h\"\n\nconst char * board_name = \"vcu1525\";\n\nconst slr_resource_info_t slrs[] =\n{\n    {\n        .sl"
  },
  {
    "path": "automation/makefile_gen.cpp",
    "chars": 2116,
    "preview": "#include <cmath>\n#include <cstdio>\n#include <vector>\n#include <fstream>\n#include <sstream>\n#include <iostream>\n\n#include"
  },
  {
    "path": "automation/para_gen.cpp",
    "chars": 10103,
    "preview": "#include <cmath>\n#include <cstdio>\n#include <vector>\n#include <fstream>\n#include <sstream>\n#include <iostream>\n\n#include"
  },
  {
    "path": "automation/parser/customize.cpp",
    "chars": 17421,
    "preview": "#include <iostream>\n#include <vector>\n#include <string>\n#include <fstream>\n#include <sstream>\n#include <algorithm>\n\n#inc"
  },
  {
    "path": "automation/parser/customize.h",
    "chars": 211,
    "preview": "#ifndef __CUSTOMIZE_INTERFACE_H__\n#define __CUSTOMIZE_INTERFACE_H__\n\nextern output_method_t customize_output_method;\n\nex"
  },
  {
    "path": "automation/parser/customize_str.h",
    "chars": 1340,
    "preview": "#ifndef __CUSTOMIZE_STR_H__\n#define __CUSTOMIZE_STR_H__\n\n\n\n#define  STREAM_ATTR_STR (\"\\n\\\n#pragma HLS INTERFACE m_axi po"
  },
  {
    "path": "automation/parser/kernel_interface.cpp",
    "chars": 2290,
    "preview": "\n#include <iostream>\n#include <vector>\n#include <string>\n#include <fstream>\n#include <sstream>\n\n\n#include \"parser.h\"\n#in"
  },
  {
    "path": "automation/parser/kernel_interface.h",
    "chars": 196,
    "preview": "#ifndef __KERNEL_INTERFACE_H__\n#define __KERNEL_INTERFACE_H__\n\nextern output_method_t kernel_output_method;\n\nextern reg_"
  },
  {
    "path": "automation/parser/makefile.cpp",
    "chars": 1739,
    "preview": "\n#include <iostream>\n#include <vector>\n#include <string>\n#include <fstream>\n#include <sstream>\n\n#include \"parser.h\"\n#inc"
  },
  {
    "path": "automation/parser/makefile.h",
    "chars": 206,
    "preview": "#ifndef __MAKEFILE_INTERFACE_H__\n#define __MAKEFILE_INTERFACE_H__\n\nextern output_method_t makefile_output_method;\n\nexter"
  },
  {
    "path": "automation/parser/mem_interface.cpp",
    "chars": 6978,
    "preview": "\n#include <iostream>\n#include <vector>\n#include <string>\n#include <fstream>\n#include <sstream>\n\n\n\n#include \"parser.h\"\n#i"
  },
  {
    "path": "automation/parser/mem_interface.h",
    "chars": 181,
    "preview": "#ifndef __MEM_INTERFACE_H__\n#define __MEM_INTERFACE_H__\n\nextern output_method_t mem_output_method;\n\nextern reg_parser_it"
  },
  {
    "path": "automation/parser.cpp",
    "chars": 6923,
    "preview": "\n#include <string>\n#include <cctype>\n#include <algorithm>\n#include <cstdlib>\n#include <iostream>\n#include <fstream>\n#inc"
  },
  {
    "path": "automation/parser.h",
    "chars": 2220,
    "preview": "#ifndef __PARSER_H__\n#define __PARSER_H__\n\n#include \"common.h\"\n\n#define MAX_CHAR_LENGTH         (256)\n\n#define PRAGMA_ID"
  },
  {
    "path": "automation/parser_debug.cpp",
    "chars": 450,
    "preview": "#include <string>\n#include <stdarg.h>\n\nvoid logger (char *fmt, ...)\n{\n    va_list argp;\n    fprintf(stdout, \"[PARSER] \")"
  },
  {
    "path": "automation/parser_debug.h",
    "chars": 209,
    "preview": "#ifndef __PARSER_DEBUG__\n#define __PARSER_DEBUG__\n\n#undef DEBUG_PRINTF\n#define DEBUG_PRINTF(fmt,...)   logger((char *)fm"
  },
  {
    "path": "dataset/README.md",
    "chars": 1601,
    "preview": "# Dataset and Data Format\n\n\n| Graphs  | *```E```* | *```V```*  | *```D_avg```* | Graph type |\n|--------|-----------|----"
  },
  {
    "path": "dataset/kronecker_generator.m",
    "chars": 1441,
    "preview": "function ijw = kronecker_generator (SCALE, edgefactor)\n%% Generate an edgelist according to the Graph500 parameters.  In"
  },
  {
    "path": "dataset/rmat-14-32.txt",
    "chars": 6116519,
    "preview": "5430 9982 \n10517 12137 \n9114 7782 \n13395 8156 \n2102 2122 \n16046 1212 \n11053 14922 \n1551 15526 \n11851 15530 \n11934 2508 \n"
  },
  {
    "path": "dataset/rmat.m",
    "chars": 394,
    "preview": "clear all\nscale = 19;\nedge_factor = 32;\nrand (\"seed\", 103);\n\nijw = kronecker_generator (scale, edge_factor);\n\nG = sparse"
  },
  {
    "path": "docs/algorithm_mapping.md",
    "chars": 7155,
    "preview": "\n# Algorithm Mapping \nIn this section, we introduce how to map new algorithms to our framework with __L2__ level APIs pr"
  },
  {
    "path": "docs/api_details.md",
    "chars": 5896,
    "preview": "\n# API Table\n\n## L1 \n### Stream Operations\nTo provide more portability, ThunderGP warps some operations on steam channel"
  },
  {
    "path": "docs/compile_arch.md",
    "chars": 4064,
    "preview": "# Compiling ThunderGP\nThis page provides details of quickly deploying build-in graph analytic algorithms of ThunderGP.  "
  },
  {
    "path": "docs/memory.md",
    "chars": 3167,
    "preview": "# Memory Management\nIn this section, we demonstrate how to manage the memory in host side with __L3__ level APIs provide"
  },
  {
    "path": "docs/results.md",
    "chars": 6024,
    "preview": "# Experimental Results\n\nWe are currently working on the support of float type property and the release builds of the bit"
  },
  {
    "path": "docs/scheduling.md",
    "chars": 4917,
    "preview": "# Scheduling across Multi-SLRs\n\nWhile modern multi-SLRs based FPGAs provide high memory bandwidth and large hardware res"
  },
  {
    "path": "docs/verification.md",
    "chars": 489,
    "preview": "# Verification\n\nAs we have a cache in ThunderGP, the static verification method (emu-sw) can not be used for the verific"
  },
  {
    "path": "libfpga/common_template/apply_kernel.mk",
    "chars": 935,
    "preview": "ifeq ($(strip $(HAVE_APPLY)), $(strip $(VAR_TRUE)))\n$(XCLBIN)/vertexApply.$(TARGET).$(DSA).xo: $(APPLY_KERNEL_PATH)/appl"
  },
  {
    "path": "libfpga/common_template/apply_top.cpp",
    "chars": 3860,
    "preview": "#include <hls_stream.h>\n#include \"graph_fpga.h\"\n\n\n#include \"fpga_global_mem.h\"\n#include \"fpga_apply.h\"\n\n\n\nextern \"C\" {\n "
  },
  {
    "path": "libfpga/common_template/scatter_gather_top.cpp",
    "chars": 720,
    "preview": "#include <hls_stream.h>\n#include <string.h>\n#include \"graph_fpga.h\"\n\n#include \"fpga_global_mem.h\"\n#include \"fpga_slice.h"
  },
  {
    "path": "libfpga/customize_template/customize_apply_cl_kernel.h",
    "chars": 1553,
    "preview": "\nscalar_t global;\n\nvoid setApplyKernel(int partId, int superStep, graphInfo *info)\n{\n    int currentPropId = superStep %"
  },
  {
    "path": "libfpga/customize_template/customize_apply_kernel.mk",
    "chars": 829,
    "preview": "ifeq ($(strip $(HAVE_APPLY)), $(strip $(VAR_TRUE)))\n$(XCLBIN)/vertexApply.$(TARGET).$(DSA).xo: $(APPLY_KERNEL_PATH)/cust"
  },
  {
    "path": "libfpga/customize_template/customize_apply_top.cpp",
    "chars": 4803,
    "preview": "#include <hls_stream.h>\n#include \"graph_fpga.h\"\n\n\n#include \"fpga_global_mem.h\"\n#include \"fpga_apply.h\"\n\nunion type_cov {"
  },
  {
    "path": "libfpga/customize_template/customize_mem.h",
    "chars": 268,
    "preview": "#ifndef __CUSTOMIZE_MEM_H__\n#define __CUSTOMIZE_MEM_H__\n\n\ntypedef struct\n{\n#pragma THUNDERGP DUMP_MEM_SCALAR\n// mark for"
  },
  {
    "path": "libfpga/fpga_application.h",
    "chars": 797,
    "preview": "#ifndef __FPGA_APPLICATION_H__\n#define __FPGA_APPLICATION_H__\n\n\n\n#include \"l2.h\"\n\n\n#ifndef IS_ACTIVE_VERTEX\n#define IS_A"
  },
  {
    "path": "libfpga/fpga_apply.h",
    "chars": 4103,
    "preview": "#include <hls_stream.h>\n#include <string.h>\n#include \"graph_fpga.h\"\n\n\n#include \"fpga_global_mem.h\"\n\n\ntemplate <typename "
  },
  {
    "path": "libfpga/fpga_cache.h",
    "chars": 24748,
    "preview": "#ifndef __FPGA_CACHE_H__\n#define __FPGA_CACHE_H__\n\n\n#include \"graph_fpga.h\"\n\n\n\n#define URAM_DEPTH              (4096)\n#d"
  },
  {
    "path": "libfpga/fpga_decoder.h",
    "chars": 6783,
    "preview": "#ifndef __FPGA_DECODER_H__\n#define __FPGA_DECODER_H__\n\n#include \"graph_fpga.h\"\n\ninline shuffled_type shuffleDecoder(ucha"
  },
  {
    "path": "libfpga/fpga_edge_prop.h",
    "chars": 2550,
    "preview": "#ifndef __FPGA_EDGE_PROP_H__\n#define __FPGA_EDGE_PROP_H__\n\n#include \"graph_fpga.h\"\n\n#include \"fpga_application.h\"\n\nvoid "
  },
  {
    "path": "libfpga/fpga_filter.h",
    "chars": 1287,
    "preview": "#ifndef __FPGA_FILTER_H__\n#define __FPGA_FILTER_H__\n\n#include \"graph_fpga.h\"\n\n\nvoid tupleFilter(\n    filter_type        "
  },
  {
    "path": "libfpga/fpga_gather.h",
    "chars": 3590,
    "preview": "#ifndef __FPGA_GATHER_H__\n#define __FPGA_GATHER_H__\n\n#include \"graph_fpga.h\"\n\n#include \"fpga_decoder.h\"\n\nvoid shuffleDis"
  },
  {
    "path": "libfpga/fpga_global_mem.h",
    "chars": 4744,
    "preview": "#ifndef __FPGA_GLOBAL_MEM_H__\n#define __FPGA_GLOBAL_MEM_H__\n\n#include \"graph_fpga.h\"\n\n#include \"fpga_application.h\"\n\n\n#d"
  },
  {
    "path": "libfpga/fpga_gs_top.h",
    "chars": 7501,
    "preview": "\n{\n#pragma HLS INTERFACE m_axi port=edgesHeadArray offset=slave bundle=gmem0 max_read_burst_length=64\n#pragma HLS INTERF"
  },
  {
    "path": "libfpga/fpga_process_edge.h",
    "chars": 5291,
    "preview": "#ifndef __FPGA_PROCESS_EDGE_H__\n#define __FPGA_PROCESS_EDGE_H__\n\n\n#include \"graph_fpga.h\"\n\n#include \"fpga_raw_solver.h\"\n"
  },
  {
    "path": "libfpga/fpga_raw_solver.h",
    "chars": 7437,
    "preview": "#ifndef __FPGA_RAW_SOLVER_H__\n#define __FPGA_RAW_SOLVER_H__\n\n\n#include \"graph_fpga.h\"\n\n#include \"fpga_application.h\"\n\n\n#"
  },
  {
    "path": "libfpga/fpga_slice.h",
    "chars": 3500,
    "preview": "#ifndef __FPGA_SLICE_H__\n#define __FPGA_SLICE_H__\n\n#include \"graph_fpga.h\"\n\ntemplate <typename T>\nvoid  sliceStream(hls:"
  },
  {
    "path": "libfpga/graph_fpga.h",
    "chars": 4214,
    "preview": "#ifndef __GRAPH_FPGA_H__\n#define __GRAPH_FPGA_H__\n\n#define AP_INT_MAX_W 4096\n#include <ap_int.h>\n#include \"para_check.h\""
  },
  {
    "path": "libgraph/common.h",
    "chars": 1082,
    "preview": "#ifndef __COMMON_H__\n#define __COMMON_H__\n\n\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <malloc."
  },
  {
    "path": "libgraph/default_entry.cpp",
    "chars": 1290,
    "preview": "/* DEFAULT_ENTRY in build.mk */\n\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <fstream>\n\n#include"
  },
  {
    "path": "libgraph/host_graph_api.h",
    "chars": 899,
    "preview": "#ifndef __HOST_GRAPH_API_H__\n#define __HOST_GRAPH_API_H__\n\n#include <string>\n\n\n#include \"common.h\"\n#include \"global_conf"
  },
  {
    "path": "libgraph/host_graph_data_structure.h",
    "chars": 2254,
    "preview": "#ifndef __HOST_GRAPH_DATA_STRUCTURE_H__\n#define __HOST_GRAPH_DATA_STRUCTURE_H__\n\n#include \"graph.h\"\n\n#define MAX_PARTITI"
  },
  {
    "path": "libgraph/host_graph_dataflow.cpp",
    "chars": 3047,
    "preview": "\n#include \"host_graph_sw.h\"\n#include \"host_graph_scheduler.h\"\n\n\ngraphAccelerator thunderGraph;\n\ngraphAccelerator * getAc"
  },
  {
    "path": "libgraph/host_graph_partition.cpp",
    "chars": 13999,
    "preview": "\n#include \"host_graph_sw.h\"\n\n#include \"host_graph_mem.h\"\n\n#include \"host_graph_scheduler.h\"\n\n\n#define EDEG_MEMORY_SIZE  "
  },
  {
    "path": "libgraph/host_graph_sw.h",
    "chars": 448,
    "preview": "#ifndef __HOST_GRAPH_SW_H__\n#define __HOST_GRAPH_SW_H__\n\n#include \"para_check.h\"\n#include <stdint.h>\n\n#include \"common.h"
  },
  {
    "path": "libgraph/kernel/host_graph_kernel.cpp",
    "chars": 4876,
    "preview": "\n#include \"host_graph_sw.h\"\n\n\n#define HW_EMU_DEBUG        (0)\n#define HW_EMU_DEBUG_SIZE   (16384 * 4)\n\ngatherScatterDesc"
  },
  {
    "path": "libgraph/kernel/host_graph_kernel.h",
    "chars": 283,
    "preview": "#ifndef __HOST_GRAPH_SW_KERNEL_H__\n#define __HOST_GRAPH_SW_KERNEL_H__\n\nvoid kernelInit(graphAccelerator * acc);\n\nvoid se"
  },
  {
    "path": "libgraph/memory/he_mapping.cpp",
    "chars": 1737,
    "preview": "#include \"common.h\"\n#include \"he_mem.h\"\n\ntypedef struct\n{\n    int cu_id;\n    int mem_id;\n    int he_attr_id;\n    int int"
  },
  {
    "path": "libgraph/memory/he_mem.cpp",
    "chars": 6949,
    "preview": "#include <cstdlib>\n#include <iostream>\n#include <fstream>\n#include <sstream>\n#include <vector>\n\n#include \"common.h\"\n#inc"
  },
  {
    "path": "libgraph/memory/he_mem.h",
    "chars": 1835,
    "preview": "#ifndef __HE_MEM_H__\n#define __HE_MEM_H__\n\n\n#include \"xcl.h\"\n\n#define ATTR_HOST_ONLY              (0)\n#define ATTR_PL_DE"
  },
  {
    "path": "libgraph/memory/he_mem_attr.h",
    "chars": 273,
    "preview": "#ifndef __MEM_ATTR_H__\n#define __MEM_ATTR_H__\n\n\nsize_attr_ctrl_t local_size_ctrl[] = \n{\n    {\n        .size_attr  = SIZE"
  },
  {
    "path": "libgraph/memory/he_mem_config.h",
    "chars": 3315,
    "preview": "#ifndef __MEM_CONFIG_H__\n#define __MEM_CONFIG_H__\n\n\n\nhe_mem_t local_mem[] =\n{\n    {\n        MEM_ID_PROP_FOR_DATAPREPARE,"
  },
  {
    "path": "libgraph/memory/he_mem_id.h",
    "chars": 1449,
    "preview": "#ifndef __HE_MEM_ID_H__\n#define __HE_MEM_ID_H__\n\n\n\n#define SIZE_IN_EDGE                (0)\n#define SIZE_IN_VERTEX       "
  },
  {
    "path": "libgraph/misc/data_helper.cpp",
    "chars": 2793,
    "preview": "#include <stdio.h>\n\n#include \"graph.h\"\n\nGraph* createGraph(const std::string &gName, const std::string &mode) {\n    Grap"
  },
  {
    "path": "libgraph/misc/graph.cpp",
    "chars": 5528,
    "preview": "#include \"graph.h\"\n#include <cstdlib>\n#include <iostream>\n#include <fstream>\n\nvoid Graph::loadFile(\n    const std::strin"
  },
  {
    "path": "libgraph/misc/graph.h",
    "chars": 1968,
    "preview": "#ifndef __GRAPH_H__\n#define __GRAPH_H__\n\n#include \"global_config.h\"\n#include <vector>\n#include <fstream>\n#include <iostr"
  },
  {
    "path": "libgraph/misc/host_graph_csv.hpp",
    "chars": 3238,
    "preview": "#ifndef __HOST_GRAPH_CSV_HPP__\n#define __HOST_GRAPH_CSV_HPP__\n\n#include \"he_mem.h\"\n#include \"he_mem_id.h\"\n\n#include \"hos"
  },
  {
    "path": "libgraph/misc/host_graph_mem.cpp",
    "chars": 3599,
    "preview": "#include \"host_graph_sw.h\"\n\n#include \"he_mem_config.h\"\n\n\n#define PARTITION_DDR       (he_get_attr_by_cu(cuIndex))\n#defin"
  },
  {
    "path": "libgraph/misc/host_graph_mem.h",
    "chars": 283,
    "preview": "#ifndef __HOST_GRAPH_MEM_H__\n#define __HOST_GRAPH_MEM_H__\n\nextern void base_mem_init(cl_context &context);\nextern void p"
  },
  {
    "path": "libgraph/misc/host_graph_misc_inner.h",
    "chars": 598,
    "preview": "#ifndef __HOST_GRAPH_MISC_INNER_H__\n#define __HOST_GRAPH_MISC_INNER_H__\n\n#define DEFAULT_KERNEL_ID       (0)\n\n#define ch"
  },
  {
    "path": "libgraph/scheduler/host_graph_scheduler.cpp",
    "chars": 1341,
    "preview": "#include \"host_graph_sw.h\"\n\n#include \"host_graph_scheduler.h\"\n\nstatic graphStaticScheduler scheduler;\n\nstatic int partId"
  },
  {
    "path": "libgraph/scheduler/host_graph_scheduler.h",
    "chars": 771,
    "preview": "#ifndef __HOST_GRAPH_SCHEDULER__\n#define __HOST_GRAPH_SCHEDULER__\n\n\ntypedef int (* schedulerInitHanlder)(void *arg);\n\nty"
  },
  {
    "path": "libgraph/scheduler/normal/scheduler.cpp",
    "chars": 1062,
    "preview": "#include \"host_graph_sw.h\"\n\n#include \"host_graph_scheduler.h\"\n\n\nstatic int stepCounter = 0;\n\nint normalInitHanlder(void "
  },
  {
    "path": "libgraph/scheduler/secondOrderEstimator/scheduler.cpp",
    "chars": 3914,
    "preview": "#include \"host_graph_sw.h\"\n\n#include \"host_graph_scheduler.h\"\n\n\n\nstatic double cuPerformance[SUB_PARTITION_NUM];\n\n\n\ndoub"
  },
  {
    "path": "libgraph/test/test_col.c",
    "chars": 2339,
    "preview": "#include \"stdio.h\"\n\n#define SIZE_BY_INT   16\n\n\n#define INVALID_FLAG (0xffffffff)\n\nint main(int argc,  char **argv)\n{\n#if"
  },
  {
    "path": "libgraph/verification/host_graph_cmodel.cpp",
    "chars": 6691,
    "preview": "#include \"host_graph_verification_inner.h\"\n#include \"host_graph_scheduler.h\"\n\n\n#include \"global_config.h\"\n#include \"fpga"
  },
  {
    "path": "libgraph/verification/host_graph_verification.h",
    "chars": 341,
    "preview": "#ifndef __HOST_GRAPH_SW_VERIFICATION_H__\n#define __HOST_GRAPH_SW_VERIFICATION_H__\n\n\nint acceleratorProfile (int superSte"
  },
  {
    "path": "libgraph/verification/host_graph_verification_apply.cpp",
    "chars": 3966,
    "preview": "\n#include \"host_graph_verification_inner.h\"\n\n#include \"global_config.h\"\n#include \"fpga_application.h\"\n\n\n#if  CUSTOMIZE_A"
  },
  {
    "path": "libgraph/verification/host_graph_verification_gs.cpp",
    "chars": 3789,
    "preview": "#include \"host_graph_verification_inner.h\"\n\n#include \"global_config.h\"\n#include \"fpga_application.h\"\n\n\n\n\nvoid partitionG"
  },
  {
    "path": "libgraph/verification/host_graph_verification_inner.h",
    "chars": 795,
    "preview": "#ifndef __HOST_GRAPH_SW_VERIFICATION_INNER_H__\n#define __HOST_GRAPH_SW_VERIFICATION_INNER_H__\n\n#include \"host_graph_sw.h"
  },
  {
    "path": "utils/bitstream.mk",
    "chars": 882,
    "preview": "$(XCLBIN)/graph_fpga.$(TARGET).$(DSA).xclbin: $(BINARY_CONTAINER_OBJS)\n\t$(XOCC) $(CLFLAGS) -l $(LDCLFLAGS)   $(BINARY_LI"
  },
  {
    "path": "utils/clean.mk",
    "chars": 530,
    "preview": "cleanexe:\n\t-$(RMDIR) $(EXECUTABLE)\nclean:\n\t-$(RMDIR) $(EXECUTABLE) $(XCLBIN)/{*sw_emu*,*hw_emu*} \n\t-$(RMDIR) sdaccel_* T"
  },
  {
    "path": "utils/help.mk",
    "chars": 560,
    "preview": ".PHONY: help\n\nhelp::\n\t$(ECHO) \"Makefile Usage:\"\n\t$(ECHO) \"  make all TARGET=<sw_emu/hw_emu/hw> DEVICE=<FPGA platform>\"\n\t"
  },
  {
    "path": "utils/main.mk",
    "chars": 885,
    "preview": "$(shell ./utils/automation.sh $(app) > generator.log)\n\nSHELL          := /bin/bash\nTARGET         := $(TARGETS)\nDEVICE  "
  },
  {
    "path": "utils/opencl.mk",
    "chars": 198,
    "preview": "# Definition of include file locations\nOPENCL_INCLUDE:= $(XILINX_XRT)/include/\n\nopencl_CXXFLAGS=-I$(OPENCL_INCLUDE)\n\nOPE"
  },
  {
    "path": "utils/report_usage.tcl",
    "chars": 199,
    "preview": "open_project [lindex $argv 0]\nopen_run  impl_1\nreport_utilization -file  util_full.report\nreport_utilization -hierarchic"
  },
  {
    "path": "utils/utils.mk",
    "chars": 1764,
    "preview": "#+-------------------------------------------------------------------------------\n# The following parameters are assigne"
  },
  {
    "path": "utils/xcl/xcl.c",
    "chars": 14998,
    "preview": "/**********\nCopyright (c) 2018, Xilinx, Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, wi"
  },
  {
    "path": "utils/xcl/xcl.h",
    "chars": 8913,
    "preview": "/**********\nCopyright (c) 2018, Xilinx, Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, wi"
  },
  {
    "path": "utils/xcl/xcl.mk",
    "chars": 103,
    "preview": "xcl_SRCS:=${UTILS_PATH}/xcl/xcl.c\nxcl_HDRS:=${UTILS_PATH}/xcl/xcl.h\n\nxcl_CXXFLAGS:=-I${UTILS_PATH}/xcl\n"
  }
]

About this extraction

This page contains the full source code of the Xtra-Computing/ThunderGP GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 166 files (6.2 MB), approximately 1.6M tokens, and a symbol index with 268 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!