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