使用 GPU PyOpenCL 优化的不同方法 python 代码:内核中的外部函数 GPU/PyOpenCL
Different ways to optimize with GPU PyOpenCL a python code : extern function inside kernel GPU/PyOpenCL
我已使用以下命令分析我的 Python 代码:
python2.7 -m cProfile -o X2_non_flat_multiprocessing_dummy.prof X2_non_flat.py
然后,我可以全局可视化不同贪心函数的重新分区:
如您所见,Pobs_C
和 interpolate
例程花费了大量时间,对应于以下代码片段:
def Pobs_C(z, zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T, R_T, DG_T_fid, DG_T, WGT_T, WT_T, WIAT_T, cl, P_dd_spec, RT500):
cc = 0
P_dd_ok = np.zeros(len(z_pk))
while cc < len(z_pk):
if ((cl+0.5)/RT500[cc] < 35 and (cl+0.5)/RT500[cc] > 0.0005):
P_dd_ok[cc] = P_dd_spec[cc]((cl+0.5)/RT500[cc])
cc=cc+1
P_dd_ok = CubicSpline(z_pk, P_dd_ok)
if paramo == 8:
P_dd_ok = P_dd_ok(z)*(DG_T(z)/DG_T_fid(z))**2
else:
P_dd_ok = P_dd_ok(z)
if paramo != 9 or paramo != 10 or paramo != 11:
C_gg = c/(100.*h_p)*0.5*delta_zpm*np.sum((F_dd_GG(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, E_T(z[1:]), R_T(z[1:]), WGT_T[aa][1:], WGT_T[bb][1:], DG_T(z[1:]), P_dd_ok[1:]) + F_dd_GG(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, E_T(z[:-1]), R_T(z[:-1]), WGT_T[aa][:-1], WGT_T[bb][:-1], DG_T(z[:-1]), P_dd_ok[:-1]))) + P_shot_GC(zi, zj)
else:
C_gg = 0.
if paramo < 12:
C_ee = c/(100.*h_p)*0.5*delta_zpm*(np.sum(F_dd_LL(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, E_T(z[1:]), R_T(z[1:]), WT_T[aa][1:], WT_T[bb][1:], DG_T(z[1:]), P_dd_ok[1:]) + F_dd_LL(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, E_T(z[:-1]), R_T(z[:-1]), WT_T[aa][:-1], WT_T[bb][:-1], DG_T(z[:-1]), P_dd_ok[:-1])) + np.sum(F_IA_d(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[1:]), R_T(z[1:]), DG_T(z[1:]), WT_T[aa][1:], WT_T[bb][1:], WIAT_T[aa][1:], WIAT_T[bb][1:], P_dd_ok[1:]) + F_IA_d(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[:-1]), R_T(z[:-1]), DG_T(z[:-1]), WT_T[aa][:-1], WT_T[bb][:-1], WIAT_T[aa][:-1], WIAT_T[bb][:-1], P_dd_ok[:-1])) + np.sum(F_IAIA(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[1:]), R_T(z[1:]), DG_T(z[1:]), WIAT_T[aa][1:], WIAT_T[bb][1:], P_dd_ok[1:]) + F_IAIA(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[:-1]), R_T(z[:-1]), DG_T(z[:-1]), WIAT_T[aa][:-1], WIAT_T[bb][:-1], P_dd_ok[:-1]))) + P_shot_WL(zi, zj)
else:
C_ee = 0.
C_gl = c/(100.*h_p)*0.5*delta_zpm*np.sum((F_dd_GL(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[1:]), R_T(z[1:]), DG_T(z[1:]), WGT_T[aa][1:], WT_T[bb][1:], WIAT_T[bb][1:], P_dd_ok[1:]) + F_dd_GL(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[:-1]), R_T(z[:-1]), DG_T(z[:-1]), WGT_T[aa][:-1], WT_T[bb][:-1], WIAT_T[bb][:-1], P_dd_ok[:-1])))
return C_gg, C_ee, C_gl
1)主要问题:有没有办法在这个例程中实现一个GPU/OpenCL层,特别是CubicSpline
或者整个[=14] =] 功能。
有哪些替代方案可以让我减少传递给 Pobs_C
及其内部函数 CubicSpline
的时间?
我对 OpenCL(不是 PyOpenCL)几乎没有概念,例如 map-reduce
方法或使用经典内核解决 Heat 2D equation
。
2) 之前的反馈: 我知道我们不能通过天真地认为在内核中调用外部函数会带来更高的加速来进行优化,因为 GPU 可以实现很多电话。相反,我宁愿把不同功能的所有内容都允许得到优化:你同意并确认吗?那么,我可以在内核代码中声明对外部函数的调用吗(我的意思是不在内核中的函数,即经典部分代码(称为 Host code
?)?
3) 可选问题:也许我可以在内核中声明这个外部函数:是否可以通过在内核中明确地声明这个函数?事实上,这可以避免复制所有可能与 GPU 并行化的函数的所有内容。
PS: 对不起,如果这是一个一般性的话题,但它会让我更清楚地了解在我的代码中包含 GPU/OpenCL 的可用方法上面然后优化它。
- Is there a way to implement a GPU/OpenCL layer in this routine, especially for CubicSpline or the whole Pobs_C function
很可能不会。分析中的大部分时间似乎都在 1200 万次多项式评估中,并且每个评估调用在 CPU 上仅花费 6 微秒。目前尚不清楚在该操作中是否会暴露出重大的令人尴尬的并行性。而且 GPU 只对执行令人尴尬的并行任务有用。
- So, can I declare inside the kernel code a call to an extern function (I mean a function not inside kernel, i.e the classical part code (called Host code ?) ?
没有。那是不可能的。鉴于 Python 代码必须在主机 CPU 上 运行 无论如何,很难理解可能带来的好处。
- Maybe can I declare this extern function inside the kernel : is it possible by doing explicitely[sic] this declaration inside ?
没有
我已使用以下命令分析我的 Python 代码:
python2.7 -m cProfile -o X2_non_flat_multiprocessing_dummy.prof X2_non_flat.py
然后,我可以全局可视化不同贪心函数的重新分区:
如您所见,Pobs_C
和 interpolate
例程花费了大量时间,对应于以下代码片段:
def Pobs_C(z, zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T, R_T, DG_T_fid, DG_T, WGT_T, WT_T, WIAT_T, cl, P_dd_spec, RT500):
cc = 0
P_dd_ok = np.zeros(len(z_pk))
while cc < len(z_pk):
if ((cl+0.5)/RT500[cc] < 35 and (cl+0.5)/RT500[cc] > 0.0005):
P_dd_ok[cc] = P_dd_spec[cc]((cl+0.5)/RT500[cc])
cc=cc+1
P_dd_ok = CubicSpline(z_pk, P_dd_ok)
if paramo == 8:
P_dd_ok = P_dd_ok(z)*(DG_T(z)/DG_T_fid(z))**2
else:
P_dd_ok = P_dd_ok(z)
if paramo != 9 or paramo != 10 or paramo != 11:
C_gg = c/(100.*h_p)*0.5*delta_zpm*np.sum((F_dd_GG(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, E_T(z[1:]), R_T(z[1:]), WGT_T[aa][1:], WGT_T[bb][1:], DG_T(z[1:]), P_dd_ok[1:]) + F_dd_GG(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, E_T(z[:-1]), R_T(z[:-1]), WGT_T[aa][:-1], WGT_T[bb][:-1], DG_T(z[:-1]), P_dd_ok[:-1]))) + P_shot_GC(zi, zj)
else:
C_gg = 0.
if paramo < 12:
C_ee = c/(100.*h_p)*0.5*delta_zpm*(np.sum(F_dd_LL(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, E_T(z[1:]), R_T(z[1:]), WT_T[aa][1:], WT_T[bb][1:], DG_T(z[1:]), P_dd_ok[1:]) + F_dd_LL(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, E_T(z[:-1]), R_T(z[:-1]), WT_T[aa][:-1], WT_T[bb][:-1], DG_T(z[:-1]), P_dd_ok[:-1])) + np.sum(F_IA_d(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[1:]), R_T(z[1:]), DG_T(z[1:]), WT_T[aa][1:], WT_T[bb][1:], WIAT_T[aa][1:], WIAT_T[bb][1:], P_dd_ok[1:]) + F_IA_d(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[:-1]), R_T(z[:-1]), DG_T(z[:-1]), WT_T[aa][:-1], WT_T[bb][:-1], WIAT_T[aa][:-1], WIAT_T[bb][:-1], P_dd_ok[:-1])) + np.sum(F_IAIA(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[1:]), R_T(z[1:]), DG_T(z[1:]), WIAT_T[aa][1:], WIAT_T[bb][1:], P_dd_ok[1:]) + F_IAIA(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[:-1]), R_T(z[:-1]), DG_T(z[:-1]), WIAT_T[aa][:-1], WIAT_T[bb][:-1], P_dd_ok[:-1]))) + P_shot_WL(zi, zj)
else:
C_ee = 0.
C_gl = c/(100.*h_p)*0.5*delta_zpm*np.sum((F_dd_GL(z[1:], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[1:]), R_T(z[1:]), DG_T(z[1:]), WGT_T[aa][1:], WT_T[bb][1:], WIAT_T[bb][1:], P_dd_ok[1:]) + F_dd_GL(z[:-1], zi, zj, h_p, wm_p, wDE_p, w0_p, wa_p, C_IAp, A_IAp, n_IAp, B_IAp, E_T(z[:-1]), R_T(z[:-1]), DG_T(z[:-1]), WGT_T[aa][:-1], WT_T[bb][:-1], WIAT_T[bb][:-1], P_dd_ok[:-1])))
return C_gg, C_ee, C_gl
1)主要问题:有没有办法在这个例程中实现一个GPU/OpenCL层,特别是CubicSpline
或者整个[=14] =] 功能。
有哪些替代方案可以让我减少传递给 Pobs_C
及其内部函数 CubicSpline
的时间?
我对 OpenCL(不是 PyOpenCL)几乎没有概念,例如 map-reduce
方法或使用经典内核解决 Heat 2D equation
。
2) 之前的反馈: 我知道我们不能通过天真地认为在内核中调用外部函数会带来更高的加速来进行优化,因为 GPU 可以实现很多电话。相反,我宁愿把不同功能的所有内容都允许得到优化:你同意并确认吗?那么,我可以在内核代码中声明对外部函数的调用吗(我的意思是不在内核中的函数,即经典部分代码(称为 Host code
?)?
3) 可选问题:也许我可以在内核中声明这个外部函数:是否可以通过在内核中明确地声明这个函数?事实上,这可以避免复制所有可能与 GPU 并行化的函数的所有内容。
PS: 对不起,如果这是一个一般性的话题,但它会让我更清楚地了解在我的代码中包含 GPU/OpenCL 的可用方法上面然后优化它。
- Is there a way to implement a GPU/OpenCL layer in this routine, especially for CubicSpline or the whole Pobs_C function
很可能不会。分析中的大部分时间似乎都在 1200 万次多项式评估中,并且每个评估调用在 CPU 上仅花费 6 微秒。目前尚不清楚在该操作中是否会暴露出重大的令人尴尬的并行性。而且 GPU 只对执行令人尴尬的并行任务有用。
- So, can I declare inside the kernel code a call to an extern function (I mean a function not inside kernel, i.e the classical part code (called Host code ?) ?
没有。那是不可能的。鉴于 Python 代码必须在主机 CPU 上 运行 无论如何,很难理解可能带来的好处。
- Maybe can I declare this extern function inside the kernel : is it possible by doing explicitely[sic] this declaration inside ?
没有