tsoding / nn.h

Simple stb-style header-only library for Neural Networks

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MPI

opened this issue · comments

The old one.

Implementation is the realization of an application, execution of a plan, idea, model, design, specification, standard, algorithm, policy, or the administration or management of a process or objective.

When a new system needs to be implemented in an organization, there are three different ways to adopt this new system: the big bang adoption, phased adoption and parallel adoption. In case of parallel adoption the old and the new system are running parallel, so all the users can get used to the new system, and meanwhile do their work using the old system. Phased adoption means that the adoption will happen in several phases, so after each phase the system is a little nearer to be fully adopted. With the big bang adoption, the switch between using the old system and using the new system happens at one single date, the so-called instant changeover of the system. Everybody starts to use the new system at the same date and the old system will not be used anymore from that moment on.

Once the management has decided to use the big bang method, and supports the changes which are needed for this, the real changing process can start. This process comprises several steps: converting the system, releasing parts of the system and training the future users.[1]

The activities in the process are explained in the table below, to state them clearly. The concepts that are used to execute the activities are in capitals.

Activity Subactivity Description
Prepare management (see Adoption) Determine organizational changes The process of determining the changes that will have to take place to make the big bang possible that results in a report of organizational changes
Agree on organizational changes To be able to introduce the big bang, there has to be agreement about the change-plan which results in an agreement contract. If there's no agreement a new agreement meetings are necessary or the changes need to be determined different again and again, until an agreement contract is created.
Convert system Make planning for future users Create a plan for the people who will have to deal with the new system, so they have an overview of the events that are going to happen[1]
Convert data from old system Convert data from the old system so it can be used in the new system (Koop, Rooimans and de Theye, 2003)
Load data into new system Load data the converted data into the new system[1]
Test data in new system Test data so it'll be known whether if the data will be usable in the new system[1]
Execute offline trials Execute trial with the system and with the users of the system to check whether if the system will work correct[1]
Check to verify validity Checking validity so the system can be made ready to become released (Koop, Rooimans and de Theye, 2003)
Release parts Release converted database Release the new database which is converted from the old database[1]
Release produced application Release the application which is produced for the staff[1]
Release infrastructure Release the new infrastructure[1]
Prepare users Maintain buffer of experienced staff Create a buffer of staff who can take over the duties of the people who have to be trained in using the new system, so the daily work can go on[1]
Train users Train users in preparation for the big release of the system, to create a list of trained users

HPL

HPL is a portable implementation of HPLinpack that was written in C, originally as a guideline, but that is now widely used to provide data for the TOP500 list, though other technologies and packages can be used. HPL generates a linear system of equations of order n and solves it using LU decomposition with partial row pivoting. It requires installed implementations of MPI and either BLAS or VSIPL to run.[13]

Coarsely, the algorithm has the following characteristics:[14][15]

cyclic data distribution in 2D blocks
LU factorization using the right-looking variant with various depths of look-ahead
recursive panel factorization
six different panel broadcasting variants
bandwidth reducing swap-broadcast algorithm
backward substitution with look-ahead of depth 1

import random as rd
import copy

class Graph:
    def __init__(self):
        self.adjacency_dict = {}
        self.visited = {}

    def add_vertex(self, vertex_id):
        self.adjacency_dict.setdefault(vertex_id, {})
        self.visited[vertex_id] = 0

    def add_edge(self, start_vertex, end_vertex, weight):
        self.add_vertex(start_vertex)
        self.add_vertex(end_vertex)
        self.adjacency_dict[start_vertex][end_vertex] = weight

    def get_adjacent_vertices(self, vertex_id):
        return list(self.adjacency_dict.get(vertex_id, {}).keys())

    def get_vertex_weight(self, start_vertex, end_vertex):
        return self.adjacency_dict.get(start_vertex, {}).get(end_vertex, None)

    def get_all_vertices(self):
        return list(self.adjacency_dict.keys())

    def get_incoming_vertices(self, vertex_id):
        return [vertex for vertex in self.get_all_vertices() if vertex_id in self.get_adjacent_vertices(vertex)]

    def get_vertex_degree(self, vertex_id):
        return len(self.get_adjacent_vertices(vertex_id))

    def mark_visited(self, vertex_id):
        self.visited[vertex_id] = 1

    def is_visited(self, vertex_id):
        return self.visited.get(vertex_id, 0)

    def clear_visited(self, vertex_id=None):
        if vertex_id is None:
            for key in self.visited:
                self.visited[key] = 0
        else:
            self.visited[vertex_id] = 0

    def remove_vertex(self, vertex_id):
        if vertex_id in self.adjacency_dict:
            del self.adjacency_dict[vertex_id]
            del self.visited[vertex_id]
            for key in self.adjacency_dict:
                self.adjacency_dict[key].pop(vertex_id, None)

    def remove_edge(self, start_vertex, end_vertex):
        if start_vertex in self.adjacency_dict and end_vertex in self.adjacency_dict[start_vertex]:
            del self.adjacency_dict[start_vertex][end_vertex]

    def get_adjacency_matrix(self):
        vertices = self.get_all_vertices()
        size = len(vertices)
        matrix = np.zeros((size, size), dtype=int)

        for i, vertex in enumerate(vertices):
            for adjacent_vertex in self.get_adjacent_vertices(vertex):
                j = vertices.index(adjacent_vertex)
                matrix[i, j] = 1

        return matrix


# Demonstration and performance evaluation
if __name__ == "__main__":
    # Create a graph
    g = Graph()
    g.add_edge("A", "B", 1)
    g.add_edge("A", "C", 2)
    g.add_edge("B", "C", 3)
    g.add_edge("C", "D", 4)
    g.add_vertex("E")

    # Display vertices and edges
    print("Vertices:", g.get_all_vertices())
    print("Edges:")
    for vertex in g.get_all_vertices():
        print(f"{vertex} -> {g.get_adjacent_vertices(vertex)}")

    # Test adjacency matrix
    adjacency_matrix = g.get_adjacency_matrix()
    print("Adjacency Matrix:")
    print(adjacency_matrix)

    # Performance evaluation: Remove a vertex and its edges
    import timeit

    def remove_vertex_performance():
        g_copy = copy.deepcopy(g)
        g_copy.remove_vertex("C")

    remove_vertex_time = timeit.timeit(remove_vertex_performance, number=10000)
    print(f"Time taken to remove a vertex and its edges (10000 times): {remove_vertex_time} seconds")

    # Performance evaluation: Add edges
    def add_edge_performance():
        g_copy = copy.deepcopy(g)
        g_copy.add_edge("A", "E", 5)

    add_edge_time = timeit.timeit(add_edge_performance, number=10000)
    print(f"Time taken to add an edge (10000 times): {add_edge_time} seconds")