2

並列で実行される python コードでは、少なくとも 1 つのプロセッサで失敗したアサートはすべてのプロセッサを中止する必要があるように思えます。

1) エラー メッセージが明確に表示されている (スタック トレースを使用)

2) 残りのプロセッサが永遠に待機し続けるわけではありません。

ただし、これは標準の assert が行うことではありません。

この質問は、プロセッサー 0 でのアサートが失敗した場合に停止しない mpirun で実行されている python スクリプトで既に尋ねられてい ます が、私は答えに満足していません。comm.Abort() 関数を使用することをお勧めしますが、これは上記の 2) にしか答えません。

だから私は疑問に思っていました:並列コード(mpi4pyなど)用の標準の「アサート」機能はありますか、それともその目的のために独自のアサートを作成する必要がありますか?

ありがとう!

編集 - これが私の試みです(クラス内ですが、外部にある可能性があります)。これは確実に改善できます:

import mpi4py.MPI as mpi
import traceback

class My_code():

    def __init__(self, some_parameter=None):

        self.current_com = mpi.COMM_WORLD
        self.rank = self.current_com.rank
        self.nb_procs = self.current_com.size

        self.my_assert(some_parameter is not None)
        self.parameter = some_parameter
        print "Ok, parameter set to " + repr(self.parameter)

    # some class functions here...

    def my_assert(self, assertion):
        """
        this is a try for an assert function that kills 
        every process in a parallel run
        """
        if not assertion:
            print 'Traceback (most recent call last):'
            for line in traceback.format_stack()[:-1]:
                print(line.strip())
            print 'AssertionError'
            if self.nb_procs == 1:
                exit()
            else:
                self.current_com.Abort()
4

1 に答える 1

0

次のコードがその質問に答えると思います。これは、Dan D. が指摘した議論から派生したものです。

import mpi4py.MPI as mpi
import sys


# put this somewhere but before calling the asserts
sys_excepthook = sys.excepthook
def mpi_excepthook(type, value, traceback): 
    sys_excepthook(type, value, traceback) 
    if mpi.COMM_WORLD.size > 1:
        mpi.COMM_WORLD.Abort(1) 
sys.excepthook = mpi_excepthook 

# example:
if mpi.COMM_WORLD.rank == 0:
    # with sys.excepthook redefined as above this will kill every processor
    # otherwise this would only kill processor 0
    assert 1==0          

# assume here we have a lot of print messages
for i in range(50):
    print "rank = ", mpi.COMM_WORLD.rank

# with std asserts the code would be stuck here 
# and the error message from the failed assert above would hardly be visible
mpi.COMM_WORLD.Barrier()   
于 2015-12-16T13:29:30.603 に答える