Changeset 409

Show
Ignore:
Timestamp:
07/10/08 17:08:21 (1 month ago)
Author:
pierre
Message:

Add a gather function to the nest2 api in the distributed mode. Now we can launched the VAbenchmark_graphs script easily to check that the behaviour of nest2 is slightly dependent of the number of nodes due to the random number generators. Nevertheless, statistics are the same.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/nest1/connectors.py

    r405 r409  
    103103        presynaptic_neurons  = numpy.reshape(projection.pre.cell,(projection.pre.cell.size,)) 
    104104        # what about NativeRNG? 
     105        npre = len(presynaptic_neurons) 
    105106        if projection.rng: 
    106107            if isinstance(projection.rng, NativeRNG): 
     
    115116            # We evaluate the probabilities of connections for those distances 
    116117            func = eval("lambda d: %s" %self.d_expression) 
    117             distances[:,0] = func(distances[:,0]) 
    118             rarr = rng.uniform(0, 1, len(distances[:,0]),
     118            distances = func(distances[:,0]) 
     119            rarr = rng.uniform(0, 1, (npre,)
    119120            # We get the list of cells that will established a connection 
    120             idx = numpy.where((distances[:,0] >= 1) | ((0 < distances[:,0]) & (distances[:,0] < 1) & (rarr < distances[:,0])))[0] 
    121             source_list = presynaptic_neurons[idx].tolist() 
     121            source_list = numpy.compress((distances >= 1) | ((0 < distances) & (distances < 1) & (rarr <= distances)), presynaptic_neurons).tolist() 
    122122            # We remove the post cell if we don't allow self connections 
    123             if not self.allow_self_connections: 
    124                 try: 
    125                     source_list.remove(post) 
    126                 except Exception: 
    127                     pass 
     123            if not self.allow_self_connections and post in source_list: 
     124                source_list.remove(post) 
    128125            N = len(source_list) 
    129126            weights = self.getWeights(N) 
  • trunk/src/nest2/__init__.py

    r408 r409  
    160160        user_filename = file or self.filename 
    161161        nest_filename = _merge_files(self._device, gather) 
     162        if num_processes() > 1: 
     163            user_filename += '.%d' % rank() 
    162164        if compatible_output: 
    163             if gather == False and num_processes() > 1: 
    164                 user_filename += '.%d' % rank() 
    165             if gather == False or rank() == 0: # if we gather, only do this on the master node 
    166                 recording.write_compatible_output(nest_filename, user_filename, Recorder.formats[self.variable],self.population, get_time_step()) 
     165            # We should do the post processing (i.e the compatible output) in a distributed 
     166            # manner to speed up the thing. The only problem that will arise is the headers,  
     167            # that should be taken into account to be really clean. Otherwise, if the # symbol 
     168            # is escaped while reading the file, there is no problem 
     169           recording.write_compatible_output(nest_filename, user_filename, Recorder.formats[self.variable],self.population, get_time_step()) 
    167170        else: 
    168171            system_line = 'cat %s >> %s' % (nest_filename, user_filename) 
    169172            os.system(system_line) 
     173        if gather == True and num_processes()> 1: 
     174            root_file = file or self.filename 
     175            for node in xrange(num_processes()): 
     176                if rank()==0: 
     177                    node_file = root_file + '.%d' % node  
     178                    if os.path.exists(node_file): 
     179                        system_line = 'cat %s >> %s' % (node_file, root_file) 
     180                        os.system(system_line) 
     181                        system_line = 'rm %s' %node_file 
     182                        os.system(system_line) 
    170183        # don't want to remove nest_filename at this point in case the user wants to access the data 
    171184        # a second time (e.g. with both getSpikes() and printSpikes()), but we should 
     
    514527            os.system(system_line) 
    515528            os.remove(nest_filename) 
    516     if gather and len(node_list) > 1: 
    517         #if rank() == 0: 
    518         raise Exception("gather not yet implemented") 
     529    #if gather and len(node_list) > 1: 
     530        ##if rank() == 0: 
     531        #raise Exception("gather not yet implemented") 
    519532    return merged_filename 
    520533 
     
    868881        ## This is a rough approximation, because in fact each nodes is only multiplying  
    869882        ## the frequency of the recorders by the number of processes. To do better, we need a MPI 
    870         ## package to send informations to node 0. 
     883        ## package to send informations to node 0. Nevertheless, it works for threaded mode 
    871884        node_list = range(nest.GetStatus([0], "total_num_virtual_procs")[0]) 
    872885        n_spikes  = 0 
  • trunk/src/nest2/connectors.py

    r408 r409  
    3939    # in Python (faster, but more memory needed), but PyNEST should soon have 
    4040    # a function to do the lookup, at which point we will switch to using that. 
    41     conn_dict = nest.GetConnections([pre], synapse_type)[0] 
    42     if conn_dict: 
    43         first_port = len(conn_dict['targets']) 
    44     else: 
    45         first_port = 0 
     41    first_port = len(nest.GetConnections([pre], synapse_type)[0]['targets']) 
    4642    return range(first_port, first_port+len(target_list)) 
    4743 
     
    9490            else: 
    9591                rarr = numpy.random.uniform(0, 1, (npost,)) 
    96             if len(rarr) > len(postsynaptic_neurons): 
    97                 rarr = rarr[:len(postsynaptic_neurons)] 
    9892            target_list = numpy.compress(numpy.less(rarr, self.p_connect), postsynaptic_neurons).tolist() 
    9993            # if self connections are not allowed, check whether pre and post are the same 
     
    120114            print "Periodic boundaries activated and set to size ", periodic_boundaries 
    121115        postsynaptic_neurons = projection.post.cell.flatten() # array 
     116        npost = len(postsynaptic_neurons) 
    122117        #postsynaptic_neurons = projection.post.cell_local 
    123118        # what about NativeRNG? 
     
    137132            # We evaluate the probabilities of connections for those distances 
    138133            func = eval("lambda d: %s" %self.d_expression) 
    139             distances[0] = func(distances[0]) 
     134            distances = func(distances[0]) 
    140135            # We get the list of cells that will established a connection 
    141             rarr = rng.uniform(0, 1, len(distances[0,:]),
    142             idx = numpy.where((distances[0,:] >= 1) | ((0 < distances[0,:]) & (distances[0,:] < 1) & (rarr < distances[0,:])))[0] 
    143             target_list = postsynaptic_neurons[idx].tolist() 
     136            rarr = rng.uniform(0, 1, (npost,)
     137            target_list = numpy.compress((distances >= 1) | ((0 < distances) & (distances < 1) & (rarr <= distances)), postsynaptic_neurons).tolist() 
     138            #target_list = postsynaptic_neurons[idx].tolist() 
    144139            # We remove the pre cell if we don't allow self connections 
    145             if not self.allow_self_connections: 
    146                 try: 
    147                     target_list.remove(pre) 
    148                 except Exception: 
    149                     pass 
     140            if not self.allow_self_connections and pre in target_list: 
     141                target_list.remove(pre) 
    150142            N = len(target_list) 
    151143            weights = self.getWeights(N) 
  • trunk/test/VAbenchmarks.py

    r384 r409  
    3838rngseed  = 98765 
    3939 
    40 n        = 400  # number of cells 
     40n        = 5000  # number of cells 
    4141r_ei     = 4.0   # number of excitatory cells:number of inhibitory cells 
    4242pconn    = 0.02  # connection probability 
     
    9595        w_exc = w_exc*0.1 
    9696        w_inh = w_inh*0.1 
    97     print w_exc, w_inh 
    9897    assert w_exc > 0; assert w_inh < 0 
    9998 
     
    139138 
    140139print "%s Initialising membrane potential to random values..." % node_id 
    141 rng = NumpyRNG(seed=rngseed, parallel_safe=True, rank=node_id, num_processes=np) 
     140rng = NumpyRNG(seed=rngseed, parallel_safe=False, rank=node_id, num_processes=np) 
    142141uniformDistr = RandomDistribution('uniform', [v_reset,v_thresh], rng=rng) 
    143142if simulator == "brian": 
     
    159158    connections['ext2i'] = Projection(ext_stim, inh_cells, ext_conn, target='excitatory') 
    160159 
    161  
    162160#for prj in connections.keys(): 
    163161    #connections[prj].saveConnections('Results/VAbenchmark_%s_%s_%s_np%d.conn' % (benchmark, prj, simulator, np)) 
     
    183181I_rate = inh_cells.meanSpikeCount()*1000./tstop 
    184182 
    185  
    186183# === Print results to file ==================================================== 
    187184 
     
    191188exc_cells.printSpikes("Results/VAbenchmark_%s_exc_%s_np%d.ras" % (benchmark, simulator, np)) 
    192189inh_cells.printSpikes("Results/VAbenchmark_%s_inh_%s_np%d.ras" % (benchmark, simulator, np)) 
    193 exc_cells.print_v("Results/VAbenchmark_%s_exc_%s_np%d.v" % (benchmark, simulator, np), compatible_output=True
     190exc_cells.print_v("Results/VAbenchmark_%s_exc_%s_np%d.v" % (benchmark, simulator, np)
    194191writeCPUTime = Timer.elapsedTime() 
    195192