2016-02-14 7 views
0

Существует программа, которая умножает матрицу и вектор, используя MPJ Express. Матрица делится на строки. Но во время обработки возникает исключение. Что я делаю неправильно?Зачем возникает исключение в программе, использующей MPJ Express?

import java.util.Random; 

import mpi.Comm; 
import mpi.MPI; 

public class Main { 
    private static final int rootProcessorRank = 0; 
    private static Comm comunicator; 
    private static int processorsNumber; 
    private static int currentProcessorRank; 


    public static void main(String[] args) { 
     MPI.Init(args); 
     comunicator = MPI.COMM_WORLD; 
     currentProcessorRank = comunicator.Rank(); 
     processorsNumber = comunicator.Size(); 

     if (currentProcessorRank == rootProcessorRank) { 
      rootProcessorAction(); 
     } else { 
      notRootProcessorAction(); 
     } 

     MPI.Finalize(); 

    } 

    public static void rootProcessorAction() { 
     int[] matrixVectorSize = new int[] {5}; 
     int[][] matrix = createAndInitMatrix(matrixVectorSize[0]); 
     int[] vector = createAndInitVector(matrixVectorSize[0]); 

     for (int i = 1; i < processorsNumber; i++) { 
      comunicator.Isend(matrixVectorSize, 0, 1, MPI.INT, i, MPI.ANY_TAG); 
      System.out.println("Proc: " + currentProcessorRank + ", send matrixVectorSize"); 

      comunicator.Isend(vector, 0, vector.length, MPI.INT, i, MPI.ANY_TAG); 
      System.out.println("Proc: " + currentProcessorRank + ", send vector"); 
     } 

     int averageRowsPerProcessor = matrix.length/(processorsNumber - 1); 
     int[] rowsPerProcessor = new int[processorsNumber]; 
     int notDistributedRowsNumber = matrix.length; 
     for (int i = 1; i < rowsPerProcessor.length; i++) { 
      if (i == rowsPerProcessor.length - 1) { 
       rowsPerProcessor[i] = notDistributedRowsNumber; 
      } else { 
       rowsPerProcessor[i] = averageRowsPerProcessor; 
       notDistributedRowsNumber -= averageRowsPerProcessor; 
      } 
     } 

     int offset = 0; 
     // the processorRows[0] always will be '0' 
     for (int i = 1; i < rowsPerProcessor.length; i++) { 
      int[] processorRows = new int[1]; 
      processorRows[0] = rowsPerProcessor[i]; 
      comunicator.Isend(processorRows, 0, 1, MPI.INT, i, MPI.ANY_TAG); 
      comunicator.Isend(matrix, offset, processorRows[0], MPI.OBJECT, i, MPI.ANY_TAG); 
      offset += rowsPerProcessor[i]; 
     } 

     // there will be a code that receive a subRecults from all processes. 
    } 

    public static void notRootProcessorAction() { 
     int[] matrixVectorSize = new int[1]; 
     int[] rowsNumber = new int[1]; 
     int[] vector = null; 
     int[][] subMatrix = null; 

     comunicator.Probe(rootProcessorRank, MPI.ANY_SOURCE); 
     comunicator.Recv(matrixVectorSize, 0, 1, MPI.INT, rootProcessorRank, MPI.ANY_TAG); 
     System.out.println("Proc: " + currentProcessorRank + ", receive matrixVectorSize"); 

     vector = new int[matrixVectorSize[0]]; 
     comunicator.Probe(rootProcessorRank, MPI.ANY_SOURCE); 
     comunicator.Recv(vector, 0, vector.length, MPI.INT, rootProcessorRank, MPI.ANY_TAG); 
     System.out.println("Proc: " + currentProcessorRank + ", receive vector"); 

     comunicator.Probe(rootProcessorRank, MPI.ANY_SOURCE); 
     comunicator.Recv(rowsNumber, 0, 1, MPI.INT, rootProcessorRank, MPI.ANY_TAG); 
     System.out.println("Proc: " + currentProcessorRank + ", receive rowsNumber"); 
     subMatrix = new int[rowsNumber[0]][rowsNumber[0]]; 

     comunicator.Probe(rootProcessorRank, MPI.ANY_SOURCE); 
     comunicator.Recv(subMatrix, 0, subMatrix.length, MPI.OBJECT, rootProcessorRank, MPI.ANY_TAG); 
     System.out.println("Proc: " + currentProcessorRank + ", receive subMatrix"); 

     int[] result = new int[rowsNumber[0]]; 
     multiplyMatrixVector(subMatrix, vector, result); 

     comunicator.Send(result, 0, result.length, MPI.INT, rootProcessorRank, MPI.ANY_TAG); 
    } 

