예제 #1
0
    def _select_sparse_matrix_format(self, proj):
        """
        The sparse matrix format determines the fundamental structure for
        connectivity representation. It depends on the model type as well
        as hardware paradigm.

        Returns (str1, str2, bool):

            * str1:     sparse matrix format declaration
            * str2:     sparse matrix format arguments if needed (e. g. sizes)
            * bool:     if the matrix is a complete (True) or sliced matrix (False)
        """
        if Global.config["structural_plasticity"] and proj._storage_format != "lil":
            raise Global.InvalidConfiguration("Structural plasticity is only allowed for LIL format.")

        # get preferred index type
        idx_type, _, size_type, _ = determine_idx_type_for_projection(proj)

        # ANNarchy supports a list of different formats to encode projections.
        # The general structure of the decision tree is:
        #
        # - rate-coded
        #     - formats
        #         - paradigm
        # - spike
        #     - formats
        #         - ordering
        #             - paradigm
        if proj.synapse_type.type == "rate":
            # Sanity check
            if proj._storage_order == "pre_to_post":
                Global.CodeGeneratorException("    The storage_order 'pre_to_post' is invalid for rate-coded synapses (Projection: "+proj.name+")")

            # Check for the provided format + paradigm combination if a suitable implementation is available.
            if proj._storage_format == "lil":
                if Global._check_paradigm("openmp"):
                    if Global.config['num_threads'] == 1:
                        sparse_matrix_format = "LILMatrix<"+idx_type+", "+size_type+">"
                        sparse_matrix_include = "#include \"LILMatrix.hpp\"\n"
                        single_matrix = True
                    else:
                        if proj._no_split_matrix:
                            sparse_matrix_format = "LILMatrix<"+idx_type+", "+size_type+">"
                            sparse_matrix_include = "#include \"LILMatrix.hpp\"\n"
                            single_matrix = True
                        else:
                            sparse_matrix_format = "PartitionedMatrix< LILMatrix<"+idx_type+", "+size_type+">, "+idx_type+", "+size_type+">"
                            sparse_matrix_include = "#include \"PartitionedMatrix.hpp\"\n#include \"LILMatrix.hpp\"\n"
                            single_matrix = False
                else:
                    Global.CodeGeneratorException("    No implementation assigned for rate-coded synapses using LIL and paradigm="+str(Global.config['paradigm'])+" (Projection: "+proj.name+")")

            elif proj._storage_format == "coo":
                if Global._check_paradigm("openmp"):
                    sparse_matrix_format = "COOMatrix<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"COOMatrix.hpp\"\n"
                    single_matrix = True

                elif Global._check_paradigm("cuda"):
                    sparse_matrix_format = "COOMatrixCUDA<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"COOMatrixCUDA.hpp\"\n"
                    single_matrix = True

                else:
                    Global.CodeGeneratorException("    No implementation assigned for rate-coded synapses using COO and paradigm="+str(Global.config['paradigm'])+" (Projection: "+proj.name+")")

            elif proj._storage_format == "bsr":
                if Global._check_paradigm("openmp"):
                    sparse_matrix_format = "BSRMatrix<"+idx_type+", "+size_type+", true>"
                    sparse_matrix_include = "#include \"BSRMatrix.hpp\"\n"
                    single_matrix = True

                elif Global._check_paradigm("cuda"):
                    sparse_matrix_format = "BSRMatrixCUDA<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"BSRMatrixCUDA.hpp\"\n"
                    single_matrix = True

                else:
                    Global.CodeGeneratorException("    No implementation assigned for rate-coded synapses using BSR and paradigm="+str(Global.config['paradigm'])+" (Projection: "+proj.name+")")

            elif proj._storage_format == "csr":
                if Global._check_paradigm("openmp"):
                    sparse_matrix_format = "CSRMatrix<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"CSRMatrix.hpp\"\n"
                    single_matrix = True

                elif Global._check_paradigm("cuda"):
                    sparse_matrix_format = "CSRMatrixCUDA<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"CSRMatrixCUDA.hpp\"\n"
                    single_matrix = True
                
                else:
                    Global.CodeGeneratorException("    No implementation assigned for rate-coded synapses using CSR and paradigm="+str(Global.config['paradigm'])+" (Projection: "+proj.name+")")

            elif proj._storage_format == "ellr":
                if Global._check_paradigm("openmp"):
                    sparse_matrix_format = "ELLRMatrix<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"ELLRMatrix.hpp\"\n"
                    single_matrix = True

                elif Global._check_paradigm("cuda"):
                    sparse_matrix_format = "ELLRMatrixCUDA<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"ELLRMatrixCUDA.hpp\"\n"
                    single_matrix = True

                else:
                    Global.CodeGeneratorException("    No implementation assigned for rate-coded synapses using ELLPACK-R and paradigm="+str(Global.config['paradigm'])+" (Projection: "+proj.name+")")

            elif proj._storage_format == "ell":
                if Global._check_paradigm("openmp"):
                    sparse_matrix_format = "ELLMatrix<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"ELLMatrix.hpp\"\n"
                    single_matrix = True

                elif Global._check_paradigm("cuda"):
                    sparse_matrix_format = "ELLMatrixCUDA<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"ELLMatrixCUDA.hpp\"\n"
                    single_matrix = True

                else:
                    Global.CodeGeneratorException("    No implementation assigned for rate-coded synapses using ELLPACK and paradigm="+str(Global.config['paradigm'])+" (Projection: "+proj.name+")")

            elif proj._storage_format == "hyb":
                if Global._check_paradigm("openmp"):
                    sparse_matrix_format = "HYBMatrix<"+idx_type+", "+size_type+", true>"
                    sparse_matrix_include = "#include \"HYBMatrix.hpp\"\n"
                    single_matrix = True

                elif Global._check_paradigm("cuda"):
                    sparse_matrix_format = "HYBMatrixCUDA<"+idx_type+", "+size_type+">"
                    sparse_matrix_include = "#include \"HYBMatrixCUDA.hpp\"\n"
                    single_matrix = True

                else:
                    Global.CodeGeneratorException("    No implementation assigned for rate-coded synapses using Hybrid (COO+ELL) and paradigm="+str(Global.config['paradigm'])+" (Projection: "+proj.name+")")

            elif proj._storage_format == "dense":
                if Global._check_paradigm("openmp"):
                    sparse_matrix_format = "DenseMatrix<"+idx_type+", "+size_type+", true>"
                    sparse_matrix_include = "#include \"DenseMatrix.hpp\"\n"
                    single_matrix = True

                else:
                    sparse_matrix_format = "DenseMatrixCUDA<"+idx_type+", "+size_type+", true>"
                    sparse_matrix_include = "#include \"DenseMatrixCUDA.hpp\"\n"
                    single_matrix = True

            else:
                Global.CodeGeneratorException("    No implementation assigned for rate-coded synapses using '"+proj._storage_format+"' storage format (Projection: "+proj.name+")")

        elif proj.synapse_type.type == "spike":
            # Check for the provided format + paradigm
            # combination if it's availability
            if proj._storage_format == "lil":
                if proj._storage_order == "pre_to_post":
                    Global.CodeGeneratorException("    The storage_order 'pre_to_post' is invalid for LIL representations (Projection: "+proj.name+")")

                if Global._check_paradigm("openmp"):
                    if Global.config['num_threads'] == 1 or proj._no_split_matrix:
                        sparse_matrix_format = "LILInvMatrix<"+idx_type+", "+size_type+">"
                        sparse_matrix_include = "#include \"LILInvMatrix.hpp\"\n"
                        single_matrix = True
                    else:
                        sparse_matrix_format = "PartitionedMatrix<LILInvMatrix<"+idx_type+", "+size_type+">, "+idx_type+", "+size_type+">"
                        sparse_matrix_include = "#include \"PartitionedMatrix.hpp\"\n#include \"LILInvMatrix.hpp\"\n"
                        single_matrix = False

                else:
                    Global.CodeGeneratorException("    No implementation assigned for spiking synapses using LIL and paradigm="+str(Global.config['paradigm'])+ " (Projection: "+proj.name+")")

            elif proj._storage_format == "csr":
                if proj._storage_order == "post_to_pre":
                    if Global._check_paradigm("openmp"):
                        sparse_matrix_format = "CSRCMatrix<"+idx_type+", "+size_type+">"
                        sparse_matrix_include = "#include \"CSRCMatrix.hpp\"\n"
                        single_matrix = True

                    elif Global._check_paradigm("cuda"):
                        sparse_matrix_format = "CSRCMatrixCUDA<"+idx_type+", "+size_type+">"
                        sparse_matrix_include = "#include \"CSRCMatrixCUDA.hpp\"\n"
                        single_matrix = True

                    else:
                        raise NotImplementedError

                else:
                    if Global._check_paradigm("openmp"):
                        if Global.config['num_threads'] == 1 or proj._no_split_matrix:
                            sparse_matrix_format = "CSRCMatrixT<"+idx_type+", "+size_type+">"
                            sparse_matrix_include = "#include \"CSRCMatrixT.hpp\"\n"
                            single_matrix = True
                        else:
                            sparse_matrix_format = "PartitionedMatrix<CSRCMatrixT<"+idx_type+", "+size_type+">, "+idx_type+", "+size_type+">"
                            sparse_matrix_include = "#include \"PartitionedMatrix.hpp\"\n#include \"CSRCMatrixT.hpp\"\n"
                            single_matrix = False

                    else:
                        raise NotImplementedError

            elif proj._storage_format == "dense":
                if proj._storage_order == "post_to_pre":
                    if Global._check_paradigm("openmp"):
                        sparse_matrix_format = "DenseMatrix<"+idx_type+", "+size_type+", false>"
                        sparse_matrix_include = "#include \"DenseMatrix.hpp\"\n"
                        single_matrix = True

                    else:
                        raise NotImplementedError

                else:
                    raise NotImplementedError

            else:
                Global.CodeGeneratorException("    No implementation assigned for spiking synapses using '"+proj._storage_format+"' storage format (Projection: "+proj.name+")")

        else:
            Global.CodeGeneratorException("    Invalid synapse type " + proj.synapse_type.type)

        # HD (6th Oct 2020)
        # Currently I unified this by flipping the dimensions in CSRCMatrixT in the C++ code
        sparse_matrix_args = " %(post_size)s, %(pre_size)s" % {
            'pre_size': proj.pre.population.size if isinstance(proj.pre, PopulationView) else proj.pre.size,
            'post_size': proj.post.population.size if isinstance(proj.post, PopulationView) else proj.post.size
        }

        if proj._storage_format == "bsr":
            if hasattr(proj, "_bsr_size"):
                sparse_matrix_args += ", " + str(proj._bsr_size)
            else:
                sparse_matrix_args += ", " + str(determine_bsr_blocksize(proj.pre.population.size if isinstance(proj.pre, PopulationView) else proj.pre.size, proj.post.population.size if isinstance(proj.post, PopulationView) else proj.post.size))

        if Global.config['verbose']:
            print("Selected", sparse_matrix_format, "(", sparse_matrix_args, ")", "for projection ", proj.name, "and single_matrix =", single_matrix )

        return sparse_matrix_include, sparse_matrix_format, sparse_matrix_args, single_matrix