使用openmp读取fortran中的多个netcdf文件



我有两个netcdf文件-ocean_rst_01.nc和ocean_rst _02.nc-我希望在Fortran中使用openmp并行读取它们。我使用的代码是以下

implicit none
....
....
!$OMP THREADPRIVATE(ncid,varid)
write ( *, '(a,i8)' ) &
'  The number of processors available = ', omp_get_num_procs ( )
write ( *, '(a,i8)' ) &
'  The number of threads available    = ', omp_get_max_threads ( )
filen = "ocean_rst_0x"
!$OMP PARALLEL DO PRIVATE(j,filename,varname,buf) 
do i = 1, nbv
j = OMP_GET_THREAD_NUM()
print*,"i=",i, "j = ",j! OMP_GET_THREAD_NUM()
if (i<10) write(num,"(a11,i1)") filen,i
if (i>=10) write(num,"(a10,i2)") filen,i
filename(i)=trim(num)//".nc"
write(6,*) "Reading file = ",trim(filename(i))," by ", j
varname="CHLA"
call check( NF90_OPEN(trim(filename(i)),NF90_NOWRITE,ncid) )
call check( NF90_INQ_VARID(ncid,trim(varname),varid) )
start = (/1, 1, 1/)
count = (/nlon, nlat, nlev/)
call check( NF90_GET_VAR(ncid,varid,buf,start=start, &
count = count) )
call check( NF90_CLOSE(ncid))
call check( NF90_OPEN(trim(filename(i)),NF90_NOWRITE,ncid) )
call check( NF90_INQ_VARID(ncid,"zeta",varid) )
start_1 = (/1, 1/)
count_1 = (/nlon, nlat/)
call check( NF90_GET_VAR(ncid,varid,buf2d,start=start_1, &
count = count_1) )
call check( NF90_CLOSE(ncid))
var(:,:,:,i) = buf(:,:,:)
var2d(:,:,i) = buf2d(:,:)
write(6,*) "var = ",var(132,231,39,i), "read by thread = ",j
write(6,*) "zeta = ",var2d(132,231,i), "read by thread = ",j
enddo
!$OMP END PARALLEL DO
end

我正在CRAY机器中使用ftn和netcdf4库编译代码。

我得到了随机输出。有时我会得到正确的输出。有时,var2d和/或var的输出对于两个线程是相同的。如果我将buf2d声明为私有,我会得到一个分段错误(核心转储(。有时我会得到以下错误

a.out:posio.c:442:px_rel:断言`pxp->bf_offset<=偏移量&amp;偏移<pxp->bf_offset+(off_t(pxp->bf_extent'失败。中止(堆芯转储(

如果我读取多个ascii文件,上面的算法可以很好地工作。使用openmp读取fortran 90中的多个netcdf文件的正确方法是什么?

不幸的是,netcdf目前不是线程安全的,请参阅例如

https://www.unidata.ucar.edu/support/help/MailArchives/netcdf/msg13578.html

尽管人们似乎确实在考虑这样做,例如

https://www.unidata.ucar.edu/blogs/developer/entry/implementing-thread-safe-access-to

因此,你想做的事情不太可能奏效,如果成功了,它可能不会可靠地工作,因为一个线程的操作会"干扰"另一个线程。

最新更新