-
Notifications
You must be signed in to change notification settings - Fork 59
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
Part 1 of the big GPU merge #45
Changes from 2 commits
b38f78b
7e54957
b7bd5dd
3edad46
1388d20
8e6d97f
4ee9930
4c0864b
d1a5b6e
36ebcc7
851f38c
4a1777f
2c6f5a3
c742fd5
039d5a9
121dade
b6aec69
44c8ac0
78f60f5
5c09594
3830c9a
2db99a2
65ed2fe
7f1216d
de992ad
b5bae5b
06ef117
18a9226
05e4770
b9b1e57
dbca304
ff14704
9e0b874
f1eac25
5174b69
a39c9a3
63c507b
830428a
cee495c
c97135d
5ade8d0
1b929ff
f189d73
550da10
a03af27
e7a8fb6
5aeea90
e8d3285
b39a93e
0ded25a
cd4d9ae
e74720b
b11990f
bb14d18
1584bf3
46427e6
7751058
2b2b310
5825543
faf1a41
6cf11d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,21 +18,16 @@ else() | |
add_executable(miniapp.exe ${MINIAPP_SOURCES} ${HEADERS}) | ||
endif() | ||
|
||
target_link_libraries(miniapp.exe LINK_PUBLIC nestmc) | ||
set(aaa nestmc) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this debugging CMake code that snuck in? |
||
|
||
if(WITH_TBB) | ||
target_link_libraries(miniapp.exe LINK_PUBLIC ${TBB_LIBRARIES}) | ||
endif() | ||
target_link_libraries(miniapp.exe LINK_PUBLIC nestmc) | ||
target_link_libraries(miniapp.exe LINK_PUBLIC ${EXTERNAL_LIBRARIES}) | ||
|
||
if(WITH_MPI) | ||
target_link_libraries(miniapp.exe LINK_PUBLIC ${MPI_C_LIBRARIES}) | ||
set_property(TARGET miniapp.exe APPEND_STRING PROPERTY LINK_FLAGS "${MPI_C_LINK_FLAGS}") | ||
endif() | ||
|
||
if(WITH_UNWIND) | ||
target_link_libraries(miniapp.exe LINK_PUBLIC ${UNWIND_LIBRARIES}) | ||
endif() | ||
|
||
set_target_properties(miniapp.exe | ||
PROPERTIES | ||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/miniapp" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,43 @@ import argparse | |
import os | ||
import subprocess | ||
|
||
class color: | ||
purple = '\033[95m' | ||
white = '\033[37m' | ||
cyan = '\033[96m' | ||
darkcyan = '\033[36m' | ||
blue = '\033[94m' | ||
green = '\033[92m' | ||
yellow = '\033[93m' | ||
red = '\033[91m' | ||
bold = '\033[1m' | ||
underline = '\033[4m' | ||
end = '\033[0m' | ||
|
||
class nocolor: | ||
purple = '' | ||
white = '' | ||
cyan = '' | ||
darkcyan = '' | ||
blue = '' | ||
green = '' | ||
yellow = '' | ||
red = '' | ||
bold = '' | ||
underline = '' | ||
end = '' | ||
|
||
|
||
def parse_clargs(): | ||
P = argparse.ArgumentParser(description='pretty print stack traces') | ||
P.add_argument('input', metavar='FILE', | ||
help='name of file with stack trace') | ||
P.add_argument('-b', '--brief', action='store_false', | ||
P.add_argument('-b', '--brief', action='store_true', | ||
help='print only the file locations') | ||
P.add_argument('-e', '--executable', metavar='FILE', | ||
help='name of the executable or object file to look up symbols') | ||
P.add_argument('-c', '--color', action='store_true', | ||
help='use color output in terminal') | ||
|
||
return P.parse_args() | ||
|
||
|
@@ -23,27 +54,36 @@ def parse_backtrace(source): | |
tokens = line.split() | ||
trace.append({'location':tokens[0], 'function':tokens[1]}) | ||
else: | ||
print "error: unable to open file ", source | ||
print "error: unable to back trace file ", source | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing verb in error text? |
||
|
||
return trace | ||
|
||
def get_function_name(location): | ||
result = os.popen('addr2line ' + location + ' -e miniapp.exe').read() | ||
def get_function_name(location, executable): | ||
result = os.popen('addr2line ' + location + ' -e ' + executable).read() | ||
descriptor = result.split()[0].split(':') | ||
return {'filename': descriptor[0], 'line': descriptor[1]} | ||
|
||
def unmangle(mangled): | ||
unmangled = os.popen('c++filt ' + mangled).read().strip() | ||
# remove the nest::mc:: namespace from all types | ||
return unmangled.replace('nest::mc::', '') | ||
|
||
# | ||
# main | ||
# | ||
args = parse_clargs() | ||
trace = parse_backtrace(args.input) | ||
|
||
for frame in trace: | ||
location = get_function_name(frame['location']) | ||
name = unmangle(frame['function']) | ||
if args.brief: | ||
print location['filename'] + ':' + location['line'], name | ||
else: | ||
print location['filename'] + ':' + location['line'] | ||
# check that a valid executable was provided | ||
executable = args.executable | ||
if not os.path.isfile(executable): | ||
print "error:", executable, "is not a valid executable" | ||
else: | ||
for frame in parse_backtrace(args.input): | ||
location = get_function_name(frame['location'], executable) | ||
name = unmangle(frame['function']) | ||
c = color if args.color else nocolor | ||
fname = c.yellow + location['filename'] + c.end | ||
line = c.cyan + location['line'] + c.end | ||
if args.brief: | ||
print fname + ':' + line | ||
else: | ||
print fname + ':' + line, '\n ', name |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
#include <ion.hpp> | ||
#include <math.hpp> | ||
#include <matrix.hpp> | ||
#include <memory/memory.hpp> | ||
#include <profiling/profiler.hpp> | ||
#include <segment.hpp> | ||
#include <stimulus.hpp> | ||
|
@@ -24,8 +25,6 @@ | |
#include <util/rangeutil.hpp> | ||
#include <util/span.hpp> | ||
|
||
#include <memory/memory.hpp> | ||
|
||
namespace nest { | ||
namespace mc { | ||
namespace fvm { | ||
|
@@ -63,7 +62,6 @@ class fvm_multicell { | |
|
||
using matrix_assembler = typename backend::matrix_assembler; | ||
|
||
/// API for cell_group (see above): | ||
using detector_handle = size_type; | ||
using target_handle = std::pair<size_type, size_type>; | ||
using probe_handle = std::pair<const array fvm_multicell::*, size_type>; | ||
|
@@ -97,6 +95,7 @@ class fvm_multicell { | |
return (this->*h.first)[h.second]; | ||
} | ||
|
||
/// integrate all cell state forward in time | ||
void advance(double dt); | ||
|
||
/// Following types and methods are public only for testing: | ||
|
@@ -401,6 +400,15 @@ void fvm_multicell<Backend>::initialize( | |
std::vector<value_type> tmp_cv_areas(ncomp); | ||
std::vector<value_type> tmp_cv_capacitance(ncomp); | ||
|
||
// Iterate over the input cells and build the indexes etc that descrbe the | ||
// fused cell group. On completion: | ||
// - group_paranet_index contains the full parent index for the fused cells. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spellling eror There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note to self |
||
// - mech_map and syn_mech_map provide a map from mechanism names to an | ||
// iterable container of compartment ranges, which are used later to | ||
// generate the node index for each mechanism kind. | ||
// - the tmp_* vectors contain compartment-specific information for each | ||
// compartment in the fused cell group (areas, capacitance, etc). | ||
// - each probe, stimulus and detector is attached to its compartment. | ||
for (auto i: make_span(0, ncell)) { | ||
const auto& c = cells[i]; | ||
auto comp_ival = cell_comp_part[i]; | ||
|
@@ -488,6 +496,11 @@ void fvm_multicell<Backend>::initialize( | |
} | ||
} | ||
|
||
// confirm user-supplied containers for detectors and probes were | ||
// appropriately sized. | ||
EXPECTS(detectors_size==detectors_count); | ||
EXPECTS(probes_size==probes_count); | ||
|
||
// normalize capacitance across cell | ||
for (auto i: util::make_span(0, ncomp)) { | ||
tmp_cv_capacitance[i] /= tmp_cv_areas[i]; | ||
|
@@ -505,9 +518,9 @@ void fvm_multicell<Backend>::initialize( | |
matrix_.d(), matrix_.u(), matrix_.rhs(), matrix_.p(), | ||
cv_areas_, face_alpha_, voltage_, current_, cv_capacitance_); | ||
|
||
// create density mechanisms | ||
// For each density mechanism build the full node index, i.e the list of | ||
// compartments with that mechanism, then build the mechanism instance. | ||
std::vector<size_type> mech_comp_indices(ncomp); | ||
|
||
std::map<std::string, std::vector<size_type>> mech_index_map; | ||
for (auto& mech: mech_map) { | ||
mech_comp_indices.clear(); | ||
|
@@ -523,7 +536,7 @@ void fvm_multicell<Backend>::initialize( | |
mech_index_map[mech.first] = mech_comp_indices; | ||
} | ||
|
||
// create point (synapse) mechanisms | ||
// Create point (synapse) mechanisms | ||
for (const auto& syni: syn_mech_indices) { | ||
const auto& mech_name = syni.first; | ||
size_type mech_index = mechanisms_.size(); | ||
|
@@ -553,17 +566,16 @@ void fvm_multicell<Backend>::initialize( | |
target_hi = std::copy_n(std::begin(handles), n_indices, target_hi); | ||
targets_count += n_indices; | ||
|
||
//auto mech = mechanism_catalogue::make( | ||
auto mech = backend::make_mechanism( | ||
mech_name, voltage_, current_, comp_indices); | ||
auto mech = backend::make_mechanism(mech_name, voltage_, current_, comp_indices); | ||
mech->set_areas(cv_areas_); | ||
mechanisms_.push_back(std::move(mech)); | ||
|
||
// save the compartment indexes for this synapse type | ||
mech_index_map[mech_name] = comp_indices; | ||
} | ||
|
||
// confirm write-parameters were appropriately sized | ||
EXPECTS(detectors_size==detectors_count); | ||
// confirm user-supplied containers for targets are appropriately sized | ||
EXPECTS(targets_size==targets_count); | ||
EXPECTS(probes_size==probes_count); | ||
|
||
// build the ion species | ||
for (auto ion : mechanisms::ion_kinds()) { | ||
|
@@ -641,19 +653,16 @@ void fvm_multicell<Backend>::advance(double dt) { | |
PL(); | ||
} | ||
|
||
// TODO KERNEL: the stimulus might have to become a "proper" mechanism | ||
// so that the update kernel is fully implemented on GPU. | ||
|
||
// add current contributions from stimuli | ||
for (auto& stim : stimuli_) { | ||
auto ie = stim.second.amplitude(t_); // [nA] | ||
auto loc = stim.first; | ||
|
||
// TODO KERNEL | ||
// is a kernel actually needed? | ||
// for now I only make the update if the injected current in nonzero to | ||
// avoid a redundant host->device copy on the gpu | ||
// | ||
// note: current_ in [mA/cm^2], ie in [nA], cv_areas_ in [µm^2]. | ||
// unit scale factor: [nA/µm^2]/[mA/cm^2] = 100 | ||
//current_[loc] -= 100*ie/cv_areas_[loc]; | ||
if (ie!=0.) { | ||
current_[loc] = current_[loc] - 100*ie/cv_areas_[loc]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason not to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes: the types returned by This isn't a problem any more, because the gpu and cpu code for this loop has now been refactored into target specific loops/kernels. |
||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this approach. Might be cleaner to use
(and likewise above) instead of
set
.