Научная статья на тему 'Matrix Manipulation Algorithms for Hasse Processor Implementation'

Matrix Manipulation Algorithms for Hasse Processor Implementation Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
86
66
i Надоели баннеры? Вы всегда можете отключить рекламу.
i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

The processor is implemented in software-hardware modules, which are based on the use of programming languages: C ++, Verilog, Python 2.7 and platforms: Microsoft Windows, X Window (in Unix and Linux) and Macintosh OS X. HDL-code generator makes it possible to automatically synthesize HDL-code of the processor structure from 1 to 16 bits for parallel processing corresponding number of input vectors or words.

Текст научной работы на тему «Matrix Manipulation Algorithms for Hasse Processor Implementation»

Matrix Manipulation Algorithms for Hasse Processor Implementation

Hahanov Vladimir, Dahiri Farid Kharkov National University of Radioelectronics, Ukraine

Abstract - The processor is implemented in software-hardware modules, which are based on the use of programming languages: C ++, Verilog, Python 2.7 and platforms: Microsoft Windows, X Window (in Unix and Linux) and Macintosh OS X. HDL-code generator makes it possible to automatically synthesize HDL-code of the processor structure from 1 to 16 bits for parallel processing corresponding number of input vectors or words.

matrix containing thousands of rows and columns requires a lot of time and money.

Horizontal partition of a matrix into submatrices is focused to divide the matrix M into a set of submatrices with a predetermined number of rows in accordance with the expression:

I. Introduction

The binary coverage consists of finding the minimum lines combination in a matrix to make full one-units coverage. This task is very simple and doesn’t require particular human effort for a small matrix. However this task becomes very difficult for a big matrix, for example considering a matrix of 1000 lines of 100 elements. In this case obviously we need a machine to do the job.

This paper will cover 2 methods that perform binary coverage with a reasonable speed performance for a matrix with up to 50000 x 50000 elements.

Those algorithms are coded in python for convenience reasons. This language is the optimal choice for algorithm prototyping. However, the final implementation of the algorithms will be coded in C++ for memory performance and multithreading.

where n=R/SR, M is the original matrix; R is number of rows; SR is number S of rows per sub-matrix; Mi is the derivative matrix, resulting from horizontal split; i represents index of the matrix. For example, the matrix М is:

1 2 3 4 5 6 7 8 9 10

1 0 0 0 0 0 0 1 1 1 1

2 1 0 1 0 0 0 0 1 1 1

3 1 0 1 0 0 0 0 0 0 0

4 1 1 1 1 1 0 0 0 0 0

5 0 0 0 0 1 0 0 1 0 0

6 1 0 0 1 1 1 1 1 1 0

7 0 0 0 0 0 1 1 1 1 0

8 1 1 1 1 1 0 0 0 0 0

9 1 1 1 1 0 0 0 1 1 1

10 0 0 0 0 0 1 1 1 1 1

II. Formation of the minimum coverage

FOR TWO-DIMENSIONAL MATRIX

2.1 Matrix to sub-matrices horizontal split

Solving practical problem for generating a binary coverage for unit matrix is to find the minimum combination of rows and columns, covering all unit values. Searching coverage for a small matrix is realized using simple techniques [1]. Searching binary coverage for a large

Manuscript received June 19, 2014.

Vladimir Hahanov is with the Kharkov National University of Radioelectronics, Computer Engineering Faculty, Kharkov, Ukraine, email: hahanov@kture.kharkov.ua

Farid Dahiri is with the Kharkov National University of Radioelectronics, Computer Engineering Faculty, Design Automation Department, Kharkov, Ukraine.

Applying the method with horizontal split parameter SR = 5 will result on 2 matrixes:

Matrix M1

1 2 3 4 5 6 7 8 9 10

1 0 0 0 0 0 0 1 1 1 1

2 1 0 1 0 0 0 0 1 1 1

3 1 0 1 0 0 0 0 0 0 0

4 1 1 1 1 1 0 0 0 0 0

5 0 0 0 0 1 0 0 1 0 0

Matrix M2

; 2 3 4 5 6 7 8 9 10

6 ; 0 0 ; ; ; ; ; ; 0

7 0 0 0 0 0 ; ; ; ; 0

8 ; ; ; ; ; 0 0 0 0 0

9 ; ; ; ; 0 0 0 ; ; ;

10 0 0 0 0 0 ; ; ; ; ;

