calling field export, refactoring print_program

This commit is contained in:
ignis 2019-07-07 17:13:45 +09:00
parent 1dabc539ca
commit bd81bea8be

View file

@ -176,6 +176,9 @@ class FieldBase (object):
def is_fluctuation (self):
return self.fluc
def export_on (self):
return False
def __repr__ (self):
return self.name
@ -214,6 +217,79 @@ class FieldBase (object):
return real_array_free.format(self.name)
class FieldExporter (object):
mpi_io_decl='''
! - common
! integer(kind=MPI_OFFSET_KIND) :: offset
! integer(kind=MPI_INTEGER_KIND) :: mpi_err
! integer(kind=MPI_INTEGER_KIND) :: count
'''
fmt_decl='''
! - file_handles and mpi_infos
! integer(kind=MPI_INTEGER_KIND) :: {field_name}_fh
! integer(kind=MPI_INTEGER_KIND) :: {field_name}_info
! - buffer
! real*8, allocatable, dimension(:,:,:) :: {field_name}_export_array
'''
fmt_init='''
! init
! call MPI_INFO_CREATE({field_name}_info, mpi_err)
! call MPI_FILE_OPEN(MPI_COMM_TASK,{field_name}_fname,MPI_MODE_WRONLY+MPI_MODE_CREATE,{field_name}_info,{field_name}_fh,mpi_err)
! allocate({field_name}_export_array({1}), stat=ierr) ; {field_name}_export_array = 0.
'''
fmt_final='''
! finalize
! call MPI_FILE_CLOSE({field_name}_fh, mpi_err)
! call MPI_INFO_FREE({field_name}_info, mpi_err)
! deallocate({field_name}_export_array)
'''
fmt_calc='''
! copy to array for export
do k = 1, nzp
do j = 1, nyp
do i = {}, {}
{}(i,j,k) = {}(i,j,k)
end do
end do
end do
! after calculate
! count = {x1-x0+1} * ny * nz
! offset = time_count * count
! call MPI_FILE_WRITE_AT({field_name}_fh, offset, {field_name}_export_buffer, count, MPI_REAL8, mpi_status, mpi_err)
'''
def __init__ (self, name, attr, parent):
self.name = name
self.attr = attr
self.parent = parent
self.x0 = attr["x0"]
self.x1 = attr["x1"]
self.xslice = "{}:{},ny,nz".format(x0, x1)
def code (self):
# argument time index, file id, array
return # real_array_loop.format((self.array, rhs), self.comment)
def code_decl (self):
return # real_array_decl.format(self.name, self.dim)
def code_alloc (self):
return # real_array_alloc.format(self.name, self.shape)
def code_free (self):
return # real_array_free.format(self.name)
class Field (FieldBase):
def __init__ (self, name, attr, exp, fdict):
@ -672,7 +748,7 @@ class Stage4():
return narr, var2arr
def array_codes (self):
def work_array_codes (self):
array_names = [self.array_name.format(i) for i in range(self.narr)]
@ -687,32 +763,7 @@ class Stage4():
return decl, alloc, free
def print_program (self):
allvar = dict(self.derived)
allvar.update(self.averaged)
declarr, allocarr, freearr = self.array_codes()
declavg = "\n".join(v.code_decl() for v in self.averaged.itervalues())
allocavg = "\n".join(v.code_alloc() for v in self.averaged.itervalues())
freeavg = "\n".join(v.code_free() for v in self.averaged.itervalues())
sub_calc1 = "\n".join(allvar[v].code(self.alloc1) for v in self.pass1)
sub_calc2 = "\n".join(allvar[v].code(self.alloc2) for v in self.pass2)
set1 = sorted([a.name for a in filter(AveragedField.pass1, self.averaged.values())])
set2 = sorted([a.name for a in filter(AveragedField.pass2, self.averaged.values())])
sub_avg1 = "\n".join(allvar[v].code_avg() for v in set1)
sub_avg2 = "\n".join(allvar[v].code_avg() for v in set2)
ffmt = 'logical, parameter :: pass2_required={}'
declf = ffmt.format('.true.' if len(set2) > 0 else '.false.')
hfmt = 'character (len = *), parameter :: output_header="{}"'
declh = hfmt.format(" ".join(["x"] + set1 + set2))
def write_avg_codes (self, avglist):
avg_array_write = '''
integer :: i
@ -731,9 +782,46 @@ close (200)
avgarr = "{}(i)"
write_avg = avg_array_write.format(
len(self.averaged)+1,
", ".join(map(avgarr.format, set1+set2))
", ".join(map(avgarr.format, avglist))
)
return write_avg
def print_program (self):
allvar = dict(self.derived)
allvar.update(self.averaged)
set1 = sorted([a.name for a in filter(AveragedField.pass1, self.averaged.values())])
set2 = sorted([a.name for a in filter(AveragedField.pass2, self.averaged.values())])
set_export_on = filter(lambda x: x.export_on(), self.derived.values())
ffmt = 'logical, parameter :: pass2_required={}'
declf = ffmt.format('.true.' if len(set2) > 0 else '.false.')
hfmt = 'character (len = *), parameter :: output_header="{}"'
declh = hfmt.format(" ".join(["x"] + set1 + set2))
declarr, allocarr, freearr = self.work_array_codes()
declavg = "\n".join(v.code_decl() for v in self.averaged.itervalues())
allocavg = "\n".join(v.code_alloc() for v in self.averaged.itervalues())
freeavg = "\n".join(v.code_free() for v in self.averaged.itervalues())
decl_export = "\n".join(v.exporter.code_decl() for v in set_export_on)
alloc_export = "\n".join(v.exporter.code_alloc() for v in set_export_on)
free_export = "\n".join(v.exporter.code_free() for v in set_export_on)
sub_calc1 = "\n".join(allvar[v].code(self.alloc1) for v in self.pass1)
sub_calc2 = "\n".join(allvar[v].code(self.alloc2) for v in self.pass2)
sub_avg1 = "\n".join(allvar[v].code_avg() for v in set1)
sub_avg2 = "\n".join(allvar[v].code_avg() for v in set2)
sub_write_avg = self.write_avg_codes(set1+set2)
md = {}
md["module_name"] = "terms"
md["module_data"] = "\n".join((declf, declh, declavg, declarr))
@ -743,7 +831,7 @@ close (200)
md["module_pass1_avg"] = sub_avg1
md["module_pass2"] = sub_calc2
md["module_pass2_avg"] = sub_avg2
md["module_write_result"] = write_avg
md["module_write_result"] = sub_write_avg
return md