161 lines
9.0 KiB
Markdown
161 lines
9.0 KiB
Markdown
# 환경 준비와 실행
|
|
|
|
## 준비 순서
|
|
|
|
저장소 root에서 VS x64 개발 환경을 사용한다. 직접 프로젝트는 v145 toolset과 Windows SDK를
|
|
요구한다. 필요한 로컬 설치는 MKL·TBB·HDF5·OpenMP/Intel runtime과 승인된 GoogleTest
|
|
source checkout이다. CMake 경로에는 추가로 CMake 3.25 이상과 Ninja가 필요하다.
|
|
Dependency 설치·다운로드·외부 source 수정은 아래 명령에 포함되지 않는다.
|
|
|
|
직접 MSBuild 설정은 다음 환경변수 또는 ignored `msvc/Fesa.Local.props`로 주입한다.
|
|
|
|
| 변수 | 값의 의미 |
|
|
| --- | --- |
|
|
| `FESA_GTEST_SOURCE_DIR` | `googletest/include`와 source를 포함한 승인된 checkout root |
|
|
| `FESA_MKL_ROOT` | MKL의 include·lib·runtime을 포함한 설치 root |
|
|
| `FESA_TBB_ROOT` | TBB 설치 root; Debug와 Release runtime을 구분한다. |
|
|
| `FESA_HDF5_ROOT` | HDF5 C library의 include·lib·runtime 설치 root |
|
|
| `FESA_OMP_ROOT` | Intel OpenMP library와 runtime 설치 root |
|
|
| `MKL_DIR`·`TBB_DIR`·`HDF5_DIR` | CMake에서만 사용하는 각 CONFIG package 디렉터리; 설치 root와 혼동하지 않는다. |
|
|
|
|
VS x64 Developer PowerShell에서 다음을 확인한다. 누락되면 해당 로컬 설치 경로를 설정한
|
|
뒤 다시 확인한다. 개인 경로를 repository의 추적 파일에 기록하지 않는다.
|
|
|
|
```powershell
|
|
Get-Command cl.exe, MSBuild.exe
|
|
$required_roots = 'FESA_GTEST_SOURCE_DIR','FESA_MKL_ROOT','FESA_TBB_ROOT','FESA_HDF5_ROOT','FESA_OMP_ROOT'
|
|
foreach ($root_name in $required_roots) {
|
|
$root_path = [Environment]::GetEnvironmentVariable($root_name)
|
|
if (-not $root_path -or -not (Test-Path -LiteralPath $root_path -PathType Container)) {
|
|
throw "Missing local dependency root: $root_name"
|
|
}
|
|
}
|
|
```
|
|
|
|
위 확인은 환경변수 방식의 준비 절차다. `Fesa.Local.props`를 사용하는 경우에는 그 파일의
|
|
동일 MSBuild property 값을 확인한다. CMake는 `Fesa.Local.props`를 읽지 않는다.
|
|
|
|
## 주 개발 빌드와 직접 검사
|
|
|
|
저장소 root의 VS x64 개발 환경에서 실행한다. 앞 명령이 실패하면 뒤 명령으로 진행하지 않는다.
|
|
|
|
```powershell
|
|
MSBuild FESA.sln /m:2 /p:Configuration=Debug /p:Platform=x64
|
|
if ($LASTEXITCODE -ne 0) { throw 'MSBuild failed' }
|
|
```
|
|
|
|
출력은 `.build/native/Debug`다. Solver CLI는 `src/fesa/fesa.exe`, 세 검사 실행기는
|
|
`tests/fesa_unit_tests.exe`, `tests/fesa_integration_tests.exe`,
|
|
`tests/fesa_reference_tests.exe`에 있다. Release는 별도의 `Release` 디렉터리를 사용한다.
|
|
직접 MSBuild는 CMake·Ninja·Doxygen을 선행 실행하지 않는다.
|
|
|
|
다음은 한 번의 전체 직접 검사 예시다. 각 실행기는 새 process이므로 직렬로 실행한다.
|
|
고유 디렉터리의 raw 출력·XML과 discovery를 보관한다. 이 예시는 현재 PowerShell
|
|
process의 TMP/TEMP와 GoogleTest 선택 환경을 변경한다.
|
|
|
|
```powershell
|
|
$verify_run = Join-Path $env:LOCALAPPDATA ('fv-' + [guid]::NewGuid().ToString('N').Substring(0,8))
|
|
New-Item -ItemType Directory -Path $verify_run -ErrorAction Stop | Out-Null
|
|
$env:TMP = $verify_run
|
|
$env:TEMP = $verify_run
|
|
foreach ($filter_name in 'GTEST_FILTER','GTEST_TOTAL_SHARDS','GTEST_SHARD_INDEX','GTEST_SHARD_STATUS_FILE','GTEST_OUTPUT') {
|
|
Remove-Item -LiteralPath ('Env:' + $filter_name) -ErrorAction SilentlyContinue
|
|
}
|
|
foreach ($test_name in 'fesa_unit_tests','fesa_integration_tests','fesa_reference_tests') {
|
|
$test_exe = Join-Path '.build/native/Debug/tests' ($test_name + '.exe')
|
|
& $test_exe --gtest_list_tests > (Join-Path $verify_run ($test_name + '-discovery.txt'))
|
|
if ($LASTEXITCODE -ne 0) { throw "Discovery failed: $test_name" }
|
|
& $test_exe ('--gtest_output=xml:' + (Join-Path $verify_run ($test_name + '.xml'))) *> (Join-Path $verify_run ($test_name + '-raw.txt'))
|
|
if ($LASTEXITCODE -ne 0) { throw "Tests failed: $test_name; records: $verify_run" }
|
|
}
|
|
```
|
|
|
|
생성된 경로에서도 실제 최장 lease 경로를 확인한다. 너무 길면 승인된 짧은 작업 위치를 사용한다.
|
|
|
|
## MITC4 drilling 방식 변경
|
|
|
|
`src/fesa/elements/mitc4_drilling_internal.h`의 `kProductionDrillingMode` 한 곳을 바꾼다.
|
|
기본값은 `Mitc4DrillingMode::kDirectSpring`, 기존 방식은
|
|
`Mitc4DrillingMode::kLegacyCorotatedTwist`다. 변경 후 solver·CLI·검사를 모두 rebuild한다.
|
|
같은 모델의 모든 MITC4 정적·pressure·frequency·HHT에 적용되며 CLI/INP/환경변수나
|
|
section별 override는 현재 없다. 시험용 명시적 alternate mode 경로는 production 설정이 아니다.
|
|
서로 다른 mode의 실행물·DLL·입력 sibling 결과를 별도 위치에 두고 실제 metadata marker로
|
|
선택을 확인한다. 선형 변위와 원형상 eigen값이 두 방식에서 같아도 정상이다.
|
|
|
|
## CMake 보조 빌드
|
|
|
|
같은 VS x64 환경에서 로컬 CONFIG package 환경변수를 설정한 뒤 실행한다.
|
|
한국어 MSVC의 include 추적을 위해 configure/build의 code page를 65001로 맞춘다.
|
|
직접 검사와 별개의 짧고 고유한 TMP/TEMP를 만들고 상속된 필터·sharding을 제거한다.
|
|
|
|
```powershell
|
|
Get-Command cmake.exe, ninja.exe
|
|
chcp 65001
|
|
$cmake_verify_run = Join-Path $env:LOCALAPPDATA ('fc-' + [guid]::NewGuid().ToString('N').Substring(0,8))
|
|
New-Item -ItemType Directory -Path $cmake_verify_run -ErrorAction Stop | Out-Null
|
|
$env:TMP = $cmake_verify_run
|
|
$env:TEMP = $cmake_verify_run
|
|
foreach ($filter_name in 'GTEST_FILTER','GTEST_TOTAL_SHARDS','GTEST_SHARD_INDEX','GTEST_SHARD_STATUS_FILE','GTEST_OUTPUT') {
|
|
Remove-Item -LiteralPath ('Env:' + $filter_name) -ErrorAction SilentlyContinue
|
|
}
|
|
cmake --preset windows-msvc-ninja-debug
|
|
if ($LASTEXITCODE -ne 0) { throw 'Configure failed' }
|
|
cmake --build --preset windows-msvc-ninja-debug --parallel 2
|
|
if ($LASTEXITCODE -ne 0) { throw 'Build failed' }
|
|
ctest --preset windows-msvc-ninja-debug --show-only=json-v1
|
|
if ($LASTEXITCODE -ne 0) { throw 'Discovery failed' }
|
|
ctest --preset windows-msvc-ninja-debug --output-on-failure -j 1
|
|
if ($LASTEXITCODE -ne 0) { throw 'CTest failed' }
|
|
```
|
|
|
|
Debug tree는 `.build/cmake-debug`, Release tree는 `.build/cmake-release`다.
|
|
CLI는 각각의 tree에서 `src/fesa/fesa.exe`에 있다. Native와 CMake의 실행 기록을 분리하고
|
|
discovery가 0건이 아닌지, 전체 identity가 일치하는지 확인한다. CTest label만으로
|
|
물리 기능을 선별하지 않는다. 현재 공통 label에는 beam 이름이 들어 있으며 전체 검사의 procedure 분류가 아니다.
|
|
`fesa_docs`는 Doxygen을 검출했을 때만 존재하는 선택적 target이다.
|
|
|
|
## Python 비교기와 실제 모델
|
|
|
|
Python suite는 pytest·NumPy·h5py를 사용한다. 설치된 환경에서 다음을 실행한다.
|
|
|
|
```powershell
|
|
python -c "import pytest, numpy, h5py"
|
|
if ($LASTEXITCODE -ne 0) { throw 'Python dependencies are missing' }
|
|
python -m pytest tests -q
|
|
if ($LASTEXITCODE -ne 0) { throw 'Python tests failed' }
|
|
```
|
|
|
|
`scripts/verification/compare_hex8.py`와 `compare_hht_dynamic.py`는 입력·reference·HDF5를
|
|
읽고 지정한 JSON report를 쓴다. Solver는 실행하지 않는다. 실행 전에 각 script의 `--help`로
|
|
필수 인자와 덮어쓰기 방지 조건을 확인하고 기존 report와 다른 출력 위치를 사용한다.
|
|
|
|
실제 모델은 원본 INP hash를 확인해 새 작업 디렉터리로 복사한 뒤
|
|
`fesa.exe <작업복사본.inp>`로 실행한다. 출력은 해당 입력의 sibling이다.
|
|
Exit·로그·새 HDF5의 identity를 확인한 뒤 대응하는 정식 reference와 비교한다.
|
|
`reference/temp`는 사용하지 않는다. 원본 폴더 안에서 solver를 실행하지 않는다.
|
|
|
|
다음은 Debug 빌드 뒤 정식 beam 입력을 새 위치에서 실행하는 예시다. 원본 폴더에 쓰지 않으며
|
|
비교 CSV는 복사·수정하지 않는다. 실행 성공은 후속 reference 비교를 대신하지 않는다.
|
|
|
|
```powershell
|
|
$model_source = 'reference/cantilever beam/cantilever beam.inp'
|
|
$model_run = Join-Path $env:LOCALAPPDATA ('fm-' + [guid]::NewGuid().ToString('N').Substring(0,8))
|
|
New-Item -ItemType Directory -Path $model_run -ErrorAction Stop | Out-Null
|
|
$model_copy = Join-Path $model_run 'beam.inp'
|
|
Copy-Item -LiteralPath $model_source -Destination $model_copy -ErrorAction Stop
|
|
if ((Get-FileHash -LiteralPath $model_source).Hash -ne (Get-FileHash -LiteralPath $model_copy).Hash) {
|
|
throw 'Input copy hash mismatch'
|
|
}
|
|
& '.build/native/Debug/src/fesa/fesa.exe' $model_copy
|
|
if ($LASTEXITCODE -ne 0) { throw "Solver failed; records: $model_run" }
|
|
Get-Item -LiteralPath (Join-Path $model_run 'beam_results.h5'), (Join-Path $model_run 'beam_log.txt')
|
|
```
|
|
|
|
## 시간 측정과 배포의 경계
|
|
|
|
성능 판정은 Ryzen 7 5800H의 Windows/MSVC x64 최적화 Release가 기준이다.
|
|
같은 thread·runtime·전원·compiler 조건에서 워밍업 없이 모델별 process를 한 번 측정한다.
|
|
Process 시작 요청 직전부터 종료 직후까지 입력·계산·복구·로그·HDF5 최종화를 포함한다.
|
|
빌드·복사·VTune·비교는 측정 구간 밖이다. Debug 시간이나 반복 최솟값으로 대체하지 않는다.
|
|
배포 형식·installer·dependency 재배포 조건은 미확정이며 개발 빌드 절차를 배포 절차로 간주하지 않는다.
|