Я пытаюсь прочитать разреженную матрицу PETSc, сохраненную из кода Фортрана, в двоичный файл следующим образом:
CALL PetscViewerBinaryOpen(PETSC_COMM_SELF, TRIM(ADJUSTL(filename)), FILE_MODE_WRITE, viewer2, ier)
CALL MatView(aa_symmetric, viewer2, ier)
CALL PetscViewerDestroy(viewer2, ier)
Когда я запускаю однопоточный код Фортрана, все работает нормально, и я могу без проблем прочитать матрицу, используя следующий код Python:
import petsc4py
from petsc4py import PETSc
# Initialize PETSc
petsc4py.init(sys.argv)
# Create a viewer for reading the binary file
viewer = PETSc.Viewer().createBinary(filename, mode='r', comm=PETSc.COMM_WORLD)
# Create a matrix and load data from the binary file
A_petsc = PETSc.Mat().create(comm=PETSc.COMM_WORLD)
A_petsc.setType(PETSc.Mat.Type.AIJ)
A_petsc.setFromOptions()
A_petsc.load(viewer)
# Finalize PETSc
PETSc.Finalize()
Однако, когда я запускаю код Фортрана на большем количестве процессоров («mpirun -n 2 my_exe»), я получаю следующую ошибку на стороне Python:
Traceback (most recent call last):
File "/home/Python/test_matrixImport_binary.py", line 80, in <module>
A_petsc.load(viewer) File "petsc4py/PETSc/Mat.pyx", line 2025, in
petsc4py.PETSc.Mat.load petsc4py.PETSc.Error: error code 79 [0] MatLoad() at
/home/lib/petsc-3.21.0/src/mat/interface/matrix.c:1344 [0] MatLoad_SeqAIJ() at
/home/lib/petsc-3.21.0/src/mat/impls/aij/seq/aij.c:5091 [0] MatLoad_SeqAIJ_Binary() at
/home/lib/petsc-3.21.0/src/mat/impls/aij/seq/aij.c:5142 [0] Unexpected data in file [0]
Inconsistent matrix data in file: nonzeros = 460, sum-row-lengths = 761
Как я могу это исправить?
Честно говоря, я не уверен, что именно это было сделано в другой части кода, которую я не писал, и я просто повторно использовал тот же код. Я точно знаю, что сохранение работает нормально - когда я использую программу просмотра ASCII, все работает как положено.
Сохраненный вывод должен каким-то образом отличаться, когда его можно открыть, а когда нельзя.






Похоже, что проблема была на стороне экспорта, а не на стороне PETSc. Первоначально я написал процедуру экспорта для симметричных матриц, но затем применил ее к несимметричной, что привело к путанице в адресации в двоичном файле. Я не уловил этого раньше, потому что использовал свою собственную процедуру импорта ASCII на стороне Python, которая не заботилась о симметрии. Фрагмент в вопросе должен работать нормально. Сейчас я использую следующие две функции, которые, на мой взгляд, немного понятнее:
import numpy as np
from scipy.sparse import coo_matrix, csr_matrix
from petsc4py import PETSc
def readMat(filename, toScipy=False):
viewer = PETSc.Viewer().createBinary(filename, mode='r', comm=PETSc.COMM_WORLD)
A_petsc = PETSc.Mat().create(comm=PETSc.COMM_WORLD)
A_petsc.setType(PETSc.Mat.Type.AIJ)
A_petsc.setFromOptions()
A_petsc.load(viewer)
if toScipy:
I, J, V = A_petsc.getValuesCSR()
return csr_matrix((V, J, I)).tocoo()
else:
return A_petsc
def readVec(filename, toNumpy=False):
viewer = PETSc.Viewer().createBinary(filename, mode='r', comm=PETSc.COMM_WORLD)
v_petsc = PETSc.Vec().create(comm=PETSc.COMM_WORLD)
v_petsc.setFromOptions()
v_petsc.load(viewer)
if toNumpy:
return np.array(v_petsc)
else:
return v_petsc
Почему
PETSC_COMM_SELF?