    private static void multiplyMatrixVector(int[][] matrix, int[] vector, int[] result) { 
     for (int i = 0; i < matrix.length; i++) { 
      int summ = 0; 
      for (int j = 0; j < matrix[i].length; j++) { 
       summ += matrix[i][j] * vector[j]; 
      } 
      result[i] = summ; 
     } 
    } 

    private static int[][] createAndInitMatrix(int size) { 
     int[][] matrix = new int[size][size]; 
     Random random = new Random(); 
     for (int i = 0; i < matrix.length; i++) { 
      for (int j = 0; j < matrix.length; j++) { 
       matrix[i][j] = random.nextInt(100); 
      } 
     } 
     return matrix; 
    } 

    private static int[] createAndInitVector(int size) { 
     int[] vector = new int[size]; 
     Random random = new Random(); 
     for (int i = 0; i < vector.length; i++) { 
      vector[i] = random.nextInt(100); 
     } 
     return vector; 
    } 
} 

Вот исключение:

MPJ Экспресс (0.44) запускается в конфигурации многоядерный java.lang.reflect.InvocationTargetException на sun.reflect.NativeMethodAccessorImpl.invoke0 (метод Native) на sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:57) на sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) в java.lang.reflect.Method.invoke (Method.java:6 06) на runtime.starter.MulticoreStarter $ 1.run (MulticoreStarter.java:281) на java.lang.Thread.run (Thread.java:745) Вызвано: mpi.MPIException: xdev.XDevException: java.lang .NullPointerException в mpi.Comm.isend (Comm.java:944) в mpi.Comm.Isend (Comm.java:885) в Main.rootProcessorAction (Main.java:35) в Main.main (Main.java: 20) ... 6 более Вызванный: xdev.XDevException: java.lang.NullPointerException на xdev.smpdev.SMPDevice.isend (SMPDevice.java:104) в mpjdev.javampjdev.Comm.isend (Comm.java : 1019) в mpi.Comm.isend (Comm.java:941) ... еще 9 Причина: java.lang.NullPointerException at xdev.smpdev.SMPDevice Impl $ SendQueue.add (SMPDeviceImpl.java:930) в xdev.smpdev.SMPDeviceImpl $ SendQueue.add (SMPDeviceImpl.java:909) в xdev.smpdev.SMPDeviceImpl.isend (SMPDeviceImpl.java:330) в xdev. smpdev.SMPDevice.isend (SMPDevice.java:101) ... 11 более xdev.XDevException: java.lang.NullPointerException на xdev.smpdev.SMPDevice.recv (SMPDevice.java:162)

+0

Исключение указателя NULL обычно связано с доступом к некоторой несуществующей части памяти ... являются ли данные непрерывными в вашем исходном коде? –

+0

Можете ли вы запустить простой мир приветствия MPJ? – Zulan

+0

На самом деле, я написал простую программу с использованием MPI. И он работает. –

ответ

1

В мой опыт работы с mpj express, старайтесь избегать использования констант MPI.ANY_SOURCE и MPI.ANY_TAG. Установите свой собственный тег и источник, и все должно быть в порядке. Когда я использовал эти константы в своей программе, иногда я получал случайные сбои с исключением xDev.xDevException, вызванным нулевым указателем, и иногда он работает нормально.

Вот список внутренних констант MPJ выражения не следует использовать в качестве тега Aswell, я показываю только константы, которые являются целыми числами:

public static final int mpi.MPI.NUM_OF_PROCESSORS = 4 
public static int mpi.MPI.UNDEFINED = -1 
public static int mpi.MPI.THREAD_SINGLE = 1 
public static int mpi.MPI.THREAD_FUNNELED = 2 
public static int mpi.MPI.THREAD_SERIALIZED = 3 
public static int mpi.MPI.THREAD_MULTIPLE = 4 
public static int mpi.MPI.ANY_SOURCE = -2 
public static int mpi.MPI.ANY_TAG = -2 
public static int mpi.MPI.PROC_NULL = -3 
public static int mpi.MPI.BSEND_OVERHEAD = 0 
public static int mpi.MPI.SEND_OVERHEAD = 0 
public static int mpi.MPI.RECV_OVERHEAD = 0 
public static final int mpi.MPI.IDENT = 0 
public static final int mpi.MPI.CONGRUENT = 3 
public static final int mpi.MPI.SIMILAR = 1 
public static final int mpi.MPI.UNEQUAL = 2 
public static int mpi.MPI.GRAPH = 1 
public static int mpi.MPI.CART = 2 
public static int mpi.MPI.TAG_UB = 0 
public static int mpi.MPI.HOST = 0 
public static int mpi.MPI.IO = 0 

веселит.

 Смежные вопросы

  • Нет связанных вопросов^_^