Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 43 additions & 11 deletions .github/scripts/compare_cpu_gpu_builds.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,55 @@ echo "=== Building (CPU-only reference) ==="
make -j8

echo ""
echo "--- Running test_cpu_gpu_consistency (CPU-only build) ---"
echo "This test will skip GPU-specific tests and run CPU validation only."
./test_cpu_gpu_consistency || {
echo "[INFO] CPU-only build completed (GPU tests skipped as expected)"
echo "--- Step 1: Generate CPU reference outputs ---"
rm -rf cpu_gpu_comparison
mkdir -p cpu_gpu_comparison
./test_cpu_gpu_consistency --dump-prefix cpu_gpu_comparison/cpu_ref || {
echo "[FAIL] CPU reference generation failed!"
exit 1
}
./test_solver_cpu_gpu --dump-prefix cpu_gpu_comparison/cpu_ref || {
echo "[FAIL] Solver CPU reference generation failed!"
exit 1
}
./test_time_history_consistency --dump-prefix cpu_gpu_comparison/cpu_ref || {
echo "[FAIL] Time-history CPU reference generation failed!"
exit 1
}

# Now run with the GPU-offload build
cd "$WORKDIR/build_ci_gpu_correctness"

echo ""
echo "--- Running test_cpu_gpu_consistency (GPU-offload build) ---"
echo "This test compares CPU and GPU execution paths within the same binary."
./test_cpu_gpu_consistency || {
echo "[FAIL] GPU consistency test failed!"
echo "--- Step 2: Run GPU and compare against CPU reference ---"
if [ ! -d "$WORKDIR/build_ci_gpu_correctness" ]; then
echo "[INFO] build_ci_gpu_correctness not found; creating GPU-offload build..."
rm -rf "$WORKDIR/build_ci_gpu_correctness"
mkdir -p "$WORKDIR/build_ci_gpu_correctness"
cd "$WORKDIR/build_ci_gpu_correctness"

echo "=== CMake Configuration (GPU-offload) ==="
CC=nvc CXX=nvc++ cmake .. -DCMAKE_BUILD_TYPE=Release -DUSE_GPU_OFFLOAD=ON 2>&1 | tee cmake_config.log
echo ""
echo "=== Building (GPU-offload) ==="
make -j8
else
cd "$WORKDIR/build_ci_gpu_correctness"
echo "=== Building (GPU-offload incremental) ==="
make -j8
fi

./test_cpu_gpu_consistency --compare-prefix "$WORKDIR/build_ci_cpu_ref/cpu_gpu_comparison/cpu_ref" || {
echo "[FAIL] GPU vs CPU comparison failed!"
exit 1
}
./test_solver_cpu_gpu --compare-prefix "$WORKDIR/build_ci_cpu_ref/cpu_gpu_comparison/cpu_ref" || {
echo "[FAIL] Solver GPU vs CPU comparison failed!"
exit 1
}
./test_time_history_consistency --compare-prefix "$WORKDIR/build_ci_cpu_ref/cpu_gpu_comparison/cpu_ref" || {
echo "[FAIL] Time-history GPU vs CPU comparison failed!"
exit 1
}

echo ""
echo "[PASS] CPU-only vs GPU-offload comparison completed successfully"
echo " GPU results match CPU reference within tolerance"

23 changes: 2 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,24 @@ name: CI

on:
push:
branches: [ main, master, develop ]
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- '.gitignore'
pull_request:
branches: [ main, master, develop ]
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- '.gitignore'

jobs:
build-and-test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest]
build_type: [Release, Debug]

steps:
- uses: actions/checkout@v3

- name: Install dependencies (Ubuntu)
if: runner.os == 'Linux'
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake build-essential

- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew install cmake

- name: Configure CMake
run: |
Expand Down Expand Up @@ -152,4 +134,3 @@ jobs:
exit 1
fi
echo "No warnings detected (unused-variable warnings excluded)"

7 changes: 1 addition & 6 deletions .github/workflows/gpu-ci.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
name: GPU CI

on:
pull_request:
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- '.gitignore'
push:

jobs:
gpu-tests:
Expand Down
38 changes: 0 additions & 38 deletions .github/workflows/test-local.yml

This file was deleted.

10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@ model_comparison.*
# Logs
*.log

# Keep example models but ignore trained models
# NN Models: commit curated models, ignore transient training runs
# Keep: curated models (*_caseholdout), README
# Ignore: job-id suffixed directories (e.g., tbnn_channel_2996744)
data/models/*_[0-9][0-9][0-9][0-9][0-9][0-9][0-9]/
data/models/test_*
data/models/*_real
data/models/tbnn_*
data/models/mlp_*
!data/models/example_*
!data/models/*_caseholdout/
!data/models/README.md

# Temp files
Expand Down
13 changes: 9 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,13 @@ if(BUILD_TESTS)
target_link_libraries(test_nn_integration nn_cfd_core)
add_test(NAME NNIntegrationTest COMMAND test_nn_integration)

add_executable(test_gpu_execution tests/test_gpu_execution.cpp)
target_link_libraries(test_gpu_execution nn_cfd_core)
add_test(NAME GPUExecutionTest COMMAND test_gpu_execution)
add_executable(test_backend_execution tests/test_backend_execution.cpp)
target_link_libraries(test_backend_execution nn_cfd_core)
add_test(NAME BackendExecutionTest COMMAND test_backend_execution)

add_executable(test_cpu_gpu_consistency tests/test_cpu_gpu_consistency.cpp)
target_link_libraries(test_cpu_gpu_consistency nn_cfd_core)
add_test(NAME CPUGPUConsistencyTest COMMAND test_cpu_gpu_consistency)
add_test(NAME ConsistencyTest COMMAND test_cpu_gpu_consistency)

add_executable(test_solver_cpu_gpu tests/test_solver_cpu_gpu.cpp)
target_link_libraries(test_solver_cpu_gpu nn_cfd_core)
Expand Down Expand Up @@ -224,6 +224,11 @@ if(BUILD_TESTS)
add_executable(test_turbulence_guard tests/test_turbulence_guard.cpp)
target_link_libraries(test_turbulence_guard nn_cfd_core)
add_test(NAME NanInfGuardTest COMMAND test_turbulence_guard)

# Turbulence feature tests - analytic validation of features, invariants, and model response
add_executable(test_turbulence_features tests/test_turbulence_features.cpp)
target_link_libraries(test_turbulence_features nn_cfd_core)
add_test(NAME TurbulenceFeaturesTest COMMAND test_turbulence_features)
endif()

# Installation
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ make -j4
# EARSM (Wallin-Johansson)
./channel --model earsm_wj --adaptive_dt

# Neural network model
./channel --model nn_tbnn --nn_preset test_tbnn --adaptive_dt
# Neural network models
./channel --model nn_mlp --nn_preset mlp_channel_caseholdout --adaptive_dt # Fast, GPU-optimized
./channel --model nn_tbnn --nn_preset tbnn_channel_caseholdout --adaptive_dt # Physically consistent

# Periodic hills
./periodic_hills --Nx 64 --Ny 96 --model baseline --adaptive_dt
Expand Down
Empty file removed data/.gitkeep
Empty file.
114 changes: 19 additions & 95 deletions data/README.md
Original file line number Diff line number Diff line change
@@ -1,105 +1,29 @@
# Neural Network Weights Directory
# Data Directory

This directory contains neural network weights and scaling parameters for the NN-based turbulence models.
This directory contains data assets for the CFD-NN project.

**Organization:**
- Root directory (`data/`): Legacy example weights (kept for backward compatibility)
- `models/` subdirectory: Organized model storage with metadata (recommended)
- `models/example_scalar_nut/` - Example MLP scalar eddy viscosity model
- `models/example_tbnn/` - Example TBNN tensor basis model
## Neural Network Models

To use a model from the `models/` directory, use `--nn_preset <model_name>` (e.g., `--nn_preset example_tbnn`).
**All neural network turbulence model weights are stored in `data/models/`.**

## File Format
See `data/models/README.md` for:
- Available trained models
- How to use models with `--nn_preset`
- Training your own models
- Model architecture details

### For `nn_mlp` model (scalar eddy viscosity)
### Quick Start

```
layer0_W.txt # Weight matrix for layer 0 (space-separated, row-major)
layer0_b.txt # Bias vector for layer 0 (one value per line)
layer1_W.txt # Weight matrix for layer 1
layer1_b.txt # Bias vector for layer 1
...
input_means.txt # Input feature means (one per line)
input_stds.txt # Input feature standard deviations (one per line)
```

### For `nn_tbnn` model (TBNN anisotropy)

Same format as above, but the output dimension should match the number of tensor basis functions (typically 4 for 2D).

## Exporting Weights from Python

### PyTorch Example

```python
import torch
import numpy as np

# Load your trained model
model = torch.load('model.pth')
model.eval()

# Export each layer
for i, layer in enumerate(model.layers):
W = layer.weight.detach().cpu().numpy() # Shape: (out_features, in_features)
b = layer.bias.detach().cpu().numpy() # Shape: (out_features,)

# Save in space-separated format
np.savetxt(f'layer{i}_W.txt', W, fmt='%.16e')
np.savetxt(f'layer{i}_b.txt', b, fmt='%.16e')

# Export input scaling (if used during training)
np.savetxt('input_means.txt', feature_means, fmt='%.16e')
np.savetxt('input_stds.txt', feature_stds, fmt='%.16e')
```

### TensorFlow/Keras Example

```python
import tensorflow as tf
import numpy as np
```bash
# Use trained TBNN model for channel flow
./channel --model nn_tbnn --nn_preset tbnn_channel_caseholdout

# Load your trained model
model = tf.keras.models.load_model('model.h5')
# Use trained TBNN model for periodic hills
./periodic_hills --model nn_tbnn --nn_preset tbnn_phll_caseholdout

# Export each dense layer
layer_idx = 0
for layer in model.layers:
if isinstance(layer, tf.keras.layers.Dense):
W, b = layer.get_weights() # W shape: (in_features, out_features)
W = W.T # Transpose to match C++ convention (out, in)

np.savetxt(f'layer{layer_idx}_W.txt', W, fmt='%.16e')
np.savetxt(f'layer{layer_idx}_b.txt', b, fmt='%.16e')
layer_idx += 1
# Use example/demo models (random weights - for testing only)
./channel --model nn_tbnn --nn_preset example_tbnn
./channel --model nn_mlp --nn_preset example_scalar_nut
```

## Example File Contents

**layer0_W.txt** (3 inputs, 2 outputs):
```
1.234567e-01 -2.345678e-01 3.456789e-01
4.567890e-01 5.678901e-01 -6.789012e-01
```

**layer0_b.txt**:
```
7.890123e-02
-8.901234e-02
```

## Feature Ordering

Features should match the order expected by the C++ code. For scalar `nu_t` model:

0. Normalized strain rate magnitude
1. Normalized rotation rate magnitude
2. Normalized wall distance
3. Strain-rotation ratio
4. Local Reynolds number
5. Normalized velocity magnitude

For TBNN model, features include tensor invariants as defined in `features.cpp`.


**Note:** NN models now require explicit selection via `--nn_preset` or `--weights/--scaling`. There are no default/fallback weights.
5 changes: 0 additions & 5 deletions data/input_means.txt

This file was deleted.

5 changes: 0 additions & 5 deletions data/input_stds.txt

This file was deleted.

Loading