HCJung-jbnu / Autocoding

0 stars 0 forks source link

NEMO API: OpenACC 적용 -> nemolite2d #7

Closed HyunChaeJung closed 1 year ago

HyunChaeJung commented 1 year ago

[MPI+OpenACC]

HyunChaeJung commented 1 year ago

[ cluster CPU & GPU ]

*CPU: Intel Xeon Silver 4216 16C 2.10GHz 2대** 코어 수: 16 개 (총 32 개) / 스레드 수: 32 개 (총 64 개) 프로세서 기본 주파수(기본 클럭): 2.10 GHz / 프로세서 최대 주파수(최대 클럭): 3.20 GHz 인텔(소켓3647) / PCIe3.0

GPU: NVIDIA Quadro RTX6000 CUDA cores: 4,608 / NVIDIA tensor cores: 576 / NVIDIA RT cores: 72 GPU memory: 24 GB GDDR6 with ECC / Bandwidth: 624 GB/sec 16.3 TFLOPS FP32 Performance / 32.6 TFLOPS FP16 Performance System Interface: PCI Express 3.0 * 16

HyunChaeJung commented 1 year ago

~/PSyclone-2.0.0/config/psyclone.cfg

# Setting specific to the Nemo API
# ================================
[nemo]
# The valid types of loop and associated loop variable and bounds:
mapping-lon = var: ji, start: 1, stop: jpi
mapping-lat = var: jj, start: 1, stop: jpj
mapping-levels = var: jk, start: 1, stop: jpk
mapping-tracers = var: jt, start: 1, stop:
mapping-unknown = var: , start: 1, stop:
# Used for converting implicit loops to explicit loops
index-order = lon, lat, levels, tracers
HyunChaeJung commented 1 year ago

[check openacc version]

PROGRAM test
USE openacc
print*, _OPENACC
END PROGRAM
$ nvfortran -acc -o a.out check_acc_ver.F90
$ ./a.out
$        201711

'201711' => version 2.6

The OpenACC Application Program Interface version 2.6 (파일 위치: \Nextcloud\2021 차세대 전산과학\05 프로젝트수행\1-1 autocoding\reference\openacc_compile_method(options)\OpenACC-ver.2.6-Application_Programming_Interface_201711)

cf)

$ gfortran -fopenacc -o a.out check_acc_ver.F90
$ ./a.out
$        201306

'201306' => version 2.0

$ echo | cpp -fopenmp -dM | grep -i open
$ #define _OPENMP 201511

'201511' => version 4.5

+) 460.27.04+ (CUDA 11.2) CUDA toolkit(library) 11.2 NVIDIA HPC SDK 22.2 -> 여기서 제공해 주는 nvc, nvfortran이 OpenACC 지원

HyunChaeJung commented 1 year ago

[psyclone nemo api 활용 nemolite2d serial 코드에 openacc 지시문 삽입]



OpenMP 지시문을 삽입할 때와 동일한 방법(아래)으로 진행함.

  1. PROGRAM, END PROGRAMMODULE, END MODULE로 변경
  2. CONTAINS 이전에는 모듈 선언, 변수 선언만 존재하도록 다른 부분 삭제
  3. PSyclone NEMO API를 사용해 'lat' 루프에 OpenACC data, kernel 문 삽입
  4. 생성된 코드에서 MODULE, END MODULEPROGRAM, END PROGRAM으로 다시 변경하고, 2번 과정에서 삭제한 부분을 다시 추가

(4번) 코드 생성 시(PSY.gen) IF ~ CYCLE 문을 인지하지 못하여 오류 발생

!subroutine momentum
DO jj = 1, jpj
DO ji = 1, jpi-1
  IF(pt(ji,jj) + pt(ji+1,jj) <= 0)  CYCLE               !jump over non-computatinal domain
  IF(pt(ji,jj) <= 0 .OR. pt(ji+1,jj) <= 0)  CYCLE       !jump over boundary u