m = {m;,m'2}

Applying this method we can considerably reduce binary coverage search time. In fact, when having two separate matrices M;’ and M2’, we can parallelize binary coverage search.

2.2. Matrix to sub-matrices horizontal vertical split

When solving the problem of binary coverage generation the most effective method is splitting M both horizontally and vertically into a set of submatrices with the specified number of rows and columns according to the expression:

M(R,C,Sr,Sc)= M[+aj+m}

j = C/CR ’

where C is number of matrix columns; CR is number C of columns per sub-matrix.

An example of horizontal-vertical partitioning of the matrix М when split-parameters have the following values Sr=5 и SC=5 is represented below:

Matrix М[л

; 2 3 4 5

; 0 0 0 0 0

2 ; 0 ; 0 0

3 ; 0 ; 0 0

4 ; ; ; ; ;

5 0 0 0 0 ;

Matrix М2Д

; 2 3 4 5

6 ; 0 0 ; ;

7 0 0 0 0 0

8 ; ; ; ; ;

9 ; ; ; ; 0

10 0 0 0 0 0

Matrix M2 2

6 7 8 9 10

; 0 ; ; ; ;

2 0 0 ; ; ;

3 0 0 0 0 0

4 0 0 0 0 0

5 0 0 ; 0 0

Matrix M12

6 7 8 9 10

6 1 1 1 1 0

7 1 1 1 1 0

8 0 0 0 0 0

9 0 0 1 1 1

10 1 1 1 1 1

Partition of the matrix into submatrices can significantly reduce the search time of a binary coverage due to parallel processing submatrices.

2.3. Python matrix representation

In Python [2-4] bi-dimensional arrays (matrices) are not implemented; thereby a matrix is represented by an array of arrays. The class that implements the array interface in Python is List, so a matrix is represented by a list of lists. Let’s consider the following matrix:

6 7 8 9 10

6 1 1 1 1 0

7 1 1 1 1 0

8 0 0 0 0 0

9 0 0 1 1 1

10 1 1 1 1 1

A simplified python representation of this matrix is shown in Listing ;.

Listing ;

matrix = [[1, 1, 1, 1, 0],

[1, ;, ;, ;, 0],

[0, 0, 0, 0, 0],

[0, 0, ;, ;, 1],

[i, ;, ;, ;, ;]]

In fact, a matrix is composed of a list of “Line” objects. A line object is a python matrix row representation. Bellow goes an example of matrix row and its python representation (Listing 2):

1 1 1 1 1

Listing 2 print line

index :0 indexes :[] values :[;, ;, ;, ;] ones count :[;, ;, ;, ;]

The “Line” class members with the unique constructor are represented in Listing 3:

Listing 3

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

class Line(object):

def___init__(self, index = 0, indexes = [], values = [],

ones_count = []):

self.index = index self.indexes = indexes self.values = values self.ones_count = ones_count if len(self.values) != len(self.ones_count): self.ones_count.extend(values)

end

Listing 4 involves some methods of the class Line:

Listing 4

class Line(object):

def ones_qnty(self): qnty = 0

for value in self.values: if value: qnty += 1 return qnty

def binary_or(self, line): before_ones_qnty = self.ones_qnty() for key, value in enumerate(line.values): self_value = self.values[key] self.values[key] = self_value | value self.ones_count[key] += value if self.ones_qnty() > before_ones_qnty: for index in line.indexes: self.indexes.append(index) self.indexes.append(line.index) return True return False

def binary_xor(self, line): for key, value in enumerate(line.values): self.ones_count[key] -= value if self.ones_count[key] <= 0: self.ones_count[key] = 0 self.values[key] = 0 else:

self.values[key] = 1 self.indexes.remove(line.index)

end

The method “ones_qnty” returns the quantity of one-unit in the line.

The method “binary_or” applies binary or transformation with the given line. A Boolean variable is returned:

- true if the binary or modified the line;

- false if the line was not modified.

The “ones_count” instance variable keeps ones count implied in binary or operation.

The method “binary_xor” performs a custom xor operation with a given line. For each element the “value” is subtracted from “ones_qnty”. If the “ones_qnty” is equal to zero, the value field of the concerned line is set to zero too, otherwise it is set to one-unit.

A matrix set is represented as a container, which simplifies the manipulation of complicated matrices (Listing 5).

Listing 5

class ComplexMatrix(object):

def___init__(self, matrices):

self.matrices = matrices

self.columns = len(self.matrices[0].lines)

self.rows = len(self.matrices) / self.columns

def matrixAtRowColumn(self, row, column): return self.matrices[row * self.columns + column]

2.4. Matrix to sub-matrices horizontal split

implementation

Software implementation of vertical-horizontal

partitioning matrix of arbitrary size into a set of submatrices with user-defined number of rows is shown in the Listing 6.

Listing 6

class MatrixUtils(object):

@staticmethod

def split_array(array, divisions):

return [array[i:i+divisions] for i in range(0, len(array), divisions)]

@staticmethod

def linearSplittedMatricesFromValues(matrix,

max_lines = 25):

splited_lines = MatrixUtils.split_array(matrix.lines, max_lines)

matrixes = []

for lines in splited_lines:

matrixes.append(Matrix(lines))

return matrixes

end

The method “split_matrix” splits a list into a set of lists by the following manner (Listing 7):

Listing 7

matrix_to_split = [[0, 0], [0, 1], [1, 1], [1, 0]]

matrices = split_array(matrix_to_split, 2)

>>>Print matrices

[[[0, 0], [0, 1]], [[1, 1], [1, 0]]]

Then the list is rearranged in order to obtain 2 matrices (Listing 8):

Listing 8 [[0, 0],

[0, 1]]

[[1, 1],

[1, 0]]

Matrix to sub-matrices horizontal vertical split implementation “ComplexMatrixFromValues” is a utility method; it returns a complex matrix from a set of matrices. The original matrix is split horizontally and vertically by calling the internal method

“rectSplitedMatricesFromValues” (Listing 9):

Listing 9

class MatrixUtils(object):

@staticmethod

def complexMatrixFromValues(values, horiz_max_lines = 10, vert_max_lines = 10):

matrices =

MatrixUtils.rectSplitedMatricesFromValues(values,

horiz_max_lines,

vert_max_lines)

return ComplexMatrix(matrices) end

The method “RectSplitedMatricesFromValues” returns a set of matrices (Listing 10):

Listing 10 @staticmethod

def rectSplitedMatricesFromValues(values,

horiz_max_lines = 10, vert_max_lines = 10): horiz_splitted_lines = [] for hrz_line in values:

print mat_index

matrices.append(Matrix(MatrixUtils.matrixLinesFromListV alues(val), mat_index))

mat_counter += 1

return matrices

2.5. Matrix’s binary coverage signature

The matrix’s binary coverage signature represents a high level optimization, particularly for horizontal-vertical split. This method is not yet implemented.

The idea is about representing a matrix by a hash unique to matrix one-unit quantity and repartition. The goal is to avoid recalculating binary coverage for a same matrix. Bellow follows matrix signature representation:

HLJ = {{R,C},{MLj}}

Matrix signature associated value:

horiz_splitted_lines.append(MatrixUtils.split_array(hrz_line , horiz_max_lines))

result = [] final_results = []

elements_count = len(horiz_splitted_lines[0]) print 'elements count: ' + str(elements_count)

for _ in range(elements_count): result.append([])

line_count = 0

for line in horiz_splitted_lines: element_count = 0 for element in line:

result[element_count].append(element) element_count += 1

line_count += 1

if (not (line_count % horiz_max_lines) and line_count):

final_results.append(result) result = []

for _ in range(elements_count): result.append([])

print 'result: ' + str(result) matrices = [] mat_counter = 0 for res in final_results: for val in res:

mat_index = [mat_counter / horiz_max_lines, mat_counter % vert_max_lines]

Let’s consider the following example:

1 2 3 4 5 6 7 8 9 10

1 0 0 0 0 0 0 1 1 1 1

2 1 0 1 0 0 0 0 1 1 1

3 1 0 1 0 0 0 0 0 0 0

4 1 1 1 1 1 0 0 0 0 0

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

5 0 0 0 0 1 0 0 1 0 0

6 0 0 0 0 0 0 1 1 1 1

7 1 0 1 0 0 0 0 1 1 1

8 1 0 1 0 0 0 0 0 0 0

9 1 1 1 1 1 0 0 0 0 0

10 0 0 0 0 1 0 0 1 0 0

Applying the method with horizontal split parameter Sr=5 and vertical split parameter SC=5 will result on 4 matrices:

Matrix М[л

1 2 3 4 5

1 0 0 0 0 0

2 1 0 1 0 0

3 1 0 1 0 0

4 1 1 1 1 1

5 0 0 0 0 1

Matrix M 2i i

1 2 3 4 5

6 0 0 0 0 0

7 1 0 1 0 0

8 1 0 1 0 0

9 1 1 1 1 1

10 0 0 0 0 1

Matrix M i 2

6 7 8 9 10

1 0 1 1 1 1

2 0 0 1 1 1

3 0 0 0 0 0

4 0 0 0 0 0

5 0 0 1 0 0

Matrix M 2i i

6 7 8 9 10

6 0 1 1 1 1

7 0 0 1 1 1

8 0 0 0 0 0

9 0 0 0 0 0

10 0 0 1 0 0

Now we are going to calculate the hash for each matrix:

MatrixUtils.rectSplitedMatricesFromValues(test_table_4, 5,

Н{д = {{5,5), {0000010100101001111100001)} Н{д = {{5,5}, {0111100111000000000000100}} Hii = {{5,5}, {0000010100101001111100001}} Hi,2 = {{5,5}, {0111100111000000000000100}}

The values for those hashes:

V{,! = {{4}, {11111}} V{,2 = {{!}. {01111}} %,i= {{9}, {ШИ}} V2,2={{6}-{01111}}

The hashes Н{д. H{2 are respectively equal to Нзд, Нт.,2- This means that if we already know the binary coverage of M{ д we can deduce the binary coverage result of д by simply calculating it’s hash.

2.6. Methods comparison

Both methods goals are to parallelize binary coverage. The horizontal split is simple to realize. However, it does not consider the matrix columns count. For large matrices, where the columns count is considerably bigger than the rows count, this method can create time overhead because of linear complexity of binary coverage method.

The horizontal-vertical method is much harder to realize and the time to split the matrix into sub-matrices is considerably higher than for simple horizontal split. Also should be considered the time for reconstructing the matrices into the original matrix because of vertical split. The advantage of this method is high parallelizing. In fact, a large matrix can be split into matrices with smaller columns number. Moreover, a custom logic can be realized in order to processes particular matrices to speed up the coverage.

Profile test for both methods is presented in Listing 11, the result - in Listing 12.

Listing 11

Ml

Created on 17.04.2013

@author:_________

Ml

from models.matrix_utils import MatrixUtils from test_main import test_table_4 import cProfile

def linear_split_test(): for _ in range(100):

MatrixUtils.linearSplittedMatricesFromValues(test_table_4,

5)

def rect_split_test(): for _ in range(100):

5)

if name == ' main ':

cProfile.run('rect_split_test()')

cProfile.run('linear_split_test()')

Listing 12

306104 function calls in 1.576 seconds Ordered by: standard name

ncalls tottime percall cumtime percall

filename:lineno(function)

1 0.000 0.000 1.576 1.576 <string>:1(<module>)

56000 0.281 0.000 0.399 0.000 line.py:9(__init__)

1 0.051 0.051 1.576 1.576 main.py:17(rect_split_test) 11200 0.029 0.000 0.029 0.000 matrix.py:11(__init__) 8100 0.078 0.000 0.112 0.000

matrix_utils.py:15(split_array)

100 0.300 0.003 1.525 0.015

matrix_utils.py:43(rectSplitedMatricesFromValues)

11200 0.404 0.000 0.910 0.000

matrix_utils.py:83(matrixLinesFromListValues)

8200 0.015 0.000 0.015 0.000 {len}

145500 0.276 0.000 0.276 0.000 {method

'append' of 'list' objects}

1 0.000 0.000 0.000 0.000 {method 'disable' of

'_lsprof.Profiler' objects}

56000 0.118 0.000 0.118 0.000 {method 'extend'

of 'list' objects}

9801 0.023 0.000 0.023 0.000 {range}

188604 function calls in 1.069 seconds

Ordered by: standard name

ncalls tottime percall cumtime percall filename:lineno(function)

1 0.000 0.000 1.069 1.069 <string>:1(<module>)

8100 0.035 0.000 0.054 0.000 line.py:9(__init__) 1 0.047 0.047 1.069 1.069

main.py:12(linear_split_test)

81950 0.256 0.000 0.256 0.000

matrix.py:11(___init__)

100 0.059 0.001 0.062 0.001

matrix_utils.py:15(split_array)

100 0.430 0.004 1.022 0.010

matrix_utils.py:31(linearSplittedMatricesFromValues)

100 0.053 0.001 0.124 0.001

matrix_utils.py :93(matrixFromListValues)

100 0.000 0.000 0.000 0.000 {len}

89950 0.167 0.000 0.167 0.000 {method 'append'

of 'list' objects}

1 0.000 0.000 0.000 0.000 {method 'disable' of

'_lsprof.Profiler' objects}

8100 0.019 0.000 0.019 0.000 {method 'extend'

of 'list' objects}

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

101 0.002 0.000 0.002 0.000 {range}

The linear method splits the original matrix on 17 submatrices. The rect-split method splits the matrix into 112 matrices but is 50% slower.

III. Matrix binary coverage algorithms

3.1 Binary OR for first line algorithm

We take the first matrix line which contains at least 1 one-unit and apply binary or operation with the rest of the lines. If the first line is full of zeros (contains only zeros), we skip it and iterate to the next line. The operation is repeated until a non empty line is found. If the 5 lines of the sub-matrix are full of zeros, the entire sub-matrix is skipped and will not participate in further calculations. Each time we apply oR, we check if the operation changed the line, if yes we keep the result line and save the indexes of both lines.

For example, let us consider the following matrices M1, М2, and М3.

Matrix М1:

1 2 3 4 5

1 0 0 0 0 0

2 0 0 0 0 0

3 0 1 0 0 0

4 0 1 0 0 0

5 0 0 1 0 0

11 empty -> 11 skipped

12 empty -> 12 skipped

I3nuI4 -> I3n = 01000 -» 14 rejected

13 и/5 -» I31 saved

We have skipped {l1,l2} because they contain only zeros. Those lines are empty.

Matrix М2:

1 2 3 4 5

1 0 1 0 0 1

2 0 0 0 0 0

3 1 1 0 0 0

4 0 0 1 1 0

5 1 1 0 0 0

11 и 12 — Ii1] = 01001 not changed -» 12 rejected

Iin и 13 -» Ii1 = 11001 changed -» 13 saved

h1 и 14 -s- h3 = 11111 changed - 14 saved

Matrix М3:

1 2 3 4 5

1 0 0 0 0 0

2 0 0 0 0 0

3 0 0 0 0 0

4 0 0 0 0 0

5 0 0 0 0 0

11 empty -s

12 empty -»

13 empty -»

14 empty -»

15 empty -»

11 skipped

12 skipped

13 skipped

14 skipped

15 skipped

Each oR operation we check if the binary coverage for 1 is full, in other words if the resulting line is full of one-units. At state l12 the line is full of one-units we no more perform OR operation. Let’s make it clear with the following example:

Matrix М4:

1 2 3 4 5 6 7 8 9 10

1 0 1 0 1 0 0 0 0 0 0

2 1 0 0 1 0 0 0 0 0 0

3 0 0 0 0 1 0 0 0 0 0

4 1 1 1 1 1 0 0 0 0 0

5 0 0 1 0 0 0 0 0 0 0

6 0 0 0 0 0 0 1 0 1 1

7 1 0 0 0 1 1 0 1 0 0

8 0 0 0 0 0 0 0 0 0 0

9 0 0 0 0 0 0 0 0 0 0

10 0 0 0 0 0 0 0 0 0 0

II и 12 -It1 = 1101000000

11‘и13 It3 = 1101100000

Ii=ul4 Ii3 = 1101100000

It3 и IS It3 = 1111100000

Iia и 16 -» h*= 1111101011

114 и 17 -» Ii5= 1111111111

115 = {II, 12,13, IS, 16,17}

-» 12 sailed -» 13 saved —14 rejected - IS saved —16 saved -17 saved

3.2 Binary OR for first line with reverse algorithm This method consists of 3 steps:

1. First the matrix lines are sorted by one-units quantity descending. consider the following example of the matrix М1:

1 2 3 4 5 6 7 8 9 10

1 1 1 0 0 0 0 0 0 0 0

2 0 0 1 1 0 0 0 0 0 0

3 0 0 0 0 1 1 0 0 0 0

4 0 1 0 0 0 0 1 0 0 0

5 0 0 0 0 0 0 1 1 1 1

6 0 0 0 0 0 0 0 0 0 0

7 0 0 0 0 0 0 0 0 0 0

8 0 0 0 0 0 0 0 0 0 0

9 0 0 0 0 0 0 0 0 0 0

10 0 0 0 0 0 0 0 0 0 0

Bellow the sorted matrix Mjs:

1 2 3 4 5 6 7 8 9 10

5 0 0 0 0 0 0 1 1 1 1

2 0 0 1 1 0 0 0 0 0 0

3 0 0 0 0 1 1 0 0 0 0

4 0 1 0 0 0 0 1 0 0 0

1 1 1 0 0 0 0 0 0 0 0

6 0 0 0 0 0 0 0 0 0 0

7 0 0 0 0 0 0 0 0 0 0

8 0 0 0 0 0 0 0 0 0 0

9 0 0 0 0 0 0 0 0 0 0

10 0 0 0 0 0 0 0 0 0 0

2. Then we perform binary or for first line until we reach full coverage or the end of the matrix (if we reach the last line without full coverage the calculation is stopped):

IsuI2 -Is1 = 0011001111 - 12 saved Is1 и 13 - Is= = 0011111111 - 13 saved Is=uI4 - Is3 = 0111111111 -14 saved Is3ull - Is* = 1111111111 -II saved Is* = {15,12,13,14,11}

3. After that we begin deleting one line from /54each time. The lines are deleted starting from the penultimate line. Each time a line is deleted, we check if the binary coverage is still total. It is important to note that the algorithm is applied recursively. We can optimize binary coverage by deleting redundant lines. The following example demonstrates that fact:

IsuI2 — Is1 = 0011001111 — 12 saved

Is1 и 13 - Is= = 0011111111 - 13 saved

Is3 и 14 - Is3 = 0111111111 -14 saved (line to delete)

Is3ull - Is* = 1111111111 -II saved

Is* = {15,12,13,14,11}

15 и 12 -IS1 =0011001111 -» 12 saveddine to delete) Is1 и 13 Is3 = 0011111111 13 saved

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

Is3ull - Is* = 1111111111 - II saved Is* = {15,13,11}

The result is represented below:

Is1uI3 -> Is3 = 0000001111 -> 13 saved Is3ull -» Is* = 1111001111 - II saved Is* = {15,11}

Deleting the row l2 makes the binary coverage not full. The row l2 cannot be deleted.

3.3 Binary OR for first line algorithm implementation

The following method implements the binary or for first line algorithm. First, a primary line is chosen. The primary contains must not be full of zeros (empty line). If the matrix contains only empty lines, the entire matrix is skipped and an empty line is returned (Listing 13).

Listing 13

class Matrix(object):

The result is represented below:

Is и 12 -Is1 = 0011001111 - 12 saved Is1 и 13 - Is3 = 0011111111 - 13 saved Is3ull - Is* = 1111111111 -II saved Is* = {15,12,13,11}

def binary_or_for_first_line_with_full_check(self): if not len(self.lines): return Line()

first_line = self.lines[0].deepcopy() iter_lines = iter(self.lines) next(iter_lines)

The binary coverage without row l4 is still total, l4 will be excluded from the final coverage. The row l4 is marked as primary redundant. Now, when we have found one redundant line, we begin applying this algorithm recursively, until we delete all redundant lines (rows). After there is no more redundant rows for the primary row l4, the same algorithm is applied for the next primary row. In this case the next primary row is l3. After the algorithm applied for all primary rows, the quantity of redundant rows is compared and the best result is considered.

Applying the algorithm for primary row l3:

15 и 12 -Is1 = 0011001111 - 12 saved Is1uI3 - Is3 = 0011111111 - 13 saved(lineto delete) Is3ull - Is* = 1111111111 -II saved Is* = {15,12,13,11}

try:

passedLoop = False while first_line.is_full_of_zeros(): first_line = next(iter_lines) passedLoop = True if passedLoop:

first_line = first_line.deepcopy() except StopIteration: return first_line

for line in iter_lines: first_line .binary_or(line) if first_line.is_full_of_ones(): break

return first_line

The result is represented below:

end

15 и 12 —Is1 = 0011001111 — 12 saved 3.4 Binary OR for first line with reverse algorithm

Is1 и 13 - Is3 = 0011111111 - 13 saved{line to delete) implementation

Is3 и II - Is* = 1111111111 -II saved Is* = {15,12,13,11}

Deleting the row l3 makes the binary coverage not full. The row l3 cannot be deleted.

Applying for row l2:

The static method “applyMatrixRecurtion” from “Algorithm” class takes as argument a matrix object of type “Matrix”. The returned value is a list of lines objects of type “Line” (Listing 14).

Listing 14

class Algorithm(object):

@staticmethod

def applyMatrixRecurtion(matrix): matrix.sort_by_ones_qnty() matrix.updateLinesMapping()

return matrix.binary_full_check_reverse()

end

Matrix class implements the algorithm (Listing 15). Listing 15

class Matrix(object):

def binary_full_check_reverse(self): line =

self.binary_or_for_first_line_with_full_check() result_lines = []

for value in line.indexes: newLine = line.deepcopy() newLine.binary_xor(self.lineForIndex(value)) result_lines.append(newLine)

return result_lines

end

Bellow follows an example of input matrix and output values.

Input matrix is represented in Listing 16.

Listing 16 test_table = [

[0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], #0

[0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #1

[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], #2

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #3

[0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #4

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], #5

[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #6

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #7

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], #8

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #9

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], #10

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #11

[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], #12

[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], #13

[0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], #14

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], #15

[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #16

[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #17

[0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], #18

]

Listing 17

if __name__ == '__main__':

lines = Algorithm.applyMatrixRecurtion( MatrixUtils.matrixFromListValues(test_table)) for line in lines: print line

And finally the output (Listing 18):

Listing 18 index :0

indexes :[18, 1, 14, 2, 12, 13, 6, 8, 10, 15, 17] values :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ones count :[1, 3, 3, 2, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1] index :0

indexes :[1, 14, 2, 12, 13, 6, 8, 10, 15, 17]

values :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0]

ones count :[1, 2, 3, 1, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 0, 0] index :0

indexes :[18, 14, 2, 12, 13, 6, 8, 10, 15, 17] values :[1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ones count :[1, 3, 3, 2, 2, 3, 0, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1] index :0

indexes :[18, 1, 2, 12, 13, 6, 8, 10, 15, 17]

values :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

ones count :[1, 2, 3, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] index :0

indexes :[18, 1, 14, 12, 13, 6, 8, 10, 15, 17]

values :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1]

ones count :[1, 3, 2, 2, 3, 3, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 1] index :0

indexes :[18, 1, 14, 2, 13, 6, 8, 10, 15, 17]

values :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1]

ones count :[1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 0, 1, 1, 1, 1] index :0

indexes :[18, 1, 14, 2, 12, 6, 8, 10, 15, 17]

values :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]

ones count :[1, 3, 2, 2, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1] index :0

indexes :[18, 1, 14, 2, 12, 13, 8, 10, 15, 17]

values :[1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

ones count :[1, 3, 3, 2, 3, 3, 1, 0, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1] index :0

indexes :[18, 1, 14, 2, 12, 13, 6, 10, 15, 17]

values :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1]

ones count :[1, 3, 3, 2, 3, 3, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 1] index :0

indexes :[18, 1, 14, 2, 12, 13, 6, 8, 15, 17] values :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1] ones count :[1, 3, 3, 2, 3, 3, 1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 1, 1] index :0

indexes :[18, 1, 14, 2, 12, 13, 6, 8, 10, 17] values :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1] ones count :[1, 3, 3, 2, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, 1, 1, 1] index :0

indexes :[18, 1, 14, 2, 12, 13, 6, 8, 10, 15]

values :[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

ones count :[0, 3, 3, 2, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1]

Now goes the call that generates the output (Listing 17).

3.5 Methods comparison

Methods called to profile algorithms performance (Listing 19):

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

Listing 19 def recurtion_test(): for _ in range(100):

Algorithm.applyMatrixRecurtion(MatrixUtils.matrixFromL

istValues(test_table))

def first_line_or_test(): for _ in range(100):

Algorithm.applyMatrixFirstLineOR(MatrixUtils.matrixFro

mListValues(test_table))

if __name__ == '__main__':

cProfile.run('first_line_or_test()')

cProfile.run('recurtion_test()')

Profile results for first line or test are represented in Listing 20.

Listing 20

21105 function calls in 0.146 seconds Ordered by: standard name

ncalls tottime percall cumtime percall filename:lineno(function)

1 0.000 0.000 0.146 0.146 <string>:1(<module>)

100 0.001 0.000 0.103 0.001

algorithm.py: 15(applyMatrixFirstLineOR)

5500 0.026 0.000 0.026 0.000

line.py:19(ones qnty)

1800 0.011 0.000 0.021 0.000

line.py:29(is_full_of_ones)

100 0.001 0.000 0.001 0.000

line.py:34(is_full_of_zeros)

1800 0.041 0.000 0.063 0.000

line.py:39(binary or)

100 0.002 0.000 0.005 0.000

line.py:78(deepcopy)

2000 0.014 0.000 0.022 0 .000 line.py:9( _init__)

1 0.002 0.002 0.146 " 0.146

main.py:27(first_line_or_test)

100 0.000 0.000 0.000 0.000

matrix.py:11( init__)

100 0.011 0.000 0.102 0.001

matrix.py:73(binary or for_first_line_with_full_check)

100 0.017 0.000 0.042 0.000

matrix_utils.py :93(matrixFromListValues)

100 0.000 0.000 0.000 0.000 {iter}

5900 0.012 0.000 0.012 0.000 {len}

3000 0.006 0.000 0.006 0.000 {method 'append'

of 'list' objects}

1 0.000 0.000 0.000 0.000 {method 'disable' of

'_lsprof.Profiler' objects}

301 0.002 0.000 0.002 0.000 {method 'extend' of

'list' objects}

100 0.000 0.000 0.000 0.000 {next}

1 0.000 0.000 0.000 0.000 {range}

Profile results for recursion method are represented in Listing 21.

Listing 21

596943 function calls in 3.720 seconds

Ordered by: standard name

ncalls tottime percall cumtime percall

filename:lineno(function)

1 0.000 0.000 3.720 3.720 <string>:1(<module>)

100 0.002 0.000 3.678 0.037

algorithm.py:52(applyMatrixRecurtion)

341792 1.177 0.000 1.177 0.000

line.py :19(ones_qnty)

41000 0.257 0.000 0.493 0.000

line.py:29(is_full_of_ones)

100 0.000 0.000 0.001 0.000 line.py:34(is_full_of_zeros)

41000 0.845 0.000 1.160 0.000

line.py:39(binary or)

1100 0.021 0.000 0.024 0.000

line.py:57(binary xor)

1200 0.020 0.000 0.043 0.000

line.py:78(deepcopy)

3100 0.024 0.000 0.036 0.000 line.py:9(_ _init__)

1 0.003 0.003 3.720 3.720

main.py:23(recurtion_test)

100 0.012 0.000 1.949 0.019

matrix.py:102(binary_full_check_reverse)

100 0.000 0.000 0.000 0.000

matrix.py:11( init )

100 0.005 0.000 1.688 0.017

matrix.py:18(sort by ones _qnty)

100 0.039 0.000 0.039 0.000

matrix.py:39(updateLinesMapping)

1100 0.003 0.000 0.003 0.000

matrix. py:45(lineForIndex)

100 0.210 0.002 1.869 0.019

matrix.py:73(binary_or_for_first_line_with_full_check) 109346 0.720 0.000 1.426 0.000

matrix_utils.py:110(reverseLines)

100 0.013 0.000 0.038 0.000

matrix_utils.py: 93 (matrixFromListValues)

100 0.000 0.000 0.000 0.000 {iter}

47300 0.089 0.000 0.089 0.000 {len}

4200 0.009 0.000 0.009 0.000 {method 'append'

of 'list' objects}

1 0.000 0.000 0.000 0.000 {method 'disable' of

'_lsprof.Profiler' objects}

3601 0.008 0.000 0.008 0.000 {method 'extend'

of 'list' objects}

1100 0.003 0.000 0.003 0.000 {method 'remove'

of 'list' objects}

100 0.257 0.003 1.683 0.017 {method 'sort' of

'list' objects}

100 0.000 0.000 0.000 0.000 {next}

1 0.000 0.000 0.000 0.000 {range}

The second method is much slower, however more accurate because of binary xor recursion. Both methods are still subjects to optimization.

III Conclusion

The processor is implemented in software-hardware modules, which are based on the use of programming languages: C++, Verilog, Python 2.7 and platforms: Microsoft Windows, X Window (in Unix and Linux) and Macintosh OS X. HDL-code generator makes it possible to automatically synthesize HDL-code of the processor structure from 1 to 16 bits for parallel processing corresponding number of input vectors or words.

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

Verification of HDL-processor code is executed on test examples of coverage problem using two optimization strategies: reversible algorithm to eliminate redundancy and partitioning the coverage matrix for the purpose of further parallel processing by Hasse processors.

The performance of the proposed two methods depends on the distribution of unit elements in the matrix; this information is important for large matrices. However, most of this information is not available. In this case, both the approaches can be used for logic optimization and increase the speed of the second method.

The best solution is a combination of two proposed methods: sorting matrix and its subsequent partitioning into submatrices; use of reverse algorithm of recursive method for submatrices containing more than one unit element, and a simple horizontal partitioning algorithm for the rest of the matrix; going to step 2 of the first recursive method.

References

[1] Gorbatov V.A. Fundamentals of Discrete Mathematics / V.A. Gorbatov.- М.: Vysshaya Shkola.- 1986. - 311 p.

[2] http://www.python.org/

[3] http://www.eclipse.org/

[4] http://pydev.org/

i Надоели баннеры? Вы всегда можете отключить рекламу.