整理上学期课程资料的时候发现了自己在课程分享做的PPT和写的一些函数,选了个人觉得最有用来分享一下。
IDL并行功能函数,快速实现IDL程序并行,能简化平时使用并行函数的成本,但并行程序具有一定难度,适用于有一定IDL基础的使用者,因此并未添加关键字判断以及内容填充是否有误。
函数变量含义如下:
main_pro_path关键字用于指明待并行函数的pro程序路径
parallel_num关键字用于指明并行数量
set_key_dic关键字为字典,用于说明待并行函数的变量名称以及对应输入的变量,函数的变量名称为字典关键字,输入变量为字典值,类似于dict=dictionary("band4",data1,"band4",data2)
threads_txt_path关键字用于指定各线程的输出文档路径,名称为线程编号
function_name关键字指明带并行函数的名称及变量,此处变量的内容与数量与上述字典的关键字列表相同,类似于"pro ndvi,band5,band4"
other_pro_path关键字为pro文件路径列表,是在待并行函数中被调用且位于其他pro文件的函数路径列表
最后也会有一个使用案例进行详细说明。
并行功能函数:
pro parallel_function,main_pro_path=main_pro_path,parallel_num=parallel_num,set_key_dic=set_key_dic,threads_txt_path=threads_txt_path,$
function_name=function_name,other_pro_path=other_pro_path
;;;并行程序适用于有一定IDL基础,因此并未添加关键字判断以及内容填充是否有误
;;;main_pro_path关键字用于指明待并行函数的pro程序路径
;;;parallel_num关键字用于指明并行数量
;;;set_key_dic关键字为字典,用于说明待并行函数的变量名称以及对应输入的变量,函数的变量名称为字典关键字,输入变量为字典值,类似于dict=dictionary("band4",data1,"band4",data2)
;;;threads_txt_path关键字用于指定各线程的输出文档路径,名称为线程编号
;;;function_name关键字指明带并行函数的名称及变量,此处变量的内容与数量与上述字典的关键字列表相同,类似于"pro ndvi,band5,band4"
;;;other_pro_path关键字为pro文件路径列表,是在待并行函数中被调用且位于其他pro文件的函数路径列表
key_values=set_key_dic.values()
key_list=set_key_dic.keys()
file_num_list=fltarr(n_elements(key_list))
for key_value_i=0,n_elements(key_list)-1 do begin
file_num_list[key_value_i]=n_elements(set_key_dic[key_list[key_value_i]]) ;;得到待并行函数中各个变量的循环个数,确定循环数量
endfor
file_num_max=max(file_num_list)
threads=min([parallel_num,file_num_max]) ;;保证并行个数小于文件个数
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;开始构建并行;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if threads gt 0 then begin
p=objarr(threads)
order_1='.compile -v '+main_pro_path
dirct_list_i=0.0
for threads_i=0,threads-1 do begin
if KEYWORD_SET(threads_txt_path) eq 0 then p[threads_i]=obj_new('IDL_IDLBridge')
if KEYWORD_SET(threads_txt_path) eq 1 then p[threads_i]=obj_new('IDL_IDLBridge',OUTPUT=threads_txt_path+string(threads_i,format='(i02)')+'.txt')
p[threads_i]->execute,order_1
if KEYWORD_SET(other_pro_path) eq 1 then begin
for pro_i=0,n_elements(other_pro_path)-1 do begin
p[threads_i]->execute,'.compile -v '+other_pro_path[pro_i]
endfor
endif
for key_value_i=0,n_elements(key_values)-1 do begin
if file_num_list[key_value_i] eq 1 then begin
p[threads_i]->setvar,key_list[key_value_i],key_values[key_value_i]
endif else begin
temp_list=key_values[key_value_i]
p[threads_i]->setvar,key_list[key_value_i],temp_list[dirct_list_i]
endelse
endfor
p[threads_i]->execute,function_name,/nowait
dirct_list_i+=1.0
endfor
;;;;;;;;;;;;;;;;;;;第一次循环构建完毕,开始状态查询循环补充;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
signal=intarr(threads)
while 1 do begin
for signal_i=0,threads-1 do signal[signal_i]=p[signal_i]->status()
if (total(signal) eq 0) and (dirct_list_i eq file_num_max) then break
child=where(signal eq 0,child_num)
if child_num gt 0 then begin
for child_i=0,child_num-1 do begin
if (dirct_list_i eq file_num_max) then break
for key_value_i=0,n_elements(key_values)-1 do begin
if file_num_list[key_value_i] eq 1 then begin
p[child[child_i]]->setvar,key_list[key_value_i],key_values[key_value_i]
endif else begin
temp_list=key_values[key_value_i]
p[child[child_i]]->setvar,key_list[key_value_i],temp_list[dirct_list_i]
endelse
endfor
p[child[child_i]]->execute,function_name,/nowait
dirct_list_i+=1.0
endfor
endif
endwhile
for i=0,threads-1 do obj_destroy,p[i] ;;销毁并行
endif
;;;;;;;;;;;;;;;;;;;;;循环完成;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
end
函数使用示例:
parallel_function,main_pro_path='C:\Users\IDL_work\FY_DATA\FY4A\fy_lst.pro',parallel_num=3,set_key_dic=dictionary('tiff_path',file_list,'out_path',out_Path),$
function_name='data_get,tiff_path,out_path',other_pro_path=['H:\IDL\Study\常用结构函数\re_projection_by_lon_lat.pro','H:\IDL\Study\常用结构函数\fy_creat_lon_lat.pro']
当然,这样看难度可能也很大,因此我也把在课程分享时的案例文件以百度云的方式共享出来,包括PPT(主要内容为风云4数据重投影,并行功能在最后一节),数据文件和相应代码。
如果有读者发现了其中的错误或者进行了改进,欢迎大家指出,共同进步。
百度云链接:
链接:https://pan.baidu.com/s/1KjidBKdJLD4UIrH9FGE50w
提取码:2333