통신사업자들의 IT분야 신사업 전략 - kandroid.org · 모델을 기반으로 저렴한(무료) 음성 통화를 제공하면서 통신사업자와 경쟁하게 되면,
Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 ·...
Transcript of Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 ·...
![Page 1: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/1.jpg)
Python을 기반으로
C, Fortran, CUDA-C, OpenCL-C
코드 통합하기
김기환
(재)한국형수치예보모델개발사업단
GTC Korea 2015
![Page 2: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/2.jpg)
회사 소개
• 목표: 독자 수치예보모델 개발
• 2011년 시작 (2019년 완료)
• 약 900억 예산
![Page 3: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/3.jpg)
수치예보모델
• GEOS 5 (Goddard Earth Observing System)
• 미국 항공우주국(NASA)에서 개발한 전지구 대기 모델
• 7 km 격자 해상도, 30분 시간간격
• Visualizations by Greg Shirah on August 10, 2014
동영상
![Page 4: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/4.jpg)
Motivation
• 대부분의 수치예보모델은 Fortran으로만 개발되고 있다
• 모델이 막대한 계산성능(그리고 전력소모)을 요구함에도 불구하고, 새로운 저전력 고성능 머신들(eg. GPU, MIC, FPGA)을 활용하기가 매우 힘들다 – 25km 해상도, 15초 간격, 10일 예보 6시간 @5400 cores
• 모델 전체 코드 중 계산이 집중된 부분은 상대적으로 비중이 낮다
• Python이 대안이 될 수 있지 않을까?
![Page 5: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/5.jpg)
Goal
• 전체 모델 코드는 Python으로 작성 – 입출력, 전처리, 후처리, 가시화, 유닛테스트, 유지보수 유리
• 계산이 집중된 부분(hotspot)만 컴파일 언어로 대체 – CPU : Fortran, C
– GPU : CUDA-C, OpenCL-C
– MIC, FPGA : OpenCL-C
• Python의 장점과 컴파일 언어들의 장점 모두 활용
![Page 6: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/6.jpg)
간결하고 가독성 높은 문법 (≈ pseudo code)
쉬운 디버깅 정신건강에 이로움
활용도가 높은 표준 모듈들 (battery included)
과학/공학 계산에 유용한 확장 모듈들
(Numpy, Scipy, Matplotlib, H5Py, MPI4Py, …)
컴파일 언어 (C, C++, FORTRAN) 와의 쉬운 결합
간편한 GPU, MIC 활용 (PyCUDA, PyOpenCL)
풍부한 기술문서 (http://docs.python.org)
내가 좋아하는 Python 장점들
![Page 7: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/7.jpg)
참조 : www.scipy.org/Topical_Software
Science Tools for Python General Numpy Scipy GPGPU Computing PyCUDA PyOpenCL Parallel Computing PETSc PyMPI Pypar mpi4py Wrapping C/C++/Fortran SWIG Cython ctypes
Plotting &
Visualization
Matplotlib
Vislt
Chaco
MayaVi
AI
Pyem
Ffnet
Pymorph
Monte
Biology
Brian
SloppyCell
PySAT
Molecular &
Atomic Modeling
PyMOL
Biskit
GPAW
Geosciences
GIS Python
PyClimate
ClimPy
CDAT
Bayesian Stats
PyMC
Optimization
OpenOpt
Symbolic Math
SymPy
Electromagnetics
PyFemax
Astronomy
AstroLib
PySolar
Dynamic Systems
Simpy
PyDSTool
Finite Elements
SfePy
escript
![Page 8: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/8.jpg)
Numpy : 과학/공학 계산을 위한 기본 모듈 패키지
• 풍부한 기능의 N-차원 배열
• Broadcasting 함수 연산
• C, C++, FORTRAN 코드 결합을 위한 도구 (f2py)
• Linear algebra, Fourier transform, Random number
Scipy : 확장 모듈 패키지
Numpy & Scipy
• statistics
• optimization
• numerical integration
• linear algebra
• Fourier transforms
• signal processing
• image processing
• ODE solvers
• special functions
참조 : www.scipy.org
![Page 9: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/9.jpg)
1-D Poisson equation
Problem
Exact solution
Scipy 예제 - 1D Poisson Eq.
![Page 10: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/10.jpg)
Numeric solution: Central finite-difference method
Matrix form
Scipy 예제 - 1D Poisson Eq.
![Page 11: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/11.jpg)
Scipy 예제 - 1D Poisson Eq.
import numpy as np
from scipy.sparse import spdiags
from scipy.sparse.linalg import spsolve
omega = 5.4
u0, u1 = 0, 1
func = lambda x: omega**2 * np.sin(omega * x)
nx = 100; x = np.linspace(0, 1, nx); dx = x[1] – x[0]
u_exact = np.sin(omega*x) – (np.sin(omega) – 1) * x
arr = np.ones(nx-2)
A = spdiags([-arr, 2*arr, -arr], [-1, 0, 1], nx-2, nx-2)
b = func(x[1:-1]) * dx**2; b[0] += u0; b[-1] += u1
u = np.zeros_like(x)
u[0], u[-1], u[1:-1] = u0, u1, spsolve(A.tocsr(), b)
print np.linalg.norm(u_exact, u) == 0
$ python 1d_poisson.py
True
실행
![Page 12: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/12.jpg)
Scipy 예제 - 1D Poisson Eq. (Plot)
import matplotlib.pyplot as plt
plt.plot(x, u_exact, '.-k', label='Exact')
plt.plot(x, u_scipy, '.-b', label='Scipy')
plt.title('1-D Poisson')
plt.xlabel('x'); plt.ylabel(‘u(x)'); plt.legend()
plt.show()
![Page 13: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/13.jpg)
2-D wave equation
Numerics : Central finite-difference
Numpy 예제 – 2D Wave Eq.
![Page 14: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/14.jpg)
Numpy 예제 - 2D Wave Eq.
#!/usr/bin/env python
import numpy as np
# setup
nx, ny = 1000, 800
tmax, tgap = 600, 100
# allocation
c = np.ones((nx, ny)) * 0.25
f = np.zeros_like(c)
g = np.zeros_like(c)
# main time loop
sl = slice(1, -1)
sls = (sl, sl)
for tstep in xrange(1, tmax+1):
f[sls] = c[sls] * (g[2:,sl] + g[:-2,sl] + g[sl,2:] + g[sl,:-2] - 4*g[sls]) + 2*g[sls] - f[sls]
g[sls] = c[sls] * (f[2:,sl] + f[:-2,sl] + f[sl,2:] + f[sl,:-2] - 4*f[sls]) + 2*f[sls] - g[sls]
g[nx/2,ny/2] = np.sin(0.4 * tstep)
wave2d.py
![Page 15: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/15.jpg)
Numpy 예제 - 2D Wave Eq.
# allocation
(…)
# plot
import matplotlib.pyplot as plt
imag = plt.imshow(f, vmin=-0.1, vmax=0.1)
plt.colorbar()
# main time loop
for tstep in xrange(1, tmax+1):
(…)
if tstep % tgap == 0:
print('tstep= %d' % tstep)
imag.set_array(f)
plt.savefig('./png/%.4d.png' % tstep)
#plt.draw()
Plot
$ ./wave2d.py
tstep= 100
tstep= 200
tstep= 300
tstep= 400
tstep= 500
tstep= 600
$ display png/*
실행
![Page 16: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/16.jpg)
Numpy 예제 - 2D Wave Eq. Plot
0100.png 0400.png 0600.png
![Page 17: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/17.jpg)
Hotspot을
Fortran 코드로 바꿔봅시다
![Page 18: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/18.jpg)
f2py
• Python과 Fortran과의 쉬운 연동 제공
• Fortran의 Subroutine, Function, Module을 Python에서 호출
• Fortran에서 Python function 호출 (callback)
• Multi-dimensional Numpy array 인자 가능
• Fortran 77/90/95 지원
• Signature 파일 (.pyf)로부터 Python 확장 모듈 생성
• NumPy 프로젝트에서 개발
Python + Fortran using f2py
참조 : www.scipy.org
![Page 19: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/19.jpg)
Numpy 예제 - 2D Wave Eq.
코어 계산 부분을 function으로 선언
#!/usr/bin/env python
import numpy as np
def update_core(f, g, c):
sl = slice(1, -1)
sls = (sl, sl)
f[sls] = c[sls] * (g[2:,sl] + g[:-2,sl] + g[sl,2:] + g[sl,:-2] - 4*g[sls]) + 2*g[sls] - f[sls]
(…)
# main time loop
for tstep in xrange(1, tmax+1):
update_core(f, g, c)
update_core(g, f, c)
(…)
wave2d_python.py
![Page 20: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/20.jpg)
2D Wave Eq. (Python + Fortran)
update_core() 함수를 Fortran subroutine으로 변경
SUBROUTINE update_core(f, g, c, nx, ny)
IMPLICIT NONE
INTEGER, INTENT(in) :: nx, ny
DOUBLE PRECISION, DIMENSION(nx,ny), INTENT(inout) :: f
DOUBLE PRECISION, DIMENSION(nx,ny), INTENT(in) :: g, c
f(:nx-1,2:ny-1) = c(2:nx-1,2:ny-1) * (g(3:,2:ny-1) + g(:nx-2,2:ny-1) &
+ g(2:nx-1,3:) + g(2:nx-1,:ny-2) - 4*g(2:nx-1,2:ny-1)) &
+ 2*g(2:nx-1,2:ny-1) - f(2:nx-1,2:ny-1)
END SUBROUTINE update_core
ext_core.f90
컴파일, ext_core.so 생성
$ f2py –c –fcompiler=gnu95 –m ext_f90.so ext_core.f90
![Page 21: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/21.jpg)
2D Wave Eq. (Python + Fortran)
계산 코어를 Fortran subroutine으로 변경
#!/usr/bin/env python
import numpy as np
from ext_f90 import update_core
(…)
# main time loop
for tstep in xrange(1, tmax+1):
update_core(f, g, c)
update_core(g, f, c)
(…)
wave2d_fortran.py
![Page 22: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/22.jpg)
Hotspot을
C 코드로 바꿔봅시다
![Page 23: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/23.jpg)
2D Wave Eq. (Python + C)
update_core() 함수를 C function으로 변경
#include <Python.h>
#include <numpy/arrayobject.h>
static PyObject *update_core_py(PyObject *self, PyObject *args) {
int nx, ny;
PyArrayObject *F, *G, *C;
if (!PyArg_ParseTuple(args, “OOOii”, &F, &G, &C, &nx, &ny)) return NULL;
double *f, *g, *c;
int i, j, idx;
f = (double *)(F->data);
g = (double *)(G->data);
c = (double *)(C->data);
for (i = 0; i < nx; i++) {
for (j = 0; j < ny; j++) {
idx = i*ny +j;
f[idx] = c[idx] * (g[idx-ny] + g[idx+ny] + g[idx-1] + g[idx+1] - 4*g[idx]) + 2*g[idx] - f[idx];
}
}
Py_RETURN_NONE;
}
ext_core.c
(계속)
Python C API 사용
![Page 24: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/24.jpg)
2D Wave Eq. (Python + C)
update_core() 함수를 C function으로 변경
static PyMethodDef ufunc_methods[] = {
{“update_core”, update_core_py, METH_VARARGS, “”},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC initext_c() {
Py_InitModule(“ext_c”, ufunc_methods);
import_array();
}
이어서
컴파일, ext_core.so 생성
$ gcc –O3 –fPIC –g –I/usr/include/python2.7 –c ext_core.c –o ext_c.o
$ gcc –shared ext_core.o –o ext_c.so
![Page 25: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/25.jpg)
Hotspot을
CUDA 코드로 바꿔봅시다
![Page 26: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/26.jpg)
GPU (Graphics Processing Unit)
CPU는 임의의 메모리 접근, 흐름 제어를 포함하는 범용 연산에 적합
GPU는 많은 데이터에 동일한 연산을 수행하는 데이터 병렬 연산에 적합
GPU의 메모리 대역폭이 CPU보다 높다 (eg. 180 GB/s vs 40 GB/s)
CPU vs GPU
![Page 27: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/27.jpg)
데이터 병렬 연산 – ex) 벡터합
모든 데이터에 동일한 연산
![Page 28: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/28.jpg)
CUDA/OpenCL의 Python wrapper
모든 객체의 동적 할당/자동 해제
자동 에러 체크 : 파이썬 예외처리로 변환
JIT (Just-In-Time) 컴파일
빠른 개발 및 디버깅
PyCUDA/PyOpenCL
mathema.tician.de/software/pycuda mathema.tician.de/software/pyopencl
![Page 29: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/29.jpg)
2D Wave Eq. (Python + CUDA)
update_core() 함수를 CUDA kernel로 변경
__global__ void update_core(double *f, double *g, double *c, int nx, int ny) {
int tid = blockIdx.x * blockDim.x + threadIdx.x;
int i = tid / ny;
int j = tid % ny;
if (i > 0 && j > 0 && i < nx-1 && j < ny-1) {
f[tid] = c[tid] * (g[tid-ny] + g[tid+ny] + g[tid-1] + g[tid+1] - 4*g[tid])
+ 2*g[tid] - f[tid];
}
}
__global__ void update_src(double *f, double val, int idx0) {
int tid = blockIdx.x * blockDim.x + threadIdx.x;
if (tid == 0) f[idx0] += val;
}
ext_core.cu
![Page 30: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/30.jpg)
2D Wave Eq. (Python + CUDA)
#!/usr/bin/env python
import numpy as np
import pycuda.driver as cuda
import pycuda.autoinit
# setup
nx, ny = 1000, 800
tmax, tgap = 600, 100
# allocation
c = np.ones((nx, ny)) * 0.25
f = np.zeros_like(c)
c_gpu = cuda.to_device(c)
f_gpu = cuda.to_device(f)
g_gpu = cuda.to_device(f)
wave2d_cuda.py
(계속)
![Page 31: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/31.jpg)
2D Wave Eq. (Python + CUDA)
# cuda kernels
from pycuda.compiler import SourceModule
kernels = open('ext_core.cu').read()
mod = SourceModule(kernels)
update_core = mod.get_function('update_core')
update_src = mod.get_function('update_src')
bs, gs = (256,1,1), (nx*ny/256+1,1)
nnx, nny = np.int32(nx), np.int32(ny)
src_val = lambda tstep: np.sin(0.4 * tstep)
src_idx = np.int32( (nx/2)*ny + ny/2 )
# plot
(…)
# main time loop
for tstep in xrange(1, tmax+1):
update_core(f_gpu, g_gpu, c_gpu, nnx, nny, block=bs, grid=gs)
update_core(g_gpu, f_gpu, c_gpu, nnx, nny, block=bs, grid=gs)
update_src(g_gpu, src_val(tstep), src_idx, block=bs, grid=(1,1))
(…)
(이어서)
![Page 32: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/32.jpg)
Hotspot을
OpenCL 코드로 바꿔봅시다
![Page 33: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/33.jpg)
Intel MIC (Many Integrated Core)
~ 60 pentium cores
![Page 34: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/34.jpg)
2D Wave Eq. (Python + OpenCL)
update_core() 함수를 OpenCL kernel로 변경
#pragma OPENCL EXTENSION cl_amd_fp64 : enable
__kernel void update_core(__global double *f, __global double *g, __global double *c, int nx, int
ny) {
int tid = get_global_id(0);
int i = tid / ny;
int j = tid % ny;
if (i > 0 && j > 0 && i < nx-1 && j < ny-1)
f[tid] = c[tid] * (g[tid-ny] + g[tid+ny] + g[tid-1] + g[tid+1] - 4*g[tid])
+ 2*g[tid] - f[tid];
}
__kernel void update_src(__global double *f, __global double val, int idx0) {
int tid = get_global_id(0);
if (tid == 0) f[idx0] += val;
}
ext_core.cl
![Page 35: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/35.jpg)
2D Wave Eq. (Python + OpenCL)
#!/usr/bin/env python
import numpy as np
import pyopencl as cl
platforms = cl.get_platforms()
devices = platforms[0].get_devices() # 1st platform
context = cl.Context(devices)
queue = cl.CommandQueue(context, devices[0]) # 1st device
# setup
nx, ny = 1000, 800
tmax, tgap = 600, 100
# allocation
c = np.ones((nx, ny)) * 0.25
f = np.zeros_like(c)
c_dev = cl.Buffer(context, cl.mem_flags.COPY_HOST_PTR, hostbuf=c)
f_dev = cl.Buffer(context, cl.mem_flags.COPY_HOST_PTR, hostbuf=f)
g_dev = cl.Buffer(context, cl.mem_flags.COPY_HOST_PTR, hostbuf=f)
wave2d_opencl.py
(계속)
![Page 36: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/36.jpg)
2D Wave Eq. (Python + OpenCL)
# opencl kernels
kernels = open('ext_core.cl').read()
mod = cl.Program(context, kernels).build()
update_core = mod.update_core
update_src = mod. update_src
bs, gs = (60,), (nx*ny/256+1,)
nnx, nny = np.int32(nx), np.int32(ny)
src_val = lambda tstep: np.sin(0.4 * tstep)
src_idx = np.int32( (nx/2)*ny + ny/2 )
# plot
(…)
# main time loop
for tstep in xrange(1, tmax+1):
update_core(queue, bs, gs, f_dev, g_dev, c_dev, nnx, nny)
update_core(queue, bs, gs, g_dev, f_dev, c_dev, nnx, nny)
update_src(queue, bs, gs, g_dev, src_val(tstep), src_idx)
(…)
(이어서)
![Page 37: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/37.jpg)
Python 성능 비교
동일한 조건의 3차원 전자기 시뮬레이션 (FDTD) 실행 시간 비교
빛의 이중 슬릿 투과 시뮬레이션 (Maxwell 방정식)
![Page 38: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/38.jpg)
Python 성능 비교
빛의 이중 슬릿 투과 시뮬레이션 결과
![Page 39: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/39.jpg)
Python 성능 비교 (CPU)
Python-C API를 사용하여 계산이 집중된 부분만 C 코드로 작성함
Single CPU thread 최적화 코드 (SSE, OpenMP)
C Python+C C Python+C
GFLOPS 0.35 0.35 4.60 4.52
1.7 % 성능 차이
![Page 40: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/40.jpg)
Python 성능 비교 (GPU)
PyCUDA를 사용하여 계산이 집중된 부분만 CUDA 커널로 작성
CUDA-C PyCUDA
GFLOPS 20.16 20.16
거의 차이 없음
![Page 41: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/41.jpg)
Python에서 C, Fortran, CUDA-C, OpenCL-C와 쉽게 연동할 수 있다
수치모델 메인은 Python으로 작성, 계산이 집중된 부분만 컴파일 언어로 대체한다.
계산성능이 중요한 대규모의 과학계산 분야에서도 Python은 훌륭한 대안이 될 수 있다
Wrap up
![Page 42: Python을 기반으로 - Nvidiaimages.nvidia.com/content/gtc-kr/part_4_python.pdf · 2015-10-14 · Python을 기반으로 C, Fortran, CUDA-C, OpenCL-C 코드 통합하기 김기환](https://reader030.fdocuments.net/reader030/viewer/2022040321/5e5962631226ad6e024ea440/html5/thumbnails/42.jpg)
Have your fun with Python!
Thank you