END DO
END DO

nemolite2D serial 코드에서 original 코드IF ~ CYCLE 문을 모두 삭제한 코드의 결과 값이 차이가 없어 (go2d_00000.dat (++22.08.29)) IF ~ CYCLE 문을 모두 삭제 후 4번을 진행함


++) 22.06.15 < psyclone NEMO API를 활용하기에 앞서 CYCLE 문을 주석 처리 할 경우 >

# ~/fparser/common/readfortran.py 
class FortranFileReader(FortranReaderBase):
        ...
    def __init__(self, file_candidate, ..., ignore_comments=True):
        ...

++)22.08.30




HyunChaeJung commented 1 year ago

[ nemolite2d serial code ]

PGI compiler

  • Makefile.include.pgi (Original ver., OpenMP ver.)
    
    F90 = pgf90

NETCDF_INC = /usr/local/netcdf/netcdf-fortran-4.4.4/PGI/include NETCDF_LIB = /usr/local/netcdf/netcdf-fortran-4.4.4/PGI/lib

F90FLAGS += -O3 LDFLAGS += -O3 OMPFLAGS = -mp=multicore -Minfo=mp

```~/.bash_profile``` : ```OMP_NUM_THREADS=4```
* ```Makefile.include.pgacc``` (OpenACC ver.)
``` shell
F90 = pgf90

NETCDF_INC = /usr/local/netcdf/netcdf-fortran-4.4.4/PGI/include
NETCDF_LIB = /usr/local/netcdf/netcdf-fortran-4.4.4/PGI/lib

F90FLAGS += -O3 -acc -ta=nvidia -Minfo=accel
LDFLAGS += -O3 -acc -ta=nvidia -Mcuda

Nsight System

  • Serial ver. $ nsys profile -o nemolite2d_serial_profile ./nemolite2d.exe
  • OpenMP ver. $ nsys profile -t openmp -o nemolite2d_openmp_profile ./nemolite2d.exe Nsight System은 OpenMP 5.0 이상의 버전을 지원하는데, 클러스터에 설치된 NVIDIA HPC SDK 22.2는 OpenMP 5.0을 지원함에도 불구하고 OpenMP의 버전은 4.5인 것으로 확인됨.
  • OpenACC ver. $ nsys profile -t openacc,cuda -o nemolite2d_acc_profile ./nemolite2d.exe
  • Profile Command Switch Options
HyunChaeJung commented 1 year ago

재밌는 분석 결과네요. 모든 루프에 openACC 적용하기 보단, CPU<->GPU 데이터 통신으로 인한 속도 저하(단점)와 병렬로 인한 속도 개선(장점)간의 밸런스가 중요하다는 이야기죠? 이 내용 잘 정리해서 분석하면, 앞으로 진행할 nemo+openACC 적용 전략 세울 수 있겠어요. 해당 내용 reference들(이전에 분석한 gnemo, nemo+openacc 보고서 내용) 참조해서 분석해주세요. 학회나 과제 보고 발표때 들어가면 좋을 내용들 같습니다.

아 그리고 질문이 한가지 더 있습니다. openMP와 openACC는 LAT 루프에만 저렇게 넣어도 내부에 위치한 LON 루프에 병렬이 적용되지 않는 건가요?

HyunChaeJung commented 1 year ago

OpenACC를 코드에 적용할 때 어떤 루프에, 어떤 옵션을 적용하면 효율적일지 고민이 필요할 것 같습니다. lat 루프에 병렬화 지시문을 삽입하면 내부에 위치한 lon 루프는 직렬로 계산되는 것으로 알고 있습니다. (예: lat 루프에 0~3번 thread 중 2번 thread가 할당되면 내부 lon 루프는 2번 thread로만 계산)

HyunChaeJung commented 1 year ago

image

image

HyunChaeJung commented 1 year ago

NEMOlite2D에 OpenACC 지시문 삽입

image