Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

split simulate into prepare, run and finalize #650

Merged
merged 26 commits into from Mar 17, 2017
Merged

Conversation

@apeyser
Copy link
Contributor

@apeyser apeyser commented Jan 31, 2017

Needs careful check on simulation_manager, given that it's a conflict bottleneck on master.

As requested by several projects including visualization, this PR makes it possible to split a run into multiple time chunks, without doing the calibration and teardown steps for every run.
Thus, simulate(n) = prepare(); run(n); cleanup();
as well as prepare(); run(n/2); run(n/2); cleanup();

A follow-up issue would be to make a run interruptible, returning the time actually run so that the simulation can be continued with another run call.

Split into run: passes installcheck

pull time out of prepare

prepare_simulation_ code into prepare

prepare_simulation_.2 code into prepare

prepare_simulation_.3 code into prepare

prepare_simulation_.4 code into prepare

prepare_simulation_.all code into prepare

Map Run to Function

Run breakup doesnt break Simulate tests

Add python bindings

Seems to run a tester

Add contextmanager IterateRuns

Split run passes test

test-split fix copyright

Format with clang

Lost manager
@@ -82,6 +82,9 @@ ArrayDatum get_connections( const DictionaryDatum& dict );

void simulate( const double& t );
void resume_simulation();
void run( const double& t );
void prepare();
void cleanup();

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

Since this is the high-level API, the functions should be document with doxygen comments.
And to we still need resume_simulation() after this split?

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

prepare -> run -> run -> ... -> run -> cleanup
resume_simulation has a different function, to run a simulation after cleanup. But it should be checked, as you point out. I would, however, make that another issue -- I wouldn't remove any functionality until we have this functionality in.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

Pointer to an example of the doxygen documentation? It hasn't been used in this header previously, so I'm not precisely sure without an example.

This comment has been minimized.

@apeyser

apeyser Feb 9, 2017
Author Contributor

This comment has been minimized.

@heplesser

heplesser Feb 9, 2017
Contributor

See, e.g., event.h.

Copy link
Contributor

@heplesser heplesser left a comment

@apeyser This is just a first review, I have not evaluated the changes to simulate in detail. Could you explain the rationale for this PR? That would make it easier to understand and evaluate. I also wonder what would happen if one called Run() without having called Prepare() before? What if I forget Cleanup() after Run() and then call Simulate()?

@@ -474,6 +474,39 @@ NestModule::SimulateFunction::execute( SLIInterpreter* i ) const
i->EStack.pop();
}

void
NestModule::RunFunction::execute( SLIInterpreter* i ) const

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

Please add SLI-level documentation.



void
NestModule::PrepareFunction::execute( SLIInterpreter* i ) const

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

Please add SLI-level documentation.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

{
prepare();

// successful end of simulate

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

This comment seems wrong.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

}

void
NestModule::CleanupFunction::execute( SLIInterpreter* i ) const

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

Please add SLI-level documentation.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

