예제 #1
0
    async def _apply_smoother(self, hess: bool):
        import adios2

        names = []

        if hess and self.precondition:
            src = 'hess_vel_raw.bp'
            dst = 'hess_vel_smooth.bp'
            cmd = f'xconvert_hessian kernels_raw.bp DATABASES_MPI/solver_data.bp hess_vel_raw.bp {self.precondition}'

            await self.mpiexec(getpath('adios', 'bin', cmd), getsize(self), 1,
                               0, 'adios')

        else:
            src = 'kernels_raw.bp'
            dst = 'hessian_smooth.bp' if hess else 'kernels_smooth.bp'

        # get the names of the kernels to be smoothed
        with adios2.open(self.abs(src), 'r') as fh:  # type: ignore
            pf = '_crust_mantle/array'

            for fstep in fh:
                step_vars = fstep.available_variables()

                for name in step_vars:
                    if name.endswith(pf):
                        name = name.split(pf)[0]

                        if name.startswith('hess_'):
                            if hess:
                                names.append(name)

                        else:
                            if not hess:
                                names.append(name)

        # save the number of kernels being smoothed for probe_smoother
        kind = 'smooth_' + ('hess' if hess else 'kl')
        cache[kind] = len(names)

        # get the command to call smoother
        cmd = 'bin/xsmooth_laplacian_sem_adios'
        radius = self.smooth_hessian if hess else self.smooth_kernels

        if isinstance(radius, list):
            radius = max(radius[1], radius[0] * radius[2]**self.iteration)

        kl = ','.join(names)

        await self.mpiexec(
            f'{cmd} {radius} {radius} {kl} {src} DATABASES_MPI/ {dst} > OUTPUT_FILES/{kind}.txt',
            getsize(self), 1, 0, 'smooth_kernels')

        # reset status
        del cache[kind]
예제 #2
0
    def add_step(self):
        step = len(self.misfits) - 1

        self.add(ws := Workspace(f'step_{step:02d}'))
        ws.add(ws.mkdir)

        # update model
        model = self.abs('../model_init.bp')

        if step == 0:
            mesh = self.abs('../kernel/solver_synthetic/DATABASES_MPI/solver_data.bp')
        
        else:
            mesh = self.abs(f'step_{step-1:02d}/kernel_misfit/solver_synthetic/DATABASES_MPI/solver_data.bp')
        
        cmd = f'{self.abs("../../adios/xupdate_model")} {self.steps[-1]} {model} {mesh} {self.abs("../direction.bp")} .'
        ws.add(partial(ws.mpiexec, cmd, nprocs=getsize()))
        
        # compute misfit
        ws.add(kernel := create_kernel('kernel_misfit', {
            'misfit_only': True, 'path_model': ws.abs('model_gll.bp'), 'path_encoded': self.abs('../kernel/observed.ft.h5')
        }))

        # compute next step
        ws.add(partial(self.bracket, kernel))
예제 #3
0
    async def _apply_preconditioner(self):
        kl = 'kernels_smooth.bp' if self.smooth_kernels else 'kernels_raw.bp'
        hess = 'hess_vel_smooth.bp' if self.smooth_hessian else 'kernels_raw.bp'
        cmd = f'xprecond_kernels {kl} {hess} kernels_precond.bp {self.precondition}'

        await self.mpiexec(getpath('adios', 'bin', cmd), getsize(self), 1, 0,
                           'adios')
예제 #4
0
    async def compute_direction(self, ws: Directory, i: int):
        if i == 0:
            # steepest descent for the first iteration
            await super().compute_direction(ws, i)

        else:
            # input paths
            path_file = ws.abs('path.txt')
            direction = ws.abs('direction.bp')
            solver_file = ws.abs(
                'kernel/solver_synthetic/DATABASES_MPI/solver_data.bp')
            nprocs = getsize()

            # write path to history kernels and directions
            lines = [str(min(self.mem, i))]

            for j in range(max(0, i - self.mem), i):
                lines.append(self.abs(f'iter_{j:02d}/kernels.bp'))
                lines.append(self.abs(f'iter_{j:02d}/direction.bp'))

            lines.append(ws.abs('kernels.bp'))
            ws.write('\n'.join(lines), path_file)

            await ws.mpiexec(
                f'../adios/xlbfgs {path_file} {solver_file} {direction}',
                nprocs=nprocs,
                walltime='adios')
예제 #5
0
파일: cg.py 프로젝트: icui/pyper
    async def compute_direction(self, ws: Directory, i: int):
        if i == 0:
            # steepest descent for the first iteration
            await super().compute_direction(ws, i)
        
        else:
            # input paths
            direction = ws.abs('direction.bp')
            kernels = ws.abs(f'kernels.bp')
            solver_file = ws.abs('kernel/solver_synthetic/DATABASES_MPI/solver_data.bp')
            nprocs = getsize()

            # previous iteration
            direction0 = self.abs(f'iter_{i-1:02d}/direction.bp')
            kernels0 = self.abs(f'iter_{i-1:02d}/kernels.bp')

            cmd = f'../adios/xcg_direction {kernels0} {kernels} {direction0} {solver_file} {direction}'
            await ws.mpiexec(cmd, nprocs=nprocs, walltime='adios')
예제 #6
0
    def setup(self):
        self.clear()

        # number of processors to use
        nprocs = getsize()

        if self.path_forward:
            # prepare adjoint simulation
            self.add(self._setup_adjoint)

            # call solver
            self.add(partial(self.mpiexec, 'bin/xspecfem3D', nprocs, 1, 1,
                             'solver_adjoint', True),
                     prober=partial(probe_solver, self))

            # move OUTPUT_FILES/kernels.bp to kernels_raw.bp
            self.add(
                partial(self.mv, 'OUTPUT_FILES/kernels.bp', 'kernels_raw.bp'),
                'move_kernels')

            # smooth kernels / hessian
            if self.smooth_kernels:
                self.add(partial(self._apply_smoother, False),
                         'smooth_kernels',
                         prober=partial(probe_smoother, self, False))

            if self.smooth_hessian:
                self.add(partial(self._apply_smoother, True),
                         'smooth_hessian',
                         prober=partial(probe_smoother, self, True))

            # apply preconditioner
            if self.precondition:
                self.add(self._apply_preconditioner)

            # link final kernels to kernels.bp
            self.add(self._finalize_adjoint)

        else:
            # prepare forward simulation
            self.add(self._setup_forward)

            # call mesher and solver
            self.add(partial(self.mpiexec, 'bin/xmeshfem3D', nprocs, 1, 0,
                             'mesher'),
                     prober=partial(probe_mesher, self))
            self.add(partial(self.mpiexec, 'bin/xspecfem3D', nprocs, 1, 1,
                             'solver_forward', True),
                     prober=partial(probe_solver, self))

            # move OUTPUT_FILES/synthetic.h5 to traces_raw.h5
            self.add(
                partial(self.mv, 'OUTPUT_FILES/synthetic.h5', 'traces_raw.h5'),
                'move_traces')

            # process traces
            if self.process_traces:
                if 'dst' in self.process_traces:
                    self.add(
                        asdf_task(self.abs('traces_raw.h5'),
                                  **self.process_traces))

                else:
                    self.add(
                        asdf_task(self.abs('traces_raw.h5'),
                                  self.abs('traces_proc.h5'),
                                  **self.process_traces))

            # link final traces to traces.h5
            self.add(self._finalize_forward)
예제 #7
0
 async def compute_direction(self, ws: Directory, i: int):
     nprocs = getsize()
     await ws.mpiexec(f'../adios/xsteepDescent kernels.bp direction.bp',
                      nprocs=nprocs,
                      walltime='adios')