Upload folder using huggingface_hub
Browse files- .gitattributes +22 -10
- README.md +140 -0
- config/config.yaml +41 -0
- configuration.json +9 -0
- data/splits/test.txt +118 -0
- data/splits/train.txt +947 -0
- data/splits/valid.txt +118 -0
- model/graphViT.py +173 -0
- scripts/fake_data.py +86 -0
- scripts/inference.py +121 -0
- scripts/result.py +23 -0
- scripts/train.py +246 -0
.gitattributes
CHANGED
|
@@ -1,35 +1,47 @@
|
|
| 1 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 4 |
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 1 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bin.* filter=lfs diff=lfs merge=lfs -text
|
| 5 |
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 6 |
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 11 |
*.model filter=lfs diff=lfs merge=lfs -text
|
| 12 |
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
| 13 |
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 14 |
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 15 |
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 16 |
*.pb filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
| 17 |
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 18 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 19 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 20 |
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 21 |
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 22 |
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 23 |
*.tgz filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 24 |
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 25 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
*.zstandard filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.db* filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.ark* filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
**/*ckpt*data* filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
**/*ckpt*.meta filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
**/*ckpt*.index filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*.gguf* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
*.ggml filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
*.llamafile* filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
*.pt2 filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 46 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 47 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
language:
|
| 4 |
+
- en
|
| 5 |
+
tags:
|
| 6 |
+
- OneScience
|
| 7 |
+
- fluid dynamics
|
| 8 |
+
- unsteady turbulent flow prediction
|
| 9 |
+
- long-range mesh dependency modeling
|
| 10 |
+
frameworks: PyTorch
|
| 11 |
+
---
|
| 12 |
+
<p align="center">
|
| 13 |
+
<strong>
|
| 14 |
+
<span style="font-size: 30px;">EagleMeshTransformer</span>
|
| 15 |
+
</strong>
|
| 16 |
+
</p>
|
| 17 |
+
|
| 18 |
+
# Model Overview
|
| 19 |
+
|
| 20 |
+
EagleMeshTransformer is a multiscale Mesh Transformer developed by the LIRIS research laboratory in Lyon, France, for fluid prediction on dynamic unstructured meshes. It is particularly well suited to unsteady turbulent flows and problems involving long-range dependencies in flow fields.
|
| 21 |
+
|
| 22 |
+
Paper: [EAGLE: Large-scale Learning of Turbulent Fluid Dynamics with Mesh Transformers](https://arxiv.org/abs/2302.10803).
|
| 23 |
+
|
| 24 |
+
# Model Description
|
| 25 |
+
|
| 26 |
+
EagleMeshTransformer uses a multiscale Mesh Transformer architecture trained on the EAGLE dataset to predict velocity and pressure fields in complex unsteady flows.
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
## Use Cases
|
| 31 |
+
|
| 32 |
+
| Use Case | Description |
|
| 33 |
+
|---|---|
|
| 34 |
+
| Unsteady turbulent flow prediction | Predict velocity and pressure fields in complex, aperiodic turbulent flows involving drones, jets, wakes, and similar systems |
|
| 35 |
+
| Unstructured-mesh simulation | Process irregular mesh data defined on complex geometries |
|
| 36 |
+
| CFD surrogate acceleration | Provide fast approximations of conventional Navier–Stokes and CFD simulations |
|
| 37 |
+
| Long-horizon physical prediction | Predict the evolution of physical states through autoregressive rollouts |
|
| 38 |
+
|
| 39 |
+
# Usage
|
| 40 |
+
|
| 41 |
+
## 1. OneCode
|
| 42 |
+
|
| 43 |
+
Use the online OneCode environment for an intelligent, one-click AI for Science (AI4S) programming experience:
|
| 44 |
+
|
| 45 |
+
[Launch OneCode for one-click AI4S programming](https://web-2069360198568017922-iaaj.ksai.scnet.cn:58043/home)
|
| 46 |
+
|
| 47 |
+
## 2. Manual Setup
|
| 48 |
+
|
| 49 |
+
**Hardware Requirements**
|
| 50 |
+
|
| 51 |
+
- A GPU or DCU is recommended.
|
| 52 |
+
- A CPU can be used for import checks and small-scale pipeline validation, but full training and inference will be slow.
|
| 53 |
+
- DCU users must install DTK in advance. DTK 25.04.2 or later, or the OneScience-recommended version for the target cluster, is recommended.
|
| 54 |
+
|
| 55 |
+
### Download the Model Package
|
| 56 |
+
|
| 57 |
+
```bash
|
| 58 |
+
modelscope download --model OneScience/EagleMeshTransformer --local_dir ./EagleMeshTransformer
|
| 59 |
+
cd EagleMeshTransformer
|
| 60 |
+
```
|
| 61 |
+
|
| 62 |
+
### Set Up the Runtime Environment
|
| 63 |
+
|
| 64 |
+
**DCU Environment**
|
| 65 |
+
|
| 66 |
+
```bash
|
| 67 |
+
# Activate DTK and Conda first
|
| 68 |
+
conda create -n onescience311 python=3.11 -y
|
| 69 |
+
conda activate onescience311
|
| 70 |
+
# Installation with uv is also supported
|
| 71 |
+
pip install onescience[cfd-dcu] -i http://mirrors.onescience.ai:3141/pypi/simple/ --trusted-host mirrors.onescience.ai
|
| 72 |
+
```
|
| 73 |
+
|
| 74 |
+
**GPU Environment**
|
| 75 |
+
```bash
|
| 76 |
+
# Activate Conda first
|
| 77 |
+
conda create -n onescience311 python=3.11 -y libstdcxx-ng=12 libgcc-ng=12 gcc_linux-64=12 gxx_linux-64=12
|
| 78 |
+
conda activate onescience311
|
| 79 |
+
# Installation with uv is also supported
|
| 80 |
+
pip install onescience[cfd-gpu] -i http://mirrors.onescience.ai:3141/pypi/simple/ --trusted-host mirrors.onescience.ai
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
### Synthetic Data Validation
|
| 84 |
+
|
| 85 |
+
The default configuration points to the synthetic data directory in this repository and sets `training.max_epoch` to `1`. Generate a minimal EAGLE NPZ dataset to validate the training and inference pipelines:
|
| 86 |
+
|
| 87 |
+
```bash
|
| 88 |
+
python scripts/fake_data.py
|
| 89 |
+
```
|
| 90 |
+
### Training Data
|
| 91 |
+
The OneScience community provides the EAGLE dataset for training. Download it with the command below and verify that the data path in `conf/config.yaml` is configured correctly.
|
| 92 |
+
|
| 93 |
+
```bash
|
| 94 |
+
modelscope download --dataset OneScience/eagle --local_dir ./data
|
| 95 |
+
```
|
| 96 |
+
|
| 97 |
+
### Training
|
| 98 |
+
|
| 99 |
+
Single GPU:
|
| 100 |
+
|
| 101 |
+
```bash
|
| 102 |
+
python scripts/train.py
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
Multiple GPUs:
|
| 106 |
+
|
| 107 |
+
```bash
|
| 108 |
+
torchrun --nproc_per_node=8 --nnodes=1 --rdzv_id=1000 --rdzv_backend=c10d --max_restarts=0 --master_addr="localhost" --master_port=29500 scripts/train.py
|
| 109 |
+
```
|
| 110 |
+
|
| 111 |
+
Training saves `best_model.pth` in the `weight/` directory.
|
| 112 |
+
|
| 113 |
+
### Model Weights
|
| 114 |
+
This repository will provide pretrained EagleMeshTransformer weights in the `weights/` directory. The weights will be uploaded soon.
|
| 115 |
+
|
| 116 |
+
### Inference
|
| 117 |
+
|
| 118 |
+
```bash
|
| 119 |
+
python scripts/inference.py
|
| 120 |
+
```
|
| 121 |
+
|
| 122 |
+
Inference results are saved to `result/output/`.
|
| 123 |
+
|
| 124 |
+
### Evaluation and Visualization
|
| 125 |
+
|
| 126 |
+
```bash
|
| 127 |
+
python scripts/result.py
|
| 128 |
+
```
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
# Official OneScience Resources
|
| 132 |
+
|
| 133 |
+
| Platform | OneScience Repository | Skills Repository |
|
| 134 |
+
| --- | --- | --- |
|
| 135 |
+
| Gitee | https://gitee.com/onescience-ai/onescience | https://gitee.com/onescience-ai/oneskills |
|
| 136 |
+
| GitHub | https://github.com/onescience-ai/OneScience | https://github.com/onescience-ai/oneskills |
|
| 137 |
+
|
| 138 |
+
# Citations and License
|
| 139 |
+
- Original EagleMeshTransformer paper: [EAGLE: Large-scale Learning of Turbulent Fluid Dynamics with Mesh Transformers](https://arxiv.org/abs/2302.10803).
|
| 140 |
+
- This repository retains source attribution and has been adapted for automated execution through OneScience and ModelScope.
|
config/config.yaml
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model:
|
| 2 |
+
name: "EagleMeshTransformer"
|
| 3 |
+
architecture: "GraphViT"
|
| 4 |
+
state_size: 4
|
| 5 |
+
w_size: 32
|
| 6 |
+
|
| 7 |
+
datapipe:
|
| 8 |
+
source:
|
| 9 |
+
data_dir: "./data/fake/Eagle_dataset"
|
| 10 |
+
cluster_dir: "./data/fake/Eagle_dataset"
|
| 11 |
+
splits_dir: "./data/fake/splits"
|
| 12 |
+
|
| 13 |
+
verbose: false
|
| 14 |
+
|
| 15 |
+
data:
|
| 16 |
+
window_length_train: 3
|
| 17 |
+
window_length_val: 3
|
| 18 |
+
window_length_test: 3
|
| 19 |
+
n_cluster: 1
|
| 20 |
+
normalized: true
|
| 21 |
+
type_as_onehot: true
|
| 22 |
+
with_cells: true
|
| 23 |
+
|
| 24 |
+
dataloader:
|
| 25 |
+
batch_size: 1
|
| 26 |
+
num_workers: 0
|
| 27 |
+
|
| 28 |
+
training:
|
| 29 |
+
max_epoch: 1
|
| 30 |
+
lr: 1.0e-4
|
| 31 |
+
loss_alpha: 0.1
|
| 32 |
+
patience: 10
|
| 33 |
+
checkpoint_dir: "./weight"
|
| 34 |
+
seed: 0
|
| 35 |
+
device: "cpu"
|
| 36 |
+
|
| 37 |
+
inference:
|
| 38 |
+
checkpoint_path: "./weight/best_model.pth"
|
| 39 |
+
output_dir: "./result/output"
|
| 40 |
+
batch_size: 1
|
| 41 |
+
device: "cpu"
|
configuration.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"framework": "Pytorch",
|
| 3 |
+
"task": "other",
|
| 4 |
+
"model": {
|
| 5 |
+
"type": "EagleMeshTransformer",
|
| 6 |
+
"architecture": "GraphViT"
|
| 7 |
+
},
|
| 8 |
+
"allow_remote": false
|
| 9 |
+
}
|
data/splits/test.txt
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Spl/184/2
|
| 2 |
+
Tri/194/2
|
| 3 |
+
Cre/185/1
|
| 4 |
+
Tri/199/1
|
| 5 |
+
Spl/188/1
|
| 6 |
+
Tri/182/2
|
| 7 |
+
Spl/181/2
|
| 8 |
+
Spl/199/1
|
| 9 |
+
Spl/187/2
|
| 10 |
+
Tri/189/2
|
| 11 |
+
Cre/182/1
|
| 12 |
+
Spl/181/1
|
| 13 |
+
Spl/182/2
|
| 14 |
+
Tri/197/2
|
| 15 |
+
Tri/181/2
|
| 16 |
+
Spl/199/2
|
| 17 |
+
Spl/188/2
|
| 18 |
+
Tri/185/1
|
| 19 |
+
Spl/182/1
|
| 20 |
+
Spl/183/1
|
| 21 |
+
Spl/185/2
|
| 22 |
+
Spl/191/2
|
| 23 |
+
Spl/191/1
|
| 24 |
+
Cre/191/1
|
| 25 |
+
Tri/195/1
|
| 26 |
+
Tri/191/1
|
| 27 |
+
Spl/189/1
|
| 28 |
+
Cre/191/2
|
| 29 |
+
Spl/185/1
|
| 30 |
+
Tri/200/2
|
| 31 |
+
Cre/183/1
|
| 32 |
+
Tri/187/2
|
| 33 |
+
Cre/200/1
|
| 34 |
+
Tri/186/2
|
| 35 |
+
Tri/198/2
|
| 36 |
+
Cre/188/1
|
| 37 |
+
Cre/192/1
|
| 38 |
+
Tri/197/1
|
| 39 |
+
Tri/185/2
|
| 40 |
+
Cre/189/2
|
| 41 |
+
Cre/193/1
|
| 42 |
+
Spl/200/1
|
| 43 |
+
Cre/182/2
|
| 44 |
+
Spl/198/2
|
| 45 |
+
Spl/200/2
|
| 46 |
+
Tri/193/1
|
| 47 |
+
Tri/194/1
|
| 48 |
+
Cre/181/1
|
| 49 |
+
Tri/182/1
|
| 50 |
+
Tri/184/2
|
| 51 |
+
Cre/190/1
|
| 52 |
+
Tri/198/1
|
| 53 |
+
Spl/190/1
|
| 54 |
+
Cre/194/1
|
| 55 |
+
Tri/184/1
|
| 56 |
+
Cre/186/2
|
| 57 |
+
Spl/193/1
|
| 58 |
+
Tri/199/2
|
| 59 |
+
Spl/183/2
|
| 60 |
+
Spl/197/1
|
| 61 |
+
Cre/184/2
|
| 62 |
+
Spl/195/2
|
| 63 |
+
Cre/195/2
|
| 64 |
+
Cre/198/1
|
| 65 |
+
Cre/197/2
|
| 66 |
+
Tri/190/2
|
| 67 |
+
Tri/193/2
|
| 68 |
+
Spl/186/1
|
| 69 |
+
Cre/199/2
|
| 70 |
+
Cre/193/2
|
| 71 |
+
Tri/195/2
|
| 72 |
+
Cre/199/1
|
| 73 |
+
Spl/184/1
|
| 74 |
+
Cre/187/2
|
| 75 |
+
Tri/188/2
|
| 76 |
+
Tri/181/1
|
| 77 |
+
Tri/183/2
|
| 78 |
+
Cre/198/2
|
| 79 |
+
Cre/189/1
|
| 80 |
+
Cre/195/1
|
| 81 |
+
Tri/192/1
|
| 82 |
+
Cre/196/2
|
| 83 |
+
Cre/192/2
|
| 84 |
+
Spl/197/2
|
| 85 |
+
Tri/186/1
|
| 86 |
+
Tri/196/2
|
| 87 |
+
Tri/188/1
|
| 88 |
+
Spl/196/1
|
| 89 |
+
Tri/200/1
|
| 90 |
+
Spl/190/2
|
| 91 |
+
Cre/194/2
|
| 92 |
+
Spl/192/1
|
| 93 |
+
Cre/190/2
|
| 94 |
+
Cre/187/1
|
| 95 |
+
Spl/198/1
|
| 96 |
+
Spl/189/2
|
| 97 |
+
Cre/186/1
|
| 98 |
+
Cre/188/2
|
| 99 |
+
Spl/193/2
|
| 100 |
+
Spl/195/1
|
| 101 |
+
Tri/187/1
|
| 102 |
+
Spl/192/2
|
| 103 |
+
Cre/184/1
|
| 104 |
+
Tri/189/1
|
| 105 |
+
Spl/187/1
|
| 106 |
+
Tri/192/2
|
| 107 |
+
Tri/190/1
|
| 108 |
+
Cre/181/2
|
| 109 |
+
Cre/185/2
|
| 110 |
+
Tri/196/1
|
| 111 |
+
Cre/200/2
|
| 112 |
+
Cre/183/2
|
| 113 |
+
Cre/196/1
|
| 114 |
+
Spl/186/2
|
| 115 |
+
Spl/196/2
|
| 116 |
+
Tri/183/1
|
| 117 |
+
Tri/191/2
|
| 118 |
+
Cre/197/1
|
data/splits/train.txt
ADDED
|
@@ -0,0 +1,947 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Spl/20/2
|
| 2 |
+
Spl/26/1
|
| 3 |
+
Spl/85/1
|
| 4 |
+
Cre/55/2
|
| 5 |
+
Spl/38/2
|
| 6 |
+
Tri/124/1
|
| 7 |
+
Tri/78/1
|
| 8 |
+
Cre/103/2
|
| 9 |
+
Cre/148/2
|
| 10 |
+
Tri/96/2
|
| 11 |
+
Tri/66/2
|
| 12 |
+
Cre/63/2
|
| 13 |
+
Spl/22/2
|
| 14 |
+
Tri/110/2
|
| 15 |
+
Tri/35/2
|
| 16 |
+
Tri/26/2
|
| 17 |
+
Cre/108/1
|
| 18 |
+
Spl/124/2
|
| 19 |
+
Spl/73/1
|
| 20 |
+
Tri/15/2
|
| 21 |
+
Tri/125/1
|
| 22 |
+
Spl/53/2
|
| 23 |
+
Tri/79/2
|
| 24 |
+
Spl/57/2
|
| 25 |
+
Cre/109/2
|
| 26 |
+
Spl/32/1
|
| 27 |
+
Spl/51/2
|
| 28 |
+
Cre/145/2
|
| 29 |
+
Tri/102/1
|
| 30 |
+
Tri/8/1
|
| 31 |
+
Cre/28/2
|
| 32 |
+
Tri/17/1
|
| 33 |
+
Tri/73/2
|
| 34 |
+
Spl/137/1
|
| 35 |
+
Spl/2/1
|
| 36 |
+
Tri/1/2
|
| 37 |
+
Spl/106/2
|
| 38 |
+
Tri/49/2
|
| 39 |
+
Cre/73/1
|
| 40 |
+
Cre/25/1
|
| 41 |
+
Tri/106/2
|
| 42 |
+
Tri/140/2
|
| 43 |
+
Cre/143/1
|
| 44 |
+
Tri/10/2
|
| 45 |
+
Tri/40/1
|
| 46 |
+
Tri/122/1
|
| 47 |
+
Cre/111/2
|
| 48 |
+
Cre/41/2
|
| 49 |
+
Spl/71/1
|
| 50 |
+
Spl/146/1
|
| 51 |
+
Spl/50/2
|
| 52 |
+
Spl/136/1
|
| 53 |
+
Cre/104/1
|
| 54 |
+
Cre/152/1
|
| 55 |
+
Spl/30/1
|
| 56 |
+
Tri/105/1
|
| 57 |
+
Tri/118/2
|
| 58 |
+
Spl/149/1
|
| 59 |
+
Cre/138/2
|
| 60 |
+
Cre/122/2
|
| 61 |
+
Spl/43/2
|
| 62 |
+
Cre/31/2
|
| 63 |
+
Spl/120/2
|
| 64 |
+
Cre/69/2
|
| 65 |
+
Spl/153/1
|
| 66 |
+
Spl/44/1
|
| 67 |
+
Spl/155/2
|
| 68 |
+
Spl/155/1
|
| 69 |
+
Tri/103/2
|
| 70 |
+
Tri/42/1
|
| 71 |
+
Tri/101/2
|
| 72 |
+
Tri/74/1
|
| 73 |
+
Cre/122/1
|
| 74 |
+
Spl/34/1
|
| 75 |
+
Spl/34/2
|
| 76 |
+
Cre/141/1
|
| 77 |
+
Cre/35/1
|
| 78 |
+
Spl/129/1
|
| 79 |
+
Spl/70/1
|
| 80 |
+
Tri/130/1
|
| 81 |
+
Tri/133/2
|
| 82 |
+
Tri/44/2
|
| 83 |
+
Spl/121/1
|
| 84 |
+
Cre/13/2
|
| 85 |
+
Tri/60/2
|
| 86 |
+
Cre/23/2
|
| 87 |
+
Cre/134/2
|
| 88 |
+
Tri/100/1
|
| 89 |
+
Tri/6/1
|
| 90 |
+
Tri/99/2
|
| 91 |
+
Spl/116/2
|
| 92 |
+
Tri/100/2
|
| 93 |
+
Tri/6/2
|
| 94 |
+
Tri/124/2
|
| 95 |
+
Cre/101/2
|
| 96 |
+
Cre/63/1
|
| 97 |
+
Tri/147/2
|
| 98 |
+
Spl/103/2
|
| 99 |
+
Cre/18/1
|
| 100 |
+
Cre/131/1
|
| 101 |
+
Cre/81/1
|
| 102 |
+
Spl/74/1
|
| 103 |
+
Cre/18/2
|
| 104 |
+
Spl/139/2
|
| 105 |
+
Cre/74/2
|
| 106 |
+
Spl/20/1
|
| 107 |
+
Cre/15/2
|
| 108 |
+
Cre/153/1
|
| 109 |
+
Cre/70/2
|
| 110 |
+
Tri/104/1
|
| 111 |
+
Spl/58/2
|
| 112 |
+
Spl/102/2
|
| 113 |
+
Cre/136/1
|
| 114 |
+
Tri/25/1
|
| 115 |
+
Cre/28/1
|
| 116 |
+
Spl/48/1
|
| 117 |
+
Tri/30/1
|
| 118 |
+
Cre/35/2
|
| 119 |
+
Tri/103/1
|
| 120 |
+
Spl/59/1
|
| 121 |
+
Spl/84/2
|
| 122 |
+
Tri/5/2
|
| 123 |
+
Cre/151/2
|
| 124 |
+
Tri/1/1
|
| 125 |
+
Cre/65/1
|
| 126 |
+
Cre/117/1
|
| 127 |
+
Spl/10/1
|
| 128 |
+
Spl/117/2
|
| 129 |
+
Spl/101/2
|
| 130 |
+
Cre/152/2
|
| 131 |
+
Tri/140/1
|
| 132 |
+
Cre/62/2
|
| 133 |
+
Tri/133/1
|
| 134 |
+
Spl/133/2
|
| 135 |
+
Tri/19/2
|
| 136 |
+
Spl/45/2
|
| 137 |
+
Tri/109/1
|
| 138 |
+
Cre/44/2
|
| 139 |
+
Cre/126/1
|
| 140 |
+
Tri/134/1
|
| 141 |
+
Cre/23/1
|
| 142 |
+
Spl/150/2
|
| 143 |
+
Cre/88/2
|
| 144 |
+
Tri/147/1
|
| 145 |
+
Cre/58/1
|
| 146 |
+
Tri/37/2
|
| 147 |
+
Spl/150/1
|
| 148 |
+
Tri/159/2
|
| 149 |
+
Spl/96/2
|
| 150 |
+
Spl/66/1
|
| 151 |
+
Spl/158/2
|
| 152 |
+
Spl/122/1
|
| 153 |
+
Spl/35/2
|
| 154 |
+
Spl/126/1
|
| 155 |
+
Tri/157/1
|
| 156 |
+
Tri/18/1
|
| 157 |
+
Spl/58/1
|
| 158 |
+
Tri/52/1
|
| 159 |
+
Tri/73/1
|
| 160 |
+
Tri/151/2
|
| 161 |
+
Cre/53/1
|
| 162 |
+
Spl/35/1
|
| 163 |
+
Spl/28/1
|
| 164 |
+
Spl/118/2
|
| 165 |
+
Cre/119/1
|
| 166 |
+
Spl/4/1
|
| 167 |
+
Cre/57/2
|
| 168 |
+
Spl/81/2
|
| 169 |
+
Spl/139/1
|
| 170 |
+
Cre/46/1
|
| 171 |
+
Spl/12/2
|
| 172 |
+
Cre/131/2
|
| 173 |
+
Cre/55/1
|
| 174 |
+
Spl/60/1
|
| 175 |
+
Tri/9/2
|
| 176 |
+
Spl/36/2
|
| 177 |
+
Cre/71/1
|
| 178 |
+
Spl/32/2
|
| 179 |
+
Tri/81/1
|
| 180 |
+
Spl/100/2
|
| 181 |
+
Tri/122/2
|
| 182 |
+
Spl/33/2
|
| 183 |
+
Spl/37/1
|
| 184 |
+
Spl/91/2
|
| 185 |
+
Spl/27/2
|
| 186 |
+
Spl/156/1
|
| 187 |
+
Spl/47/1
|
| 188 |
+
Cre/6/2
|
| 189 |
+
Tri/46/1
|
| 190 |
+
Cre/54/2
|
| 191 |
+
Tri/137/1
|
| 192 |
+
Spl/114/2
|
| 193 |
+
Tri/78/2
|
| 194 |
+
Spl/23/2
|
| 195 |
+
Spl/84/1
|
| 196 |
+
Spl/101/1
|
| 197 |
+
Spl/40/1
|
| 198 |
+
Cre/29/2
|
| 199 |
+
Tri/65/1
|
| 200 |
+
Spl/60/2
|
| 201 |
+
Tri/142/1
|
| 202 |
+
Spl/154/1
|
| 203 |
+
Cre/40/1
|
| 204 |
+
Tri/38/2
|
| 205 |
+
Spl/87/1
|
| 206 |
+
Cre/14/1
|
| 207 |
+
Tri/95/1
|
| 208 |
+
Tri/118/1
|
| 209 |
+
Spl/81/1
|
| 210 |
+
Spl/152/1
|
| 211 |
+
Tri/61/2
|
| 212 |
+
Tri/129/2
|
| 213 |
+
Cre/119/2
|
| 214 |
+
Cre/142/2
|
| 215 |
+
Tri/96/1
|
| 216 |
+
Cre/47/1
|
| 217 |
+
Spl/86/2
|
| 218 |
+
Spl/147/2
|
| 219 |
+
Tri/26/1
|
| 220 |
+
Tri/49/1
|
| 221 |
+
Cre/91/2
|
| 222 |
+
Cre/45/1
|
| 223 |
+
Spl/156/2
|
| 224 |
+
Tri/19/1
|
| 225 |
+
Cre/59/1
|
| 226 |
+
Cre/146/1
|
| 227 |
+
Spl/25/2
|
| 228 |
+
Cre/110/2
|
| 229 |
+
Spl/127/2
|
| 230 |
+
Tri/136/1
|
| 231 |
+
Cre/4/1
|
| 232 |
+
Tri/148/1
|
| 233 |
+
Cre/48/1
|
| 234 |
+
Spl/2/2
|
| 235 |
+
Spl/14/2
|
| 236 |
+
Spl/99/2
|
| 237 |
+
Tri/22/2
|
| 238 |
+
Cre/116/1
|
| 239 |
+
Tri/114/1
|
| 240 |
+
Cre/94/2
|
| 241 |
+
Spl/109/1
|
| 242 |
+
Cre/85/1
|
| 243 |
+
Cre/27/1
|
| 244 |
+
Tri/97/1
|
| 245 |
+
Tri/77/2
|
| 246 |
+
Cre/132/2
|
| 247 |
+
Cre/137/1
|
| 248 |
+
Cre/77/1
|
| 249 |
+
Tri/144/1
|
| 250 |
+
Tri/127/1
|
| 251 |
+
Spl/135/1
|
| 252 |
+
Cre/3/2
|
| 253 |
+
Spl/96/1
|
| 254 |
+
Cre/90/1
|
| 255 |
+
Cre/89/1
|
| 256 |
+
Tri/88/1
|
| 257 |
+
Tri/92/2
|
| 258 |
+
Tri/37/1
|
| 259 |
+
Tri/125/2
|
| 260 |
+
Tri/86/2
|
| 261 |
+
Spl/46/1
|
| 262 |
+
Cre/65/2
|
| 263 |
+
Cre/84/1
|
| 264 |
+
Spl/134/1
|
| 265 |
+
Cre/137/2
|
| 266 |
+
Tri/17/2
|
| 267 |
+
Spl/133/1
|
| 268 |
+
Spl/11/2
|
| 269 |
+
Tri/155/1
|
| 270 |
+
Tri/57/1
|
| 271 |
+
Cre/140/1
|
| 272 |
+
Cre/26/1
|
| 273 |
+
Spl/113/2
|
| 274 |
+
Spl/63/2
|
| 275 |
+
Spl/105/1
|
| 276 |
+
Tri/51/2
|
| 277 |
+
Tri/88/2
|
| 278 |
+
Tri/36/2
|
| 279 |
+
Tri/80/2
|
| 280 |
+
Tri/92/1
|
| 281 |
+
Cre/79/1
|
| 282 |
+
Tri/28/1
|
| 283 |
+
Spl/56/2
|
| 284 |
+
Tri/59/2
|
| 285 |
+
Tri/98/1
|
| 286 |
+
Spl/6/2
|
| 287 |
+
Tri/120/1
|
| 288 |
+
Spl/75/1
|
| 289 |
+
Cre/147/1
|
| 290 |
+
Tri/27/2
|
| 291 |
+
Tri/71/1
|
| 292 |
+
Spl/33/1
|
| 293 |
+
Tri/27/1
|
| 294 |
+
Spl/77/2
|
| 295 |
+
Tri/48/2
|
| 296 |
+
Spl/15/2
|
| 297 |
+
Spl/89/1
|
| 298 |
+
Spl/140/1
|
| 299 |
+
Cre/117/2
|
| 300 |
+
Spl/148/1
|
| 301 |
+
Tri/43/2
|
| 302 |
+
Spl/119/1
|
| 303 |
+
Cre/101/1
|
| 304 |
+
Spl/152/2
|
| 305 |
+
Cre/49/1
|
| 306 |
+
Tri/39/1
|
| 307 |
+
Spl/157/1
|
| 308 |
+
Spl/11/1
|
| 309 |
+
Tri/32/2
|
| 310 |
+
Spl/21/1
|
| 311 |
+
Cre/76/2
|
| 312 |
+
Spl/72/1
|
| 313 |
+
Cre/87/1
|
| 314 |
+
Cre/158/1
|
| 315 |
+
Cre/120/2
|
| 316 |
+
Tri/66/1
|
| 317 |
+
Cre/16/1
|
| 318 |
+
Cre/29/1
|
| 319 |
+
Spl/3/1
|
| 320 |
+
Tri/23/1
|
| 321 |
+
Cre/50/2
|
| 322 |
+
Cre/89/2
|
| 323 |
+
Tri/144/2
|
| 324 |
+
Tri/76/1
|
| 325 |
+
Spl/95/1
|
| 326 |
+
Tri/136/2
|
| 327 |
+
Tri/104/2
|
| 328 |
+
Cre/159/1
|
| 329 |
+
Tri/36/1
|
| 330 |
+
Spl/77/1
|
| 331 |
+
Spl/61/2
|
| 332 |
+
Tri/94/2
|
| 333 |
+
Spl/88/2
|
| 334 |
+
Tri/158/1
|
| 335 |
+
Cre/13/1
|
| 336 |
+
Tri/79/1
|
| 337 |
+
Cre/99/2
|
| 338 |
+
Cre/120/1
|
| 339 |
+
Cre/157/2
|
| 340 |
+
Spl/79/2
|
| 341 |
+
Tri/138/1
|
| 342 |
+
Cre/91/1
|
| 343 |
+
Tri/76/2
|
| 344 |
+
Tri/13/1
|
| 345 |
+
Tri/138/2
|
| 346 |
+
Tri/58/1
|
| 347 |
+
Cre/126/2
|
| 348 |
+
Tri/116/2
|
| 349 |
+
Tri/112/2
|
| 350 |
+
Tri/105/2
|
| 351 |
+
Tri/60/1
|
| 352 |
+
Cre/15/1
|
| 353 |
+
Cre/86/2
|
| 354 |
+
Cre/74/1
|
| 355 |
+
Spl/63/1
|
| 356 |
+
Spl/18/2
|
| 357 |
+
Tri/83/1
|
| 358 |
+
Tri/145/2
|
| 359 |
+
Cre/16/2
|
| 360 |
+
Spl/67/1
|
| 361 |
+
Spl/13/2
|
| 362 |
+
Spl/83/1
|
| 363 |
+
Cre/78/2
|
| 364 |
+
Cre/68/1
|
| 365 |
+
Cre/127/1
|
| 366 |
+
Tri/61/1
|
| 367 |
+
Tri/106/1
|
| 368 |
+
Cre/66/1
|
| 369 |
+
Cre/146/2
|
| 370 |
+
Cre/130/2
|
| 371 |
+
Tri/129/1
|
| 372 |
+
Spl/62/1
|
| 373 |
+
Spl/125/2
|
| 374 |
+
Tri/115/1
|
| 375 |
+
Cre/6/1
|
| 376 |
+
Spl/75/2
|
| 377 |
+
Tri/120/2
|
| 378 |
+
Cre/156/2
|
| 379 |
+
Cre/100/1
|
| 380 |
+
Cre/124/1
|
| 381 |
+
Cre/107/2
|
| 382 |
+
Spl/68/1
|
| 383 |
+
Cre/138/1
|
| 384 |
+
Cre/75/1
|
| 385 |
+
Cre/53/2
|
| 386 |
+
Tri/34/1
|
| 387 |
+
Tri/152/2
|
| 388 |
+
Tri/90/2
|
| 389 |
+
Tri/160/2
|
| 390 |
+
Cre/154/2
|
| 391 |
+
Tri/115/2
|
| 392 |
+
Spl/86/1
|
| 393 |
+
Spl/10/2
|
| 394 |
+
Spl/24/1
|
| 395 |
+
Cre/147/2
|
| 396 |
+
Cre/9/2
|
| 397 |
+
Cre/129/2
|
| 398 |
+
Cre/136/2
|
| 399 |
+
Spl/1/2
|
| 400 |
+
Cre/130/1
|
| 401 |
+
Cre/96/1
|
| 402 |
+
Cre/118/2
|
| 403 |
+
Tri/8/2
|
| 404 |
+
Cre/39/1
|
| 405 |
+
Spl/15/1
|
| 406 |
+
Spl/65/1
|
| 407 |
+
Cre/115/2
|
| 408 |
+
Tri/35/1
|
| 409 |
+
Cre/4/2
|
| 410 |
+
Spl/134/2
|
| 411 |
+
Spl/31/2
|
| 412 |
+
Cre/34/1
|
| 413 |
+
Cre/58/2
|
| 414 |
+
Tri/77/1
|
| 415 |
+
Cre/11/1
|
| 416 |
+
Cre/133/1
|
| 417 |
+
Tri/135/1
|
| 418 |
+
Tri/45/2
|
| 419 |
+
Spl/99/1
|
| 420 |
+
Cre/121/1
|
| 421 |
+
Tri/47/2
|
| 422 |
+
Tri/62/2
|
| 423 |
+
Spl/19/2
|
| 424 |
+
Spl/143/2
|
| 425 |
+
Tri/130/2
|
| 426 |
+
Spl/78/1
|
| 427 |
+
Tri/56/2
|
| 428 |
+
Cre/40/2
|
| 429 |
+
Tri/41/2
|
| 430 |
+
Spl/49/2
|
| 431 |
+
Tri/84/1
|
| 432 |
+
Tri/74/2
|
| 433 |
+
Cre/10/1
|
| 434 |
+
Cre/83/1
|
| 435 |
+
Tri/50/1
|
| 436 |
+
Spl/40/2
|
| 437 |
+
Tri/32/1
|
| 438 |
+
Tri/21/2
|
| 439 |
+
Spl/73/2
|
| 440 |
+
Cre/3/1
|
| 441 |
+
Cre/57/1
|
| 442 |
+
Cre/157/1
|
| 443 |
+
Tri/128/2
|
| 444 |
+
Tri/110/1
|
| 445 |
+
Tri/64/2
|
| 446 |
+
Tri/107/1
|
| 447 |
+
Tri/3/2
|
| 448 |
+
Spl/79/1
|
| 449 |
+
Cre/128/2
|
| 450 |
+
Tri/54/1
|
| 451 |
+
Spl/37/2
|
| 452 |
+
Tri/68/1
|
| 453 |
+
Tri/14/2
|
| 454 |
+
Cre/127/2
|
| 455 |
+
Spl/43/1
|
| 456 |
+
Tri/65/2
|
| 457 |
+
Cre/109/1
|
| 458 |
+
Tri/15/1
|
| 459 |
+
Tri/4/1
|
| 460 |
+
Cre/104/2
|
| 461 |
+
Spl/149/2
|
| 462 |
+
Spl/66/2
|
| 463 |
+
Spl/122/2
|
| 464 |
+
Cre/153/2
|
| 465 |
+
Spl/18/1
|
| 466 |
+
Cre/39/2
|
| 467 |
+
Tri/52/2
|
| 468 |
+
Cre/140/2
|
| 469 |
+
Cre/93/2
|
| 470 |
+
Spl/64/2
|
| 471 |
+
Cre/118/1
|
| 472 |
+
Tri/113/1
|
| 473 |
+
Cre/27/2
|
| 474 |
+
Cre/38/1
|
| 475 |
+
Tri/159/1
|
| 476 |
+
Cre/56/1
|
| 477 |
+
Spl/128/1
|
| 478 |
+
Cre/11/2
|
| 479 |
+
Tri/5/1
|
| 480 |
+
Cre/54/1
|
| 481 |
+
Cre/66/2
|
| 482 |
+
Spl/148/2
|
| 483 |
+
Cre/128/1
|
| 484 |
+
Cre/31/1
|
| 485 |
+
Spl/45/1
|
| 486 |
+
Tri/33/2
|
| 487 |
+
Cre/116/2
|
| 488 |
+
Tri/72/1
|
| 489 |
+
Tri/152/1
|
| 490 |
+
Tri/20/2
|
| 491 |
+
Tri/117/1
|
| 492 |
+
Tri/62/1
|
| 493 |
+
Tri/51/1
|
| 494 |
+
Spl/135/2
|
| 495 |
+
Cre/30/1
|
| 496 |
+
Spl/117/1
|
| 497 |
+
Cre/50/1
|
| 498 |
+
Spl/88/1
|
| 499 |
+
Tri/97/2
|
| 500 |
+
Spl/16/2
|
| 501 |
+
Cre/150/2
|
| 502 |
+
Tri/155/2
|
| 503 |
+
Spl/159/2
|
| 504 |
+
Spl/74/2
|
| 505 |
+
Tri/29/2
|
| 506 |
+
Tri/156/1
|
| 507 |
+
Tri/57/2
|
| 508 |
+
Cre/112/1
|
| 509 |
+
Tri/91/1
|
| 510 |
+
Tri/70/2
|
| 511 |
+
Spl/112/1
|
| 512 |
+
Tri/42/2
|
| 513 |
+
Tri/150/2
|
| 514 |
+
Cre/5/1
|
| 515 |
+
Spl/127/1
|
| 516 |
+
Spl/47/2
|
| 517 |
+
Spl/51/1
|
| 518 |
+
Cre/102/1
|
| 519 |
+
Cre/44/1
|
| 520 |
+
Cre/34/2
|
| 521 |
+
Cre/45/2
|
| 522 |
+
Tri/131/1
|
| 523 |
+
Cre/86/1
|
| 524 |
+
Cre/80/2
|
| 525 |
+
Spl/24/2
|
| 526 |
+
Spl/41/2
|
| 527 |
+
Cre/20/1
|
| 528 |
+
Spl/72/2
|
| 529 |
+
Tri/95/2
|
| 530 |
+
Tri/143/2
|
| 531 |
+
Spl/57/1
|
| 532 |
+
Spl/65/2
|
| 533 |
+
Tri/16/2
|
| 534 |
+
Spl/138/2
|
| 535 |
+
Tri/83/2
|
| 536 |
+
Tri/87/1
|
| 537 |
+
Spl/144/1
|
| 538 |
+
Spl/160/2
|
| 539 |
+
Spl/83/2
|
| 540 |
+
Cre/154/1
|
| 541 |
+
Tri/9/1
|
| 542 |
+
Tri/47/1
|
| 543 |
+
Tri/148/2
|
| 544 |
+
Cre/37/1
|
| 545 |
+
Tri/108/2
|
| 546 |
+
Cre/92/2
|
| 547 |
+
Cre/158/2
|
| 548 |
+
Cre/25/2
|
| 549 |
+
Spl/50/1
|
| 550 |
+
Tri/85/2
|
| 551 |
+
Tri/141/1
|
| 552 |
+
Cre/151/1
|
| 553 |
+
Cre/67/1
|
| 554 |
+
Tri/156/2
|
| 555 |
+
Tri/43/1
|
| 556 |
+
Tri/25/2
|
| 557 |
+
Cre/149/1
|
| 558 |
+
Spl/94/1
|
| 559 |
+
Cre/84/2
|
| 560 |
+
Cre/139/1
|
| 561 |
+
Cre/22/1
|
| 562 |
+
Tri/14/1
|
| 563 |
+
Spl/129/2
|
| 564 |
+
Tri/29/1
|
| 565 |
+
Tri/13/2
|
| 566 |
+
Spl/123/1
|
| 567 |
+
Spl/76/1
|
| 568 |
+
Cre/78/1
|
| 569 |
+
Cre/71/2
|
| 570 |
+
Cre/5/2
|
| 571 |
+
Tri/33/1
|
| 572 |
+
Cre/107/1
|
| 573 |
+
Cre/92/1
|
| 574 |
+
Tri/116/1
|
| 575 |
+
Tri/31/2
|
| 576 |
+
Tri/63/2
|
| 577 |
+
Tri/75/2
|
| 578 |
+
Tri/160/1
|
| 579 |
+
Tri/139/1
|
| 580 |
+
Spl/7/2
|
| 581 |
+
Tri/28/2
|
| 582 |
+
Tri/2/1
|
| 583 |
+
Spl/4/2
|
| 584 |
+
Spl/158/1
|
| 585 |
+
Cre/22/2
|
| 586 |
+
Cre/10/2
|
| 587 |
+
Cre/143/2
|
| 588 |
+
Cre/80/1
|
| 589 |
+
Cre/59/2
|
| 590 |
+
Tri/18/2
|
| 591 |
+
Spl/132/2
|
| 592 |
+
Cre/69/1
|
| 593 |
+
Cre/132/1
|
| 594 |
+
Spl/61/1
|
| 595 |
+
Tri/72/2
|
| 596 |
+
Spl/85/2
|
| 597 |
+
Spl/59/2
|
| 598 |
+
Cre/42/2
|
| 599 |
+
Tri/44/1
|
| 600 |
+
Spl/97/1
|
| 601 |
+
Cre/52/1
|
| 602 |
+
Cre/94/1
|
| 603 |
+
Cre/144/1
|
| 604 |
+
Cre/155/2
|
| 605 |
+
Cre/102/2
|
| 606 |
+
Cre/61/2
|
| 607 |
+
Spl/120/1
|
| 608 |
+
Cre/51/1
|
| 609 |
+
Tri/111/2
|
| 610 |
+
Cre/2/1
|
| 611 |
+
Spl/130/1
|
| 612 |
+
Cre/110/1
|
| 613 |
+
Cre/2/2
|
| 614 |
+
Spl/159/1
|
| 615 |
+
Tri/54/2
|
| 616 |
+
Spl/8/1
|
| 617 |
+
Cre/8/2
|
| 618 |
+
Spl/94/2
|
| 619 |
+
Cre/43/2
|
| 620 |
+
Spl/130/2
|
| 621 |
+
Cre/97/1
|
| 622 |
+
Tri/53/2
|
| 623 |
+
Cre/26/2
|
| 624 |
+
Spl/46/2
|
| 625 |
+
Cre/160/2
|
| 626 |
+
Spl/121/2
|
| 627 |
+
Tri/94/1
|
| 628 |
+
Spl/93/2
|
| 629 |
+
Cre/1/1
|
| 630 |
+
Tri/150/1
|
| 631 |
+
Spl/26/2
|
| 632 |
+
Spl/80/1
|
| 633 |
+
Tri/111/1
|
| 634 |
+
Tri/69/2
|
| 635 |
+
Cre/81/2
|
| 636 |
+
Spl/157/2
|
| 637 |
+
Cre/33/2
|
| 638 |
+
Tri/69/1
|
| 639 |
+
Cre/85/2
|
| 640 |
+
Cre/24/2
|
| 641 |
+
Tri/55/1
|
| 642 |
+
Spl/9/2
|
| 643 |
+
Tri/46/2
|
| 644 |
+
Cre/17/1
|
| 645 |
+
Spl/16/1
|
| 646 |
+
Spl/119/2
|
| 647 |
+
Tri/34/2
|
| 648 |
+
Spl/140/2
|
| 649 |
+
Spl/7/1
|
| 650 |
+
Cre/115/1
|
| 651 |
+
Spl/22/1
|
| 652 |
+
Cre/82/2
|
| 653 |
+
Tri/12/1
|
| 654 |
+
Cre/99/1
|
| 655 |
+
Tri/145/1
|
| 656 |
+
Spl/125/1
|
| 657 |
+
Spl/131/1
|
| 658 |
+
Spl/14/1
|
| 659 |
+
Tri/53/1
|
| 660 |
+
Spl/55/1
|
| 661 |
+
Spl/143/1
|
| 662 |
+
Cre/68/2
|
| 663 |
+
Spl/56/1
|
| 664 |
+
Spl/5/1
|
| 665 |
+
Tri/143/1
|
| 666 |
+
Spl/128/2
|
| 667 |
+
Spl/154/2
|
| 668 |
+
Tri/153/1
|
| 669 |
+
Tri/21/1
|
| 670 |
+
Tri/87/2
|
| 671 |
+
Cre/123/2
|
| 672 |
+
Cre/70/1
|
| 673 |
+
Cre/144/2
|
| 674 |
+
Spl/54/1
|
| 675 |
+
Spl/69/2
|
| 676 |
+
Spl/78/2
|
| 677 |
+
Cre/41/1
|
| 678 |
+
Tri/75/1
|
| 679 |
+
Cre/7/1
|
| 680 |
+
Tri/128/1
|
| 681 |
+
Cre/79/2
|
| 682 |
+
Spl/36/1
|
| 683 |
+
Spl/17/2
|
| 684 |
+
Tri/39/2
|
| 685 |
+
Spl/126/2
|
| 686 |
+
Spl/13/1
|
| 687 |
+
Cre/160/1
|
| 688 |
+
Spl/114/1
|
| 689 |
+
Tri/132/1
|
| 690 |
+
Tri/50/2
|
| 691 |
+
Spl/29/2
|
| 692 |
+
Tri/82/1
|
| 693 |
+
Cre/7/2
|
| 694 |
+
Cre/90/2
|
| 695 |
+
Spl/21/2
|
| 696 |
+
Tri/67/1
|
| 697 |
+
Tri/146/2
|
| 698 |
+
Cre/61/1
|
| 699 |
+
Spl/146/2
|
| 700 |
+
Tri/112/1
|
| 701 |
+
Tri/16/1
|
| 702 |
+
Cre/83/2
|
| 703 |
+
Cre/82/1
|
| 704 |
+
Spl/27/1
|
| 705 |
+
Cre/30/2
|
| 706 |
+
Spl/108/1
|
| 707 |
+
Spl/25/1
|
| 708 |
+
Spl/70/2
|
| 709 |
+
Cre/87/2
|
| 710 |
+
Tri/132/2
|
| 711 |
+
Tri/81/2
|
| 712 |
+
Tri/24/2
|
| 713 |
+
Spl/52/1
|
| 714 |
+
Cre/103/1
|
| 715 |
+
Spl/62/2
|
| 716 |
+
Spl/92/2
|
| 717 |
+
Spl/52/2
|
| 718 |
+
Spl/104/1
|
| 719 |
+
Cre/21/1
|
| 720 |
+
Tri/80/1
|
| 721 |
+
Tri/98/2
|
| 722 |
+
Spl/76/2
|
| 723 |
+
Cre/93/1
|
| 724 |
+
Tri/64/1
|
| 725 |
+
Tri/20/1
|
| 726 |
+
Spl/112/2
|
| 727 |
+
Spl/12/1
|
| 728 |
+
Cre/37/2
|
| 729 |
+
Cre/114/1
|
| 730 |
+
Cre/36/2
|
| 731 |
+
Spl/97/2
|
| 732 |
+
Spl/71/2
|
| 733 |
+
Tri/158/2
|
| 734 |
+
Tri/58/2
|
| 735 |
+
Tri/119/2
|
| 736 |
+
Cre/12/2
|
| 737 |
+
Spl/87/2
|
| 738 |
+
Cre/32/1
|
| 739 |
+
Spl/53/1
|
| 740 |
+
Cre/108/2
|
| 741 |
+
Tri/86/1
|
| 742 |
+
Cre/64/1
|
| 743 |
+
Spl/48/2
|
| 744 |
+
Cre/95/2
|
| 745 |
+
Cre/100/2
|
| 746 |
+
Cre/12/1
|
| 747 |
+
Spl/64/1
|
| 748 |
+
Spl/80/2
|
| 749 |
+
Tri/30/2
|
| 750 |
+
Spl/123/2
|
| 751 |
+
Spl/91/1
|
| 752 |
+
Cre/62/1
|
| 753 |
+
Spl/102/1
|
| 754 |
+
Tri/151/1
|
| 755 |
+
Spl/100/1
|
| 756 |
+
Spl/6/1
|
| 757 |
+
Spl/110/2
|
| 758 |
+
Cre/14/2
|
| 759 |
+
Spl/141/2
|
| 760 |
+
Spl/29/1
|
| 761 |
+
Spl/144/2
|
| 762 |
+
Tri/114/2
|
| 763 |
+
Spl/5/2
|
| 764 |
+
Tri/134/2
|
| 765 |
+
Cre/24/1
|
| 766 |
+
Cre/113/1
|
| 767 |
+
Spl/38/1
|
| 768 |
+
Cre/75/2
|
| 769 |
+
Spl/138/1
|
| 770 |
+
Spl/131/2
|
| 771 |
+
Tri/59/1
|
| 772 |
+
Spl/109/2
|
| 773 |
+
Cre/88/1
|
| 774 |
+
Tri/31/1
|
| 775 |
+
Cre/113/2
|
| 776 |
+
Spl/90/2
|
| 777 |
+
Cre/60/2
|
| 778 |
+
Cre/139/2
|
| 779 |
+
Spl/55/2
|
| 780 |
+
Cre/9/1
|
| 781 |
+
Cre/125/1
|
| 782 |
+
Cre/98/1
|
| 783 |
+
Tri/12/2
|
| 784 |
+
Spl/3/2
|
| 785 |
+
Spl/106/1
|
| 786 |
+
Tri/90/1
|
| 787 |
+
Cre/60/1
|
| 788 |
+
Spl/98/2
|
| 789 |
+
Tri/7/1
|
| 790 |
+
Cre/43/1
|
| 791 |
+
Tri/23/2
|
| 792 |
+
Spl/39/2
|
| 793 |
+
Spl/9/1
|
| 794 |
+
Spl/19/1
|
| 795 |
+
Tri/93/1
|
| 796 |
+
Tri/71/2
|
| 797 |
+
Cre/141/2
|
| 798 |
+
Tri/137/2
|
| 799 |
+
Tri/55/2
|
| 800 |
+
Tri/142/2
|
| 801 |
+
Spl/145/1
|
| 802 |
+
Cre/111/1
|
| 803 |
+
Cre/121/2
|
| 804 |
+
Tri/108/1
|
| 805 |
+
Cre/142/1
|
| 806 |
+
Tri/109/2
|
| 807 |
+
Spl/151/2
|
| 808 |
+
Tri/41/1
|
| 809 |
+
Spl/30/2
|
| 810 |
+
Spl/108/2
|
| 811 |
+
Spl/39/1
|
| 812 |
+
Spl/115/1
|
| 813 |
+
Cre/20/2
|
| 814 |
+
Cre/77/2
|
| 815 |
+
Cre/67/2
|
| 816 |
+
Spl/68/2
|
| 817 |
+
Spl/28/2
|
| 818 |
+
Cre/46/2
|
| 819 |
+
Cre/36/1
|
| 820 |
+
Tri/84/2
|
| 821 |
+
Spl/132/1
|
| 822 |
+
Spl/17/1
|
| 823 |
+
Tri/154/2
|
| 824 |
+
Cre/17/2
|
| 825 |
+
Cre/96/2
|
| 826 |
+
Cre/97/2
|
| 827 |
+
Cre/95/1
|
| 828 |
+
Cre/149/2
|
| 829 |
+
Cre/124/2
|
| 830 |
+
Tri/135/2
|
| 831 |
+
Tri/3/1
|
| 832 |
+
Spl/160/1
|
| 833 |
+
Spl/89/2
|
| 834 |
+
Tri/146/1
|
| 835 |
+
Spl/115/2
|
| 836 |
+
Tri/68/2
|
| 837 |
+
Cre/148/1
|
| 838 |
+
Tri/141/2
|
| 839 |
+
Spl/110/1
|
| 840 |
+
Tri/149/2
|
| 841 |
+
Spl/147/1
|
| 842 |
+
Tri/117/2
|
| 843 |
+
Spl/98/1
|
| 844 |
+
Tri/11/1
|
| 845 |
+
Tri/121/1
|
| 846 |
+
Cre/64/2
|
| 847 |
+
Spl/42/2
|
| 848 |
+
Cre/150/1
|
| 849 |
+
Tri/123/1
|
| 850 |
+
Cre/155/1
|
| 851 |
+
Cre/56/2
|
| 852 |
+
Tri/91/2
|
| 853 |
+
Tri/101/1
|
| 854 |
+
Tri/4/2
|
| 855 |
+
Cre/42/1
|
| 856 |
+
Cre/47/2
|
| 857 |
+
Tri/70/1
|
| 858 |
+
Tri/119/1
|
| 859 |
+
Spl/118/1
|
| 860 |
+
Cre/73/2
|
| 861 |
+
Spl/92/1
|
| 862 |
+
Cre/123/1
|
| 863 |
+
Cre/114/2
|
| 864 |
+
Tri/131/2
|
| 865 |
+
Cre/98/2
|
| 866 |
+
Cre/33/1
|
| 867 |
+
Spl/41/1
|
| 868 |
+
Tri/7/2
|
| 869 |
+
Spl/142/1
|
| 870 |
+
Cre/125/2
|
| 871 |
+
Tri/11/2
|
| 872 |
+
Spl/104/2
|
| 873 |
+
Tri/93/2
|
| 874 |
+
Tri/154/1
|
| 875 |
+
Cre/1/2
|
| 876 |
+
Spl/1/1
|
| 877 |
+
Spl/23/1
|
| 878 |
+
Spl/82/2
|
| 879 |
+
Spl/103/1
|
| 880 |
+
Spl/44/2
|
| 881 |
+
Tri/45/1
|
| 882 |
+
Spl/49/1
|
| 883 |
+
Cre/48/2
|
| 884 |
+
Cre/8/1
|
| 885 |
+
Tri/121/2
|
| 886 |
+
Spl/93/1
|
| 887 |
+
Cre/32/2
|
| 888 |
+
Cre/134/1
|
| 889 |
+
Tri/107/2
|
| 890 |
+
Spl/124/1
|
| 891 |
+
Tri/67/2
|
| 892 |
+
Spl/153/2
|
| 893 |
+
Tri/123/2
|
| 894 |
+
Spl/8/2
|
| 895 |
+
Tri/153/2
|
| 896 |
+
Tri/2/2
|
| 897 |
+
Tri/63/1
|
| 898 |
+
Tri/22/1
|
| 899 |
+
Cre/52/2
|
| 900 |
+
Tri/127/2
|
| 901 |
+
Tri/82/2
|
| 902 |
+
Tri/10/1
|
| 903 |
+
Spl/31/1
|
| 904 |
+
Spl/116/1
|
| 905 |
+
Spl/141/1
|
| 906 |
+
Cre/38/2
|
| 907 |
+
Spl/54/2
|
| 908 |
+
Cre/51/2
|
| 909 |
+
Cre/159/2
|
| 910 |
+
Cre/76/1
|
| 911 |
+
Spl/142/2
|
| 912 |
+
Tri/149/1
|
| 913 |
+
Spl/95/2
|
| 914 |
+
Spl/42/1
|
| 915 |
+
Tri/113/2
|
| 916 |
+
Cre/129/1
|
| 917 |
+
Spl/90/1
|
| 918 |
+
Tri/157/2
|
| 919 |
+
Cre/49/2
|
| 920 |
+
Spl/67/2
|
| 921 |
+
Cre/72/2
|
| 922 |
+
Cre/145/1
|
| 923 |
+
Cre/72/1
|
| 924 |
+
Tri/99/1
|
| 925 |
+
Cre/112/2
|
| 926 |
+
Spl/145/2
|
| 927 |
+
Spl/137/2
|
| 928 |
+
Tri/139/2
|
| 929 |
+
Tri/24/1
|
| 930 |
+
Tri/85/1
|
| 931 |
+
Cre/156/1
|
| 932 |
+
Spl/105/2
|
| 933 |
+
Spl/82/1
|
| 934 |
+
Spl/151/1
|
| 935 |
+
Tri/48/1
|
| 936 |
+
Tri/89/2
|
| 937 |
+
Tri/102/2
|
| 938 |
+
Cre/133/2
|
| 939 |
+
Cre/21/2
|
| 940 |
+
Tri/56/1
|
| 941 |
+
Spl/136/2
|
| 942 |
+
Spl/69/1
|
| 943 |
+
Tri/38/1
|
| 944 |
+
Spl/113/1
|
| 945 |
+
Tri/89/1
|
| 946 |
+
Cre/105/1
|
| 947 |
+
Cre/105/2
|
data/splits/valid.txt
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Spl/178/1
|
| 2 |
+
Cre/167/1
|
| 3 |
+
Tri/177/1
|
| 4 |
+
Spl/172/1
|
| 5 |
+
Tri/173/1
|
| 6 |
+
Cre/165/2
|
| 7 |
+
Spl/177/1
|
| 8 |
+
Cre/177/1
|
| 9 |
+
Tri/175/1
|
| 10 |
+
Spl/171/1
|
| 11 |
+
Tri/175/2
|
| 12 |
+
Cre/171/1
|
| 13 |
+
Cre/168/2
|
| 14 |
+
Cre/163/2
|
| 15 |
+
Spl/161/2
|
| 16 |
+
Cre/161/2
|
| 17 |
+
Tri/166/1
|
| 18 |
+
Spl/172/2
|
| 19 |
+
Tri/174/1
|
| 20 |
+
Tri/171/2
|
| 21 |
+
Tri/165/1
|
| 22 |
+
Tri/180/1
|
| 23 |
+
Tri/178/1
|
| 24 |
+
Spl/163/1
|
| 25 |
+
Tri/162/2
|
| 26 |
+
Cre/178/1
|
| 27 |
+
Tri/172/2
|
| 28 |
+
Cre/170/2
|
| 29 |
+
Spl/170/1
|
| 30 |
+
Tri/180/2
|
| 31 |
+
Tri/166/2
|
| 32 |
+
Tri/170/2
|
| 33 |
+
Spl/162/2
|
| 34 |
+
Cre/168/1
|
| 35 |
+
Spl/171/2
|
| 36 |
+
Tri/179/2
|
| 37 |
+
Cre/165/1
|
| 38 |
+
Cre/180/2
|
| 39 |
+
Spl/180/1
|
| 40 |
+
Cre/161/1
|
| 41 |
+
Tri/176/2
|
| 42 |
+
Spl/161/1
|
| 43 |
+
Spl/164/1
|
| 44 |
+
Tri/171/1
|
| 45 |
+
Cre/162/1
|
| 46 |
+
Cre/169/2
|
| 47 |
+
Spl/173/2
|
| 48 |
+
Spl/176/2
|
| 49 |
+
Cre/176/1
|
| 50 |
+
Spl/168/2
|
| 51 |
+
Spl/180/2
|
| 52 |
+
Cre/176/2
|
| 53 |
+
Tri/176/1
|
| 54 |
+
Cre/179/2
|
| 55 |
+
Cre/174/2
|
| 56 |
+
Tri/164/2
|
| 57 |
+
Cre/178/2
|
| 58 |
+
Tri/161/2
|
| 59 |
+
Spl/173/1
|
| 60 |
+
Cre/177/2
|
| 61 |
+
Spl/165/2
|
| 62 |
+
Spl/168/1
|
| 63 |
+
Cre/162/2
|
| 64 |
+
Spl/175/2
|
| 65 |
+
Tri/167/1
|
| 66 |
+
Tri/163/2
|
| 67 |
+
Spl/177/2
|
| 68 |
+
Tri/173/2
|
| 69 |
+
Cre/166/2
|
| 70 |
+
Cre/180/1
|
| 71 |
+
Tri/179/1
|
| 72 |
+
Cre/164/2
|
| 73 |
+
Tri/164/1
|
| 74 |
+
Spl/175/1
|
| 75 |
+
Cre/166/1
|
| 76 |
+
Spl/179/2
|
| 77 |
+
Cre/163/1
|
| 78 |
+
Spl/163/2
|
| 79 |
+
Cre/164/1
|
| 80 |
+
Tri/178/2
|
| 81 |
+
Spl/167/1
|
| 82 |
+
Spl/169/2
|
| 83 |
+
Cre/173/2
|
| 84 |
+
Cre/175/1
|
| 85 |
+
Spl/165/1
|
| 86 |
+
Tri/172/1
|
| 87 |
+
Tri/168/1
|
| 88 |
+
Spl/174/1
|
| 89 |
+
Tri/163/1
|
| 90 |
+
Tri/169/1
|
| 91 |
+
Cre/174/1
|
| 92 |
+
Cre/169/1
|
| 93 |
+
Tri/161/1
|
| 94 |
+
Tri/174/2
|
| 95 |
+
Spl/170/2
|
| 96 |
+
Spl/166/1
|
| 97 |
+
Tri/169/2
|
| 98 |
+
Spl/179/1
|
| 99 |
+
Spl/176/1
|
| 100 |
+
Spl/164/2
|
| 101 |
+
Spl/162/1
|
| 102 |
+
Tri/167/2
|
| 103 |
+
Spl/174/2
|
| 104 |
+
Cre/171/2
|
| 105 |
+
Tri/165/2
|
| 106 |
+
Tri/162/1
|
| 107 |
+
Spl/166/2
|
| 108 |
+
Tri/170/1
|
| 109 |
+
Tri/168/2
|
| 110 |
+
Cre/167/2
|
| 111 |
+
Cre/173/1
|
| 112 |
+
Cre/179/1
|
| 113 |
+
Tri/177/2
|
| 114 |
+
Spl/169/1
|
| 115 |
+
Cre/170/1
|
| 116 |
+
Cre/175/2
|
| 117 |
+
Spl/178/2
|
| 118 |
+
Spl/167/2
|
model/graphViT.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torch.nn as nn
|
| 3 |
+
|
| 4 |
+
from onescience.modules.decoder.graphvit_decoder import GraphViTDecoder
|
| 5 |
+
from onescience.modules.embedding.fourier_pos_embedding import FourierPosEmbedding
|
| 6 |
+
from onescience.modules.encoder.graphvit_encoder import GraphViTEncoder
|
| 7 |
+
from onescience.modules.pooling.rnn_cluster_pooling import RNNClusterPooling
|
| 8 |
+
from onescience.modules.transformer.preln_transformer_block import (
|
| 9 |
+
PreLNTransformerBlock,
|
| 10 |
+
)
|
| 11 |
+
|
| 12 |
+
# 节点类型常量
|
| 13 |
+
NODE_NORMAL = 0
|
| 14 |
+
NODE_INPUT = 4
|
| 15 |
+
NODE_OUTPUT = 5
|
| 16 |
+
NODE_WALL = 6
|
| 17 |
+
NODE_DISABLE = 2
|
| 18 |
+
|
| 19 |
+
class GraphViT(nn.Module):
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
该模型利用图神经网络提取局部特征,通过聚类池化在潜在空间进行全局 Transformer 交互,
|
| 23 |
+
最后解码回物理空间进行下一时刻的状态预测。
|
| 24 |
+
|
| 25 |
+
Args:
|
| 26 |
+
state_size (int): 物理状态的维度(如速度 u, v, w)。
|
| 27 |
+
w_size (int): 潜在空间(Cluster Level)的特征维度。默认值: 512。
|
| 28 |
+
n_attention (int): Transformer 注意力层的数量。默认值: 4。
|
| 29 |
+
nb_gn (int): Encoder 中 GNN 的层数。默认值: 4。
|
| 30 |
+
n_heads (int): Transformer 注意力头数。默认值: 4。
|
| 31 |
+
"""
|
| 32 |
+
def __init__(self, state_size, w_size=512, n_attention=4, nb_gn=4, n_heads=4):
|
| 33 |
+
super(GraphViT, self).__init__()
|
| 34 |
+
|
| 35 |
+
# 傅里叶位置编码参数
|
| 36 |
+
pos_start = -3
|
| 37 |
+
pos_length = 8
|
| 38 |
+
|
| 39 |
+
# 1. 编码器: Mesh Space -> Latent Graph
|
| 40 |
+
self.encoder = GraphViTEncoder(
|
| 41 |
+
nb_gn=nb_gn,
|
| 42 |
+
state_size=state_size,
|
| 43 |
+
pos_length=pos_length
|
| 44 |
+
)
|
| 45 |
+
|
| 46 |
+
# 2. 池化层: Node Features -> Cluster Features
|
| 47 |
+
self.graph_pooling = RNNClusterPooling(
|
| 48 |
+
w_size=w_size,
|
| 49 |
+
pos_length=pos_length
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
# 3. 解码器: Cluster Features -> Node State Update
|
| 53 |
+
self.graph_retrieve = GraphViTDecoder(
|
| 54 |
+
w_size=w_size,
|
| 55 |
+
pos_length=pos_length,
|
| 56 |
+
state_size=state_size
|
| 57 |
+
)
|
| 58 |
+
|
| 59 |
+
# 4. 潜在空间 Transformer 交互层
|
| 60 |
+
self.attention = nn.ModuleList([
|
| 61 |
+
PreLNTransformerBlock(
|
| 62 |
+
w_size=w_size,
|
| 63 |
+
pos_length=pos_length,
|
| 64 |
+
n_heads=n_heads
|
| 65 |
+
)
|
| 66 |
+
for _ in range(n_attention)
|
| 67 |
+
])
|
| 68 |
+
|
| 69 |
+
self.ln = nn.LayerNorm(w_size)
|
| 70 |
+
self.noise_std = 0.0
|
| 71 |
+
|
| 72 |
+
# 5. 坐标嵌入层
|
| 73 |
+
self.positional_encoder = FourierPosEmbedding(
|
| 74 |
+
pos_start=pos_start,
|
| 75 |
+
pos_length=pos_length
|
| 76 |
+
)
|
| 77 |
+
|
| 78 |
+
def forward(
|
| 79 |
+
self,
|
| 80 |
+
mesh_pos,
|
| 81 |
+
edges,
|
| 82 |
+
state,
|
| 83 |
+
node_type,
|
| 84 |
+
clusters,
|
| 85 |
+
clusters_mask,
|
| 86 |
+
apply_noise=False,
|
| 87 |
+
):
|
| 88 |
+
"""
|
| 89 |
+
前向传播 (自回归滚动预测)。
|
| 90 |
+
|
| 91 |
+
参数:
|
| 92 |
+
mesh_pos: (B, T, N, 3) 节点坐标
|
| 93 |
+
edges: (B, T, M, 2) 边索引
|
| 94 |
+
state: (B, T, N, state_size) 节点物理状态
|
| 95 |
+
node_type: (B, T, N, 9) 节点类型 (One-hot)
|
| 96 |
+
clusters: (B, T, K, C_max) 簇索引
|
| 97 |
+
clusters_mask: (B, T, K, C_max) 簇掩码
|
| 98 |
+
apply_noise: 是否在初始状态施加噪声 (Training 时通常为 True)
|
| 99 |
+
"""
|
| 100 |
+
if apply_noise:
|
| 101 |
+
mask = torch.logical_or(
|
| 102 |
+
node_type[:, 0, :, NODE_NORMAL] == 1,
|
| 103 |
+
node_type[:, 0, :, NODE_OUTPUT] == 1,
|
| 104 |
+
)
|
| 105 |
+
noise = torch.randn_like(state[:, 0]).to(state.device) * self.noise_std
|
| 106 |
+
state[:, 0][mask] = state[:, 0][mask] + noise[mask]
|
| 107 |
+
|
| 108 |
+
state_hat = [state[:, 0]]
|
| 109 |
+
output_hat = []
|
| 110 |
+
target = []
|
| 111 |
+
|
| 112 |
+
# 从 t=1 开始预测,基于 t-1 的状态
|
| 113 |
+
for t in range(1, state.shape[1]):
|
| 114 |
+
# 1. 生成位置编码
|
| 115 |
+
mesh_posenc, cluster_posenc = self.positional_encoder(
|
| 116 |
+
mesh_pos[:, t - 1], clusters[:, t - 1], clusters_mask[:, t - 1]
|
| 117 |
+
)
|
| 118 |
+
|
| 119 |
+
# 2. 图节点和边编码
|
| 120 |
+
V, E = self.encoder(
|
| 121 |
+
mesh_pos[:, t - 1],
|
| 122 |
+
edges[:, t - 1],
|
| 123 |
+
state_hat[-1],
|
| 124 |
+
node_type[:, t - 1],
|
| 125 |
+
mesh_posenc,
|
| 126 |
+
)
|
| 127 |
+
|
| 128 |
+
# 3. 聚类池化
|
| 129 |
+
W = self.graph_pooling(
|
| 130 |
+
V, clusters[:, t - 1], mesh_posenc, clusters_mask[:, t - 1]
|
| 131 |
+
)
|
| 132 |
+
|
| 133 |
+
# 4. 构建 Attention Mask
|
| 134 |
+
attention_mask = clusters_mask[:, t - 1].sum(-1, keepdim=True) == 0
|
| 135 |
+
attention_mask = (
|
| 136 |
+
attention_mask.unsqueeze(1)
|
| 137 |
+
.repeat(1, len(self.attention), 1, W.shape[1])
|
| 138 |
+
.view(-1, W.shape[1], W.shape[1])
|
| 139 |
+
)
|
| 140 |
+
attention_mask[:, torch.eye(W.shape[1], dtype=torch.bool)] = False
|
| 141 |
+
attention_mask = attention_mask.transpose(-1, -2)
|
| 142 |
+
|
| 143 |
+
# 5. 潜在空间 Transformer 交互
|
| 144 |
+
for a in self.attention:
|
| 145 |
+
W = a(W, attention_mask, cluster_posenc)
|
| 146 |
+
W = self.ln(W)
|
| 147 |
+
|
| 148 |
+
# 6. 解码预测更新量
|
| 149 |
+
next_output = self.graph_retrieve(
|
| 150 |
+
W, V, clusters[:, t - 1], mesh_posenc, edges[:, t - 1], E
|
| 151 |
+
)
|
| 152 |
+
|
| 153 |
+
# 7. 更新下一时刻状态
|
| 154 |
+
next_state = state_hat[-1] + next_output
|
| 155 |
+
target.append(state[:, t] - state_hat[-1])
|
| 156 |
+
|
| 157 |
+
# 8. 强制边界条件 (Mask 覆盖)
|
| 158 |
+
mask = torch.logical_or(
|
| 159 |
+
node_type[:, t, :, NODE_INPUT] == 1, node_type[:, t, :, NODE_WALL] == 1
|
| 160 |
+
)
|
| 161 |
+
mask = torch.logical_or(mask, node_type[:, t, :, NODE_DISABLE] == 1)
|
| 162 |
+
next_state[mask, :] = state[:, t][mask, :]
|
| 163 |
+
|
| 164 |
+
state_hat.append(next_state)
|
| 165 |
+
output_hat.append(next_output)
|
| 166 |
+
|
| 167 |
+
# 堆叠时间步
|
| 168 |
+
velocity_hat = torch.stack(state_hat, dim=1)
|
| 169 |
+
output_hat = torch.stack(output_hat, dim=1)
|
| 170 |
+
target = torch.stack(target, dim=1)
|
| 171 |
+
|
| 172 |
+
# velocity_hat: [B, T, N, S], output_hat: [B, T-1, N, S]
|
| 173 |
+
return velocity_hat, output_hat, target
|
scripts/fake_data.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
import numpy as np
|
| 6 |
+
|
| 7 |
+
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
| 8 |
+
sys.path.insert(0, str(PROJECT_ROOT / "model"))
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def write_split(split_dir: Path, name: str, samples):
|
| 12 |
+
split_dir.mkdir(parents=True, exist_ok=True)
|
| 13 |
+
with open(split_dir / f"{name}.txt", "w", encoding="utf-8") as handle:
|
| 14 |
+
for sample in samples:
|
| 15 |
+
handle.write(f"{sample}\n")
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def make_sample(path: Path, seed: int, steps: int = 990, nodes: int = 6):
|
| 19 |
+
rng = np.random.default_rng(seed)
|
| 20 |
+
path.mkdir(parents=True, exist_ok=True)
|
| 21 |
+
|
| 22 |
+
base = np.array(
|
| 23 |
+
[
|
| 24 |
+
[0.0, 0.0],
|
| 25 |
+
[1.0, 0.0],
|
| 26 |
+
[0.0, 1.0],
|
| 27 |
+
[1.0, 1.0],
|
| 28 |
+
[0.5, 0.2],
|
| 29 |
+
[0.5, 0.8],
|
| 30 |
+
],
|
| 31 |
+
dtype=np.float32,
|
| 32 |
+
)
|
| 33 |
+
drift = np.linspace(0.0, 0.04, steps, dtype=np.float32).reshape(steps, 1, 1)
|
| 34 |
+
pointcloud = base.reshape(1, nodes, 2) + drift
|
| 35 |
+
|
| 36 |
+
t = np.arange(steps, dtype=np.float32).reshape(steps, 1)
|
| 37 |
+
x = pointcloud[..., 0]
|
| 38 |
+
y = pointcloud[..., 1]
|
| 39 |
+
vx = np.sin(x + t * 0.1).astype(np.float32)
|
| 40 |
+
vy = np.cos(y + t * 0.1).astype(np.float32)
|
| 41 |
+
ps = (x + y + 0.01 * rng.standard_normal((steps, nodes))).astype(np.float32)
|
| 42 |
+
pg = (x - y + 0.01 * rng.standard_normal((steps, nodes))).astype(np.float32)
|
| 43 |
+
mask = np.zeros((steps, nodes), dtype=np.int64)
|
| 44 |
+
|
| 45 |
+
triangles = np.array(
|
| 46 |
+
[
|
| 47 |
+
[0, 1, 4],
|
| 48 |
+
[0, 4, 2],
|
| 49 |
+
[1, 3, 4],
|
| 50 |
+
[2, 4, 5],
|
| 51 |
+
[3, 5, 4],
|
| 52 |
+
],
|
| 53 |
+
dtype=np.int64,
|
| 54 |
+
)
|
| 55 |
+
triangles = np.repeat(triangles.reshape(1, -1, 3), steps, axis=0)
|
| 56 |
+
|
| 57 |
+
np.savez(
|
| 58 |
+
path / "sim.npz",
|
| 59 |
+
pointcloud=pointcloud,
|
| 60 |
+
VX=vx,
|
| 61 |
+
VY=vy,
|
| 62 |
+
PS=ps,
|
| 63 |
+
PG=pg,
|
| 64 |
+
mask=mask,
|
| 65 |
+
)
|
| 66 |
+
np.save(path / "triangles.npy", triangles)
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def main():
|
| 70 |
+
os.chdir(PROJECT_ROOT)
|
| 71 |
+
data_root = PROJECT_ROOT / "data" / "fake" / "Eagle_dataset"
|
| 72 |
+
split_dir = PROJECT_ROOT / "data" / "fake" / "splits"
|
| 73 |
+
samples = ["Cre/fake_case_000/1", "Cre/fake_case_001/1", "Cre/fake_case_002/1"]
|
| 74 |
+
|
| 75 |
+
for idx, sample in enumerate(samples):
|
| 76 |
+
make_sample(data_root / sample, seed=idx)
|
| 77 |
+
|
| 78 |
+
write_split(split_dir, "train", samples[:2])
|
| 79 |
+
write_split(split_dir, "valid", samples[2:])
|
| 80 |
+
write_split(split_dir, "test", samples[2:])
|
| 81 |
+
print(f"Fake Eagle data written to: {data_root}")
|
| 82 |
+
print(f"Fake splits written to: {split_dir}")
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
if __name__ == "__main__":
|
| 86 |
+
main()
|
scripts/inference.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import ctypes
|
| 2 |
+
import os
|
| 3 |
+
import sys
|
| 4 |
+
import sysconfig
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def preload_python_shared_library():
|
| 9 |
+
"""Make libpython visible to native extensions loaded with ctypes."""
|
| 10 |
+
libdir = sysconfig.get_config_var("LIBDIR")
|
| 11 |
+
version = sysconfig.get_config_var("VERSION")
|
| 12 |
+
if not libdir or not version:
|
| 13 |
+
return
|
| 14 |
+
|
| 15 |
+
candidates = [
|
| 16 |
+
Path(libdir) / f"libpython{version}.so.1.0",
|
| 17 |
+
Path(libdir) / f"libpython{version}.so",
|
| 18 |
+
]
|
| 19 |
+
for libpython in candidates:
|
| 20 |
+
if libpython.exists():
|
| 21 |
+
ctypes.CDLL(str(libpython), mode=ctypes.RTLD_GLOBAL)
|
| 22 |
+
return
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
preload_python_shared_library()
|
| 26 |
+
|
| 27 |
+
import numpy as np
|
| 28 |
+
import torch
|
| 29 |
+
from tqdm import tqdm
|
| 30 |
+
|
| 31 |
+
# 获取项目根目录(train.py上级的上级)
|
| 32 |
+
root_path = Path(__file__).parent.parent
|
| 33 |
+
sys.path.insert(0, str(root_path))
|
| 34 |
+
|
| 35 |
+
from model.graphViT import GraphViT
|
| 36 |
+
from onescience.distributed.manager import DistributedManager
|
| 37 |
+
from onescience.utils.YParams import YParams
|
| 38 |
+
from onescience.datapipes.cfd import EagleDatapipe
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def resolve_project_path(path):
|
| 42 |
+
path = Path(path)
|
| 43 |
+
return path if path.is_absolute() else root_path / path
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def fix_single_cluster_path(datapipe, cfg_data):
|
| 47 |
+
if int(cfg_data.data.n_cluster) != 1:
|
| 48 |
+
return
|
| 49 |
+
|
| 50 |
+
cluster_path = Path(cfg_data.source.cluster_dir)
|
| 51 |
+
for dataset_name in ("train_dataset", "val_dataset", "test_dataset"):
|
| 52 |
+
dataset = getattr(datapipe, dataset_name, None)
|
| 53 |
+
if dataset is not None and getattr(dataset, "cluster_path", None) is None:
|
| 54 |
+
dataset.cluster_path = cluster_path
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def main():
|
| 58 |
+
os.chdir(root_path)
|
| 59 |
+
DistributedManager.initialize()
|
| 60 |
+
manager = DistributedManager()
|
| 61 |
+
|
| 62 |
+
config_path = root_path / "config" / "config.yaml"
|
| 63 |
+
cfg_model = YParams(config_path, "model")
|
| 64 |
+
cfg_data = YParams(config_path, "datapipe")
|
| 65 |
+
cfg_infer = YParams(config_path, "inference")
|
| 66 |
+
|
| 67 |
+
checkpoint_path = resolve_project_path(cfg_infer.checkpoint_path)
|
| 68 |
+
if not checkpoint_path.exists():
|
| 69 |
+
raise FileNotFoundError(
|
| 70 |
+
f"Checkpoint not found: {checkpoint_path}. Run `python scripts/train.py` first."
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
datapipe = EagleDatapipe(params=cfg_data, distributed=False)
|
| 74 |
+
fix_single_cluster_path(datapipe, cfg_data)
|
| 75 |
+
dataloader, _ = datapipe.test_dataloader(batch_size=int(cfg_infer.batch_size))
|
| 76 |
+
device_name = cfg_infer.get("device", "auto")
|
| 77 |
+
device = manager.device if device_name == "auto" else torch.device(device_name)
|
| 78 |
+
model = GraphViT(state_size=cfg_model.state_size, w_size=cfg_model.w_size).to(device)
|
| 79 |
+
checkpoint = torch.load(checkpoint_path, map_location=device, weights_only=False)
|
| 80 |
+
model.load_state_dict(checkpoint.get("model_state_dict", checkpoint))
|
| 81 |
+
|
| 82 |
+
output_dir = resolve_project_path(cfg_infer.output_dir)
|
| 83 |
+
output_dir.mkdir(parents=True, exist_ok=True)
|
| 84 |
+
|
| 85 |
+
model.eval()
|
| 86 |
+
saved = 0
|
| 87 |
+
with torch.no_grad():
|
| 88 |
+
for idx, x in enumerate(tqdm(dataloader, desc="Inference")):
|
| 89 |
+
if not x:
|
| 90 |
+
continue
|
| 91 |
+
mesh_pos = x["mesh_pos"].to(device)
|
| 92 |
+
edges = x["edges"].to(device).long()
|
| 93 |
+
velocity = x["velocity"].to(device)
|
| 94 |
+
pressure = x["pressure"].to(device)
|
| 95 |
+
node_type = x["node_type"].to(device)
|
| 96 |
+
clusters = x["cluster"].to(device).long()
|
| 97 |
+
clusters_mask = x["cluster_mask"].to(device).long()
|
| 98 |
+
|
| 99 |
+
state = torch.cat([velocity, pressure], dim=-1)
|
| 100 |
+
state_hat, output, target = model(
|
| 101 |
+
mesh_pos,
|
| 102 |
+
edges,
|
| 103 |
+
state,
|
| 104 |
+
node_type,
|
| 105 |
+
clusters,
|
| 106 |
+
clusters_mask,
|
| 107 |
+
apply_noise=False,
|
| 108 |
+
)
|
| 109 |
+
velocity_hat, pressure_hat = dataloader.dataset.denormalize(
|
| 110 |
+
state_hat[..., :2], state_hat[..., 2:]
|
| 111 |
+
)
|
| 112 |
+
pred = torch.cat([velocity_hat, pressure_hat], dim=-1).cpu().numpy()
|
| 113 |
+
np.save(output_dir / f"prediction_{idx:04d}.npy", pred)
|
| 114 |
+
saved += 1
|
| 115 |
+
|
| 116 |
+
print(f"Saved {saved} prediction file(s) to {output_dir}")
|
| 117 |
+
manager.cleanup()
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
if __name__ == "__main__":
|
| 121 |
+
main()
|
scripts/result.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
|
| 4 |
+
import numpy as np
|
| 5 |
+
|
| 6 |
+
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def main():
|
| 10 |
+
output_dir = PROJECT_ROOT / "result" / "output"
|
| 11 |
+
files = sorted(output_dir.glob("prediction_*.npy"))
|
| 12 |
+
if not files:
|
| 13 |
+
print(f"No prediction files found in {output_dir}")
|
| 14 |
+
return
|
| 15 |
+
|
| 16 |
+
print(f"Found {len(files)} prediction file(s) in {output_dir}")
|
| 17 |
+
for file in files[:5]:
|
| 18 |
+
arr = np.load(file)
|
| 19 |
+
print(f"{file.name}: shape={arr.shape}, mean={arr.mean():.6f}, std={arr.std():.6f}")
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
if __name__ == "__main__":
|
| 23 |
+
main()
|
scripts/train.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import ctypes
|
| 2 |
+
import logging
|
| 3 |
+
import os
|
| 4 |
+
import random
|
| 5 |
+
import sys
|
| 6 |
+
import sysconfig
|
| 7 |
+
import time
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def preload_python_shared_library():
|
| 12 |
+
"""Make libpython visible to native extensions loaded with ctypes."""
|
| 13 |
+
libdir = sysconfig.get_config_var("LIBDIR")
|
| 14 |
+
version = sysconfig.get_config_var("VERSION")
|
| 15 |
+
if not libdir or not version:
|
| 16 |
+
return
|
| 17 |
+
|
| 18 |
+
candidates = [
|
| 19 |
+
Path(libdir) / f"libpython{version}.so.1.0",
|
| 20 |
+
Path(libdir) / f"libpython{version}.so",
|
| 21 |
+
]
|
| 22 |
+
for libpython in candidates:
|
| 23 |
+
if libpython.exists():
|
| 24 |
+
ctypes.CDLL(str(libpython), mode=ctypes.RTLD_GLOBAL)
|
| 25 |
+
return
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
preload_python_shared_library()
|
| 29 |
+
|
| 30 |
+
import numpy as np
|
| 31 |
+
import torch
|
| 32 |
+
import torch.nn as nn
|
| 33 |
+
import torch.distributed as dist
|
| 34 |
+
from torch.nn.parallel import DistributedDataParallel
|
| 35 |
+
from tqdm import tqdm
|
| 36 |
+
|
| 37 |
+
# 获取项目根目录(train.py上级的上级)
|
| 38 |
+
root_path = Path(__file__).parent.parent
|
| 39 |
+
sys.path.insert(0, str(root_path))
|
| 40 |
+
|
| 41 |
+
from model.graphViT import GraphViT
|
| 42 |
+
from onescience.distributed.manager import DistributedManager
|
| 43 |
+
from onescience.utils.YParams import YParams
|
| 44 |
+
from onescience.datapipes.cfd import EagleDatapipe
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def save_best_model(model, optimizer, checkpoint_dir: str):
|
| 49 |
+
Path(checkpoint_dir).mkdir(parents=True, exist_ok=True)
|
| 50 |
+
model_to_save = model.module if hasattr(model, "module") else model
|
| 51 |
+
torch.save(
|
| 52 |
+
{
|
| 53 |
+
"model_state_dict": model_to_save.state_dict(),
|
| 54 |
+
"optimizer_state_dict": optimizer.state_dict(),
|
| 55 |
+
},
|
| 56 |
+
Path(checkpoint_dir) / "best_model.pth",
|
| 57 |
+
)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def load_best_model(model, checkpoint_dir: str, device: torch.device):
|
| 61 |
+
ckpt_path = Path(checkpoint_dir) / "best_model.pth"
|
| 62 |
+
checkpoint = torch.load(ckpt_path, map_location=device, weights_only=False)
|
| 63 |
+
state_dict = checkpoint.get("model_state_dict", checkpoint)
|
| 64 |
+
model.load_state_dict(state_dict)
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def setup_logging(rank: int):
|
| 68 |
+
logging.basicConfig(
|
| 69 |
+
level=logging.INFO if rank == 0 else logging.WARNING,
|
| 70 |
+
format="%(asctime)s - %(levelname)s - %(message)s",
|
| 71 |
+
stream=sys.stdout,
|
| 72 |
+
force=True,
|
| 73 |
+
)
|
| 74 |
+
return logging.getLogger("train")
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def get_loss(velocity, pressure, output, state_hat, target, mask, alpha):
|
| 78 |
+
velocity = velocity[:, 1:]
|
| 79 |
+
pressure = pressure[:, 1:]
|
| 80 |
+
velocity_hat = state_hat[:, 1:, :, :2]
|
| 81 |
+
pressure_hat = state_hat[:, 1:, :, 2:]
|
| 82 |
+
mask = mask[:, 1:].unsqueeze(-1)
|
| 83 |
+
|
| 84 |
+
loss_velocity = torch.sqrt(((velocity * mask - velocity_hat * mask) ** 2).mean(dim=-1)).mean()
|
| 85 |
+
loss_pressure = torch.sqrt(((pressure * mask - pressure_hat * mask) ** 2).mean(dim=-1)).mean()
|
| 86 |
+
mse = nn.MSELoss()
|
| 87 |
+
loss = mse(target[..., :2] * mask, output[..., :2] * mask)
|
| 88 |
+
loss = loss + alpha * mse(target[..., 2:] * mask, output[..., 2:] * mask)
|
| 89 |
+
return {"loss": loss, "MSE_velocity": loss_velocity, "MSE_pressure": loss_pressure}
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def move_batch(x, device):
|
| 93 |
+
return {
|
| 94 |
+
"mesh_pos": x["mesh_pos"].to(device),
|
| 95 |
+
"edges": x["edges"].to(device).long(),
|
| 96 |
+
"velocity": x["velocity"].to(device),
|
| 97 |
+
"pressure": x["pressure"].to(device),
|
| 98 |
+
"node_type": x["node_type"].to(device),
|
| 99 |
+
"mask": x["mask"].to(device),
|
| 100 |
+
"cluster": x["cluster"].to(device).long(),
|
| 101 |
+
"cluster_mask": x["cluster_mask"].to(device).long(),
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
def fix_single_cluster_path(datapipe, cfg_data):
|
| 106 |
+
if int(cfg_data.data.n_cluster) != 1:
|
| 107 |
+
return
|
| 108 |
+
|
| 109 |
+
cluster_path = Path(cfg_data.source.cluster_dir)
|
| 110 |
+
for dataset_name in ("train_dataset", "val_dataset", "test_dataset"):
|
| 111 |
+
dataset = getattr(datapipe, dataset_name, None)
|
| 112 |
+
if dataset is not None and getattr(dataset, "cluster_path", None) is None:
|
| 113 |
+
dataset.cluster_path = cluster_path
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
def validate(model, dataloader, device, alpha, manager):
|
| 117 |
+
model.eval()
|
| 118 |
+
total_loss, count = 0.0, 0
|
| 119 |
+
with torch.no_grad():
|
| 120 |
+
for x in dataloader:
|
| 121 |
+
if not x:
|
| 122 |
+
continue
|
| 123 |
+
batch = move_batch(x, device)
|
| 124 |
+
state = torch.cat([batch["velocity"], batch["pressure"]], dim=-1)
|
| 125 |
+
state_hat, output, target = model(
|
| 126 |
+
batch["mesh_pos"],
|
| 127 |
+
batch["edges"],
|
| 128 |
+
state,
|
| 129 |
+
batch["node_type"],
|
| 130 |
+
batch["cluster"],
|
| 131 |
+
batch["cluster_mask"],
|
| 132 |
+
apply_noise=False,
|
| 133 |
+
)
|
| 134 |
+
dataset = dataloader.dataset
|
| 135 |
+
state_hat[..., :2], state_hat[..., 2:] = dataset.denormalize(
|
| 136 |
+
state_hat[..., :2], state_hat[..., 2:]
|
| 137 |
+
)
|
| 138 |
+
velocity, pressure = dataset.denormalize(batch["velocity"], batch["pressure"])
|
| 139 |
+
costs = get_loss(velocity, pressure, output, state_hat, target, batch["mask"], alpha)
|
| 140 |
+
if manager.world_size > 1:
|
| 141 |
+
dist.all_reduce(costs["loss"], op=dist.ReduceOp.AVG)
|
| 142 |
+
total_loss += costs["loss"].item()
|
| 143 |
+
count += 1
|
| 144 |
+
return total_loss / max(count, 1)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def main():
|
| 148 |
+
os.chdir(root_path)
|
| 149 |
+
DistributedManager.initialize()
|
| 150 |
+
manager = DistributedManager()
|
| 151 |
+
logger = setup_logging(manager.rank)
|
| 152 |
+
|
| 153 |
+
config_path = root_path / "config" / "config.yaml"
|
| 154 |
+
cfg_model = YParams(config_path, "model")
|
| 155 |
+
cfg_data = YParams(config_path, "datapipe")
|
| 156 |
+
cfg_train = YParams(config_path, "training")
|
| 157 |
+
|
| 158 |
+
seed = int(cfg_train.get("seed", 0))
|
| 159 |
+
torch.manual_seed(seed)
|
| 160 |
+
random.seed(seed)
|
| 161 |
+
np.random.seed(seed)
|
| 162 |
+
|
| 163 |
+
datapipe = EagleDatapipe(params=cfg_data, distributed=(manager.world_size > 1))
|
| 164 |
+
fix_single_cluster_path(datapipe, cfg_data)
|
| 165 |
+
train_loader, train_sampler = datapipe.train_dataloader()
|
| 166 |
+
val_loader, val_sampler = datapipe.val_dataloader()
|
| 167 |
+
|
| 168 |
+
device_name = cfg_train.get("device", "auto")
|
| 169 |
+
device = manager.device if device_name == "auto" else torch.device(device_name)
|
| 170 |
+
model = GraphViT(state_size=cfg_model.state_size, w_size=cfg_model.w_size).to(device)
|
| 171 |
+
if manager.world_size > 1:
|
| 172 |
+
model = DistributedDataParallel(model, device_ids=[manager.local_rank], output_device=manager.local_rank)
|
| 173 |
+
|
| 174 |
+
optimizer = torch.optim.Adam(model.parameters(), lr=float(cfg_train.lr))
|
| 175 |
+
best_valid_loss = float("inf")
|
| 176 |
+
best_epoch = 0
|
| 177 |
+
|
| 178 |
+
for epoch in range(int(cfg_train.max_epoch)):
|
| 179 |
+
start = time.time()
|
| 180 |
+
if manager.world_size > 1:
|
| 181 |
+
train_sampler.set_epoch(epoch)
|
| 182 |
+
if val_sampler:
|
| 183 |
+
val_sampler.set_epoch(epoch)
|
| 184 |
+
|
| 185 |
+
model.train()
|
| 186 |
+
train_loss, count = 0.0, 0
|
| 187 |
+
pbar = tqdm(train_loader, desc=f"Epoch {epoch + 1}", disable=(manager.rank != 0))
|
| 188 |
+
for x in pbar:
|
| 189 |
+
if not x:
|
| 190 |
+
continue
|
| 191 |
+
batch = move_batch(x, device)
|
| 192 |
+
state = torch.cat([batch["velocity"], batch["pressure"]], dim=-1)
|
| 193 |
+
state_hat, output, target = model(
|
| 194 |
+
batch["mesh_pos"],
|
| 195 |
+
batch["edges"],
|
| 196 |
+
state,
|
| 197 |
+
batch["node_type"],
|
| 198 |
+
batch["cluster"],
|
| 199 |
+
batch["cluster_mask"],
|
| 200 |
+
apply_noise=True,
|
| 201 |
+
)
|
| 202 |
+
state_hat[..., :2], state_hat[..., 2:] = train_loader.dataset.denormalize(
|
| 203 |
+
state_hat[..., :2], state_hat[..., 2:]
|
| 204 |
+
)
|
| 205 |
+
velocity, pressure = train_loader.dataset.denormalize(batch["velocity"], batch["pressure"])
|
| 206 |
+
costs = get_loss(velocity, pressure, output, state_hat, target, batch["mask"], cfg_train.loss_alpha)
|
| 207 |
+
|
| 208 |
+
optimizer.zero_grad()
|
| 209 |
+
costs["loss"].backward()
|
| 210 |
+
optimizer.step()
|
| 211 |
+
|
| 212 |
+
train_loss += costs["loss"].item()
|
| 213 |
+
count += 1
|
| 214 |
+
pbar.set_postfix(loss=f"{costs['loss'].item():.6f}")
|
| 215 |
+
|
| 216 |
+
train_loss /= max(count, 1)
|
| 217 |
+
valid_loss = validate(model, val_loader, device, cfg_train.loss_alpha, manager)
|
| 218 |
+
if manager.rank == 0:
|
| 219 |
+
logger.info(
|
| 220 |
+
"Epoch %s/%s | %.2fs | train %.6f | valid %.6f",
|
| 221 |
+
epoch + 1,
|
| 222 |
+
cfg_train.max_epoch,
|
| 223 |
+
time.time() - start,
|
| 224 |
+
train_loss,
|
| 225 |
+
valid_loss,
|
| 226 |
+
)
|
| 227 |
+
if valid_loss < best_valid_loss:
|
| 228 |
+
best_valid_loss = valid_loss
|
| 229 |
+
best_epoch = epoch
|
| 230 |
+
save_best_model(model, optimizer, cfg_train.checkpoint_dir)
|
| 231 |
+
logger.info("Saved checkpoint to %s/best_model.pth", cfg_train.checkpoint_dir)
|
| 232 |
+
if epoch - best_epoch > int(cfg_train.patience):
|
| 233 |
+
break
|
| 234 |
+
|
| 235 |
+
if manager.rank == 0:
|
| 236 |
+
final_model = GraphViT(state_size=cfg_model.state_size, w_size=cfg_model.w_size).to(device)
|
| 237 |
+
load_best_model(final_model, cfg_train.checkpoint_dir, device)
|
| 238 |
+
test_loader, _ = datapipe.test_dataloader()
|
| 239 |
+
test_loss = validate(final_model, test_loader, device, cfg_train.loss_alpha, manager)
|
| 240 |
+
logger.info("Final test loss: %.6f", test_loss)
|
| 241 |
+
|
| 242 |
+
manager.cleanup()
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
if __name__ == "__main__":
|
| 246 |
+
main()
|