{
cleanup();

// successful end of simulate

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

This comment seems wrong.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor


@check_stack
def Cleanup():
"""Simulate the network for t milliseconds.

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

Docstring is wrong.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

nest.ResetKernel()
nest.SetDefaults('spike_detector', {'withtime': True})

n1 = nest.Create("iaf_neuron")

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

Please use iaf_psc_alpha or similar, iaf_neuron is deprecated.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

def IterateRuns():
Prepare()
try: yield
finally: Cleanup()

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

This Python is slightly beyond me ... It seems yield yields nothing and I cannot see when this generator would fail to yield anything and thus exit.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

The name is wrong -- it's not iterate runs, it's manage runs. It should also be commented as to use:

with nest.IterateRuns():
  for i in range(0, 10):
    nest.run(5)

It's the messed up fix for a lack of proper lambda's in python. See contextlib.contextmanager.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

Renamed RunManager + better doc string.

finalize_simulation_();
}

void
nest::SimulationManager::resume_( size_t num_active_nodes )
nest::SimulationManager::resume_()
{
assert( kernel().is_initialized() and not inconsistent_state_ );

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

The next section of code is lengthy and thus puts together a status message. Should that be delegated to a method, so that the flow of important logic becomes more transparent here?

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

Same as before -- maybe. How much should we take advantage here to clean up code, and how much should we avoid making extra changes in this same set of commits?

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

resume_ -> start_updating, finalize_ removed


void
nest::SimulationManager::run( Time const& t )
{
if ( t == Time::ms( 0.0 ) )
return;

This comment has been minimized.

@heplesser

heplesser Jan 31, 2017
Contributor

The next section of code is about error checking. Should that be delegated to a separate method to make the flow of logic clearer?

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

Maybe -- I tried to minimize changes, this was all in simulate before.

This comment has been minimized.

@apeyser

apeyser Feb 1, 2017
Author Contributor

@apeyser
Copy link
Contributor Author

@apeyser apeyser commented Feb 1, 2017

Do we have a proper image to run clang in? The formatting is tightly fixed to clang-3.6 which is no longer available in many distributions. This is probably a job for microservices! [ @DimitriPlotnikov ]

apeyser added 5 commits Feb 1, 2017
kernel().rng_manager.get_grng()->ulrand( 100000 ) ) )
{
throw KernelException(
"In SimulationManager::simulate(): "

This comment has been minimized.

@wschenck

wschenck Feb 4, 2017
Contributor

Correct output to "In SimulationManager::cleanup(): "

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor

kernel().rng_manager.get_grng()->ulrand( 100000 ) ) )
{
LOG( M_ERROR,
"SimulationManager::simulate",

This comment has been minimized.

@wschenck

wschenck Feb 4, 2017
Contributor

Correct output to "In SimulationManager::prepare(): "

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor

@@ -443,20 +507,39 @@ nest::SimulationManager::simulate( Time const& t )
"is called repeatedly with simulation times that are not multiples of "

This comment has been minimized.

@wschenck

wschenck Feb 4, 2017
Contributor

Line 502 in new code above: Correct output to "In SimulationManager::run(): "

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor

This comment has been minimized.

@apeyser

apeyser Feb 9, 2017
Author Contributor

Done.


const size_t num_active_nodes = prepare_simulation_();
// Check whether waveform relaxation is used on any MPI process
kernel().node_manager.check_wfr_use();

This comment has been minimized.

@wschenck

wschenck Feb 4, 2017
Contributor

Why was check_wfr_use() moved to this point? In the old code it was part of prepare_simulation_().

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor

That's where prepare_simulation_ was, the only part surviving is the check_wfr_use call. Maybe it could happen only once --- but I'm not sure, not tested.

This comment has been minimized.

@wschenck

wschenck Feb 8, 2017
Contributor

I think it needs to happen only once after update_delay_extrema_(), but it should not hurt here either. The gap junction team must know.
@suku248 : ???

finalize_simulation_();
void
nest::SimulationManager::cleanup()
{

This comment has been minimized.

@wschenck

wschenck Feb 4, 2017
Contributor

What do you think about a state flag within SimulationManager, which enables the execution of run()? It could be set to true within prepare() and afterwards set to false within cleanup().

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor

An earlier version had an enum that made a state machine checking that prepare, run and cleanup were called in the right order. I saw that PR #542 was playing with that, so I removed until merge. Apparently merged, so I should look again at exception throwing in terms of state.

return;

// Check for synchronicity of global rngs over processes
// TODO: This seems double up, there is such a test at end of simulate()

This comment has been minimized.

@wschenck

wschenck Feb 4, 2017
Contributor

Remove the comment line with the TODO.

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor

@@ -375,6 +376,61 @@ nest::SimulationManager::simulate( Time const& t )
t_slice_begin_ = timeval();
t_slice_end_ = timeval();

This comment has been minimized.

@wschenck

wschenck Feb 4, 2017
Contributor

I don't understand the reasoning behind t_slice_begin and t_slice_end. There are both used for print_progress_() and not changed anywhere else. But what does timeval() return? Does this refer to "struct timeval" from the C standard library?

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor

Seems to. I think someone was trying to set them to {0, 0} (maybe?).

This comment has been minimized.

@wschenck

wschenck Feb 7, 2017
Contributor

I think this functionality is broken. Not by this PR, but already in the main branch. Shall we leave it here and repair it in an additional PR afterwards?

This comment has been minimized.

@heplesser

heplesser Feb 7, 2017
Contributor

t_slice_end_ is actually updated in simulation_manager.cpp, approx line 780 (master), by

gettimeofday( &t_slice_end_, NULL );

It is used to calculate the real-time factor for the progress display.

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor

And it looks like value needs to be nulled in order to check whether it was set at all -- the tv_sec is checked to see if it's zero (not precisely correct) to see whether it's been set somewhere else.

This code is messy, probably should be fixed, but outside of the purview of the current PR.

This comment has been minimized.

@wschenck

wschenck Feb 7, 2017
Contributor

Sorry, I missed the part where t_slice_begin_ and t_slice_end_ are changed. t_slice_begin_ is also updated in line 593 (approx. in master). The initialization with timeval() is also fine according to C++ standard. Thus no reason to worry.

This comment has been minimized.

@apeyser

apeyser Feb 9, 2017
Author Contributor

But I'll comment it, since it's clearly a mess. The code really needs to be refactored into several classes, splitting the current state of the machinery... but I don't want the job.

@@ -813,27 +842,6 @@ nest::SimulationManager::update_()
}

This comment has been minimized.

@wschenck

wschenck Feb 4, 2017
Contributor

Additional comment reg. line 791 in the OLD code (in function update_()): I wonder if this part of the code outside of the update loop will work properly if running directly again without a cleanup/prepare cycle. It seems to be related to structural plasticity and updates synaptic elements.
@sdiazpier : May I ask you for help regarding this question?

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor

It's still in the update loop, it's inside of run/start_updating, in the same spot as simulate/resume

This comment has been minimized.

@wschenck

wschenck Feb 8, 2017
Contributor

I don't think so. It is outside of the do-while-loop within update_(). Thus it is called only once at the end of run() in the changed code. (In addition, the update of synaptic elements also happens within the do-while-loop, but there is this extra call at the end outside of the loop, and this concerns me slightly - at least it is something to consider.)

This comment has been minimized.

@apeyser

apeyser Feb 9, 2017
Author Contributor

@wschenck I think I may be confused about the code we're discussing. Could you add the snippet or a link to it? Currently 791 on the master is to:

    } while ( to_do_ > 0 and not exit_on_user_signal_
      and not exceptions_raised.at( thrd ) );

>>>>>    // End of the slice, we update the number of synaptic elements
    for ( std::vector< Node* >::const_iterator i =
            kernel().node_manager.get_nodes_on_thread( thrd ).begin();
          i != kernel().node_manager.get_nodes_on_thread( thrd ).end();
          ++i )
    {
      ( *i )->update_synaptic_elements(
        Time( Time::step( clock_.get_steps() + to_step_ ) ).get_ms() );
    }

  } // end of #pragma parallel omp

which is in the same place in the current monster update_ () function, right after the update loop. That needs to be refactored! 200 lines seperating the do {} while... and the function still has another 100 lines...

This comment has been minimized.

@apeyser

apeyser Feb 9, 2017
Author Contributor

To confirm, do you mean: 669dc49?diff=split#diff-06fecbcc67899362e4c211274b21fb71L791 ?
If so, that code is repeated, once after the loop, and once inside the loop: 669dc49?diff=split#diff-06fecbcc67899362e4c211274b21fb71L791

This comment has been minimized.

@wschenck

wschenck Feb 9, 2017
Contributor

Now I am slightly confused about the links in your previous posting because they just open the complete diff.
But you already got the right code snippet in your posting before, concerning the location outside of the do-while-loop. And in line 600-607 (in master) the same code exists within the do-while-loop.
Concerning the outside position of this code snippet, this would be called in a kind of irregular way in subsequent calls to run() (e.g., one run could be for just a fraction of a min-delay interval, and the next for 100 min-delay intervals, and so on...). I just wonder if this may hurt the structural plasticity algorithm. Most likely not, but given the complexity of interacting algorithms in the kernel I am on the paranoid side.

This comment has been minimized.

@apeyser

apeyser Feb 9, 2017
Author Contributor

I see now -- but this would also be a problem for multiple simulate() calls. But this may break the ideas that simulate(n) = prepare(); run(n/2); run(n/2); cleanup()
I think @sdiazpier is the only person who can answer this, or give a good suggestion on what we should do.

This comment has been minimized.

@wschenck

wschenck Feb 9, 2017
Contributor

As soon as this is sorted out, I would say 👍 for pulling!

This comment has been minimized.

@sdiazpier

sdiazpier Feb 9, 2017
Contributor

Dear @apeyser and @wschenck, sorry for the late reply. The update of the synaptic elements can be done in any irregular fraction of simulation time. This is not relevant because the structural changes actually take place on a much larger time scale, so the accumulation of these small changes in the synaptic elements can be achieved at partial steps and the final results should be the same.
To verify this I ran the simple structural plasticity examples and they provide the same output using the new Prepare() - Run() - Cleanup() functions as with Simulate()

This comment has been minimized.

@apeyser

apeyser Feb 10, 2017
Author Contributor

@@ -375,6 +376,61 @@ nest::SimulationManager::simulate( Time const& t )
t_slice_begin_ = timeval();
t_slice_end_ = timeval();

// Reset profiling timers and counters within event_delivery_manager
kernel().event_delivery_manager.reset_timers_counters();

This comment has been minimized.

@wschenck

wschenck Feb 4, 2017
Contributor

This line (resetting timers and counters) may be moved into run().

This comment has been minimized.

@apeyser

apeyser Feb 7, 2017
Author Contributor


Should be or maybe? Should they be reset every time you call run, or only once for a simulate function? Wouldn't this change the meaning, where before you called simulate (and the counters where reset) and then resume multiple times?

This comment has been minimized.

@wschenck

wschenck Feb 8, 2017
Contributor

I would move it, because now - if you think of using sionlib as I/O backend - you have to call run instead of simulate to record all data in one container. And if you want to have separate measurements for each invocation of run (what would have been simulate before) you need the reset within run.

This comment has been minimized.

@apeyser

apeyser Feb 9, 2017
Author Contributor

Is the nestio backend being re-initialized with each run in this set up, after we merge? And do we want to have different measurements for each run? It's a non-rhetorical question, what should the semantics here be. We want as little as possible being reinitialized in run, so that you can use run to handle interrupts or do external updates down from the python layer at regular intervals.

This comment has been minimized.

@wschenck

wschenck Feb 9, 2017
Contributor

Not sure what you mean about the nestio backend. In my view it is not re-initialized with each run, otherwise we would still have the sionlib problems.

My opinion about the position of reset_timers_counters is not very strong. Thus, if you like it as it is, I have no further objections.

This comment has been minimized.

@apeyser

apeyser Feb 9, 2017
Author Contributor

I was just trying to figure out the semantics -- what gets re-run on each cycle. Since you use the counters, I'll put them where you like them, given that they're light anyhow. It may even be useful for 'someone' to add double counters, one for a run cycle, and one for a simulate cycle.

apeyser added 5 commits Feb 9, 2017
Copy link
Contributor

@sdiazpier sdiazpier left a comment

Great job @apeyser, this was very much needed for many interactive applications and will benefit a lot the structural plasticity usage and monitoring.

Copy link
Member

@Silmathoron Silmathoron left a comment

This looks cool, thanks @apeyser!

* pair to divide a simulation into multiple pieces with access
* to the API in between.
*
* Thus, simulate(t) = prepare(); run(n/2); run(n/2); cleanup()

This comment has been minimized.

@Silmathoron

Silmathoron Feb 10, 2017
Member

I think this should be t/2 instead of n/2

This comment has been minimized.

@apeyser

apeyser Feb 10, 2017
Author Contributor

@apeyser
Copy link
Contributor Author

@apeyser apeyser commented Feb 10, 2017

@heplesser Any more suggestions before merging?

Copy link
Contributor

@jougs jougs left a comment

@apeyser: thanks for this nice work. I could not see any problems in the code other than the two minor things I've pointed out in my comments. As I think the test is good enough, I did not run the new code myself.

!! PLEASE DON'T MERGE UNTIL AFTER THE RELEASE OF 2.12.0 !!


Description: Simulate the network for n milliseconds.
Call prepare before, and cleanup after.
n simulate = prepare n/m run ... m times... cleanup

This comment has been minimized.

@jougs

jougs Feb 26, 2017
Contributor

Make prepare, run and simulate uppercase, wherever they refer to the corrresponding SLI commands. Those are case sensitive. This comment applies throughout this PR.

This comment has been minimized.

@apeyser

apeyser Feb 27, 2017
Author Contributor

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

n need not be an int, double is allowed as well (e.g 0.5 Run), it must just be a multiple of the step size. Since the argument is a time in ms, I would also consider t a better choice.

For the semantics explanation, I think it would be safer to multiply by m than divide:

t m mul Simulate

is equivalent to

Prepare m { t Run } repeat Cleanup

This comment has been minimized.

@apeyser

apeyser Mar 6, 2017
Author Contributor

@@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-

This comment has been minimized.

@jougs

jougs Feb 26, 2017
Contributor

Can you please rename this file to something like test_split_simulation.py? I think the current name is a bit too general.

This comment has been minimized.

@apeyser

apeyser Feb 27, 2017
Author Contributor

@apeyser
Copy link
Contributor Author

@apeyser apeyser commented Feb 27, 2017

@jougs I'll rebase on 2.12.0 (hopefully that's happening very soon). Then the whole thing can be merge into nestio.

@jougs
Copy link
Contributor

@jougs jougs commented Feb 27, 2017

We're going to release current master as 2.12.0 probably already tomorrow.

Copy link
Contributor

@heplesser heplesser left a comment

@apeyser Thank you for all the improvements you have made. I have some more suggestions, mainly on documentation and names. I would also feel safer if we had a bit of control between parts, especially a check that quits run() if prepare() has not been called since program start or last cleanup().


Description: Simulate the network for n milliseconds.
Call prepare before, and cleanup after.
n simulate = prepare n/m run ... m times... cleanup

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

n need not be an int, double is allowed as well (e.g 0.5 Run), it must just be a multiple of the step size. Since the argument is a time in ms, I would also consider t a better choice.

For the semantics explanation, I think it would be safer to multiply by m than divide:

t m mul Simulate

is equivalent to

Prepare m { t Run } repeat Cleanup
n simulate = prepare n/m run ... m times... cleanup


SeeAlso: simulate, resume, unit_conversion, prepare, cleanup

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

Please use upper case where appropriate.

Call prepare before, and cleanup after.
n simulate = prepare n/m run ... m times... cleanup


This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

Please add a Note making it very clear that Run must only be used between Prepare and Cleanup and that no changes (new nodes, connections, calls to SetStatus) should be made between Prepare and Cleanup.

Description: sets up network calibration before run is called
any number of times

SeeAlso: run, cleanup, simulate

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

Run, Cleanup, Simulate

Please add a similar warning as for Run

Description: tears down a network after run is called
any number of times

SeeAlso: run, prepare, simulate

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

See above, capitalization and warning.

Call between Prepare and Cleanup calls, or within an
with RunManager: clause
Simulate(n) = Prepare() Run(n/m) ... m times ... Cleanup()
"""

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

Similar comments apply as for the SLI documentation, see above.

"""ContextManager for Run.

Calls Prepare() before a series of Run() calls,
and adds a Cleanup() at end

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

I think here it would be very helpful for users to have an example.

}

void
nest::SimulationManager::resume_( size_t num_active_nodes )
nest::SimulationManager::start_updating_()

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

I am not really happy with the name start_updating_() because it makes me look for stop_updating_(). Since we already have update_(), maybe update_network_() or perform_update_ () would be better.

kernel().event_delivery_manager.configure_spike_buffers();

kernel().node_manager.ensure_valid_thread_local_ids();
num_active_nodes_ = kernel().node_manager.prepare_nodes();

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

Does it really make sense to have num_active_nodes_ as a member variable? It is used only once to provide an informational message. Wouldn't it make more sense to add a num_active_nodes() method to NodeManager?


void
nest::SimulationManager::check_run( Time const& t )

This comment has been minimized.

@heplesser

heplesser Mar 2, 2017
Contributor

check_run() does not express what this method does. How about assert_valid_simtime()?

Copy link
Contributor

@heplesser heplesser left a comment

@apeyser Almost there now, I would just like some more minor fixes to documentation, plus one comment on hl_api_simulation.py:55 that you didn't fix yet.

before Cleanup to finalize state (close files, etc).
Any changes made between Prepare and Cleanup may cause
undefined failures (the famed nose-inhabiting monkeys of
internet lore).

This comment has been minimized.

@heplesser

heplesser Mar 6, 2017
Contributor

@apeyser Could you remove the text in parentheses and add "or yield incorrect results"? Open failures (crashes, stop with error message) are a lesser problem than simulations generating incorrect data.

This comment has been minimized.

@apeyser

apeyser Mar 10, 2017
Author Contributor

That's what undefined means - up to crashes, but generally simply unexpected results (reordering of increments is the classic case).

before Cleanup to finalize state (close files, etc).
Any changes made between Prepare and Cleanup may cause
undefined failures (the famed nose-inhabiting monkeys of
internet lore).

This comment has been minimized.

@heplesser

heplesser Mar 6, 2017
Contributor

See above.

So:
with RunManager():
for i in range(10):
Run()

This comment has been minimized.

@heplesser

heplesser Mar 6, 2017
Contributor

Doesn't Run() need an argument? I think it would be very useful to explain this context a bit more, so that users (neuroscientist with some Python knowledge) understand how they can use this context manager sensibly. Maybe put a little plot into the loop?

apeyser added 2 commits Mar 6, 2017
@apeyser
Copy link
Contributor Author

@apeyser apeyser commented Mar 8, 2017

@heplesser @jougs I add some of the suggestion from hep that affected the node-manager, and now with the new vera++ analysis, node_manager fails with 65 errors -- apparently the file was very out of sink with vera++, and as soon as the file is changed at all, all fixes must be made.

That doesn't seem to be in the scope of this pull request, but should be a separate issue to correct this file. What should we do about this?

@heplesser
Copy link
Contributor

@heplesser heplesser commented Mar 8, 2017

@apeyser I just created #672 to fix the Vera++ issues, including a problem with our Vera++ rules. Could you also merge from master (should work without a problem) to get the new static code checking in its final version in place here?

@apeyser
Copy link
Contributor Author

@apeyser apeyser commented Mar 17, 2017

Added apeyser#1. I believe that it's only formatting changes -- please correct if I'm wrong @heplesser

@apeyser apeyser merged commit 4a373f7 into nest:master Mar 17, 2017
1 check passed
1 check passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@apeyser apeyser deleted the apeyser:resplit branch Mar 17, 2017
@heplesser
Copy link
Contributor

@heplesser heplesser commented Mar 19, 2017

@apeyser Almost all changes were formatting (adding curly braces around one-line blocks, ! -> not, line length, spaces), a few tiny spelling corrections and in three places I changed "undefined behavior (the famed nose-inhabiting monkeys of internet lore)" to "undefined behavior and incorrect results" in comments (nestmodule.cpp, l 490, 520, 543).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

6 participants
You can’t perform that action at this time.