Last active
July 18, 2018 11:36
-
-
Save germannp/e11c154b8e68a6ef968a8e0c3416b417 to your computer and use it in GitHub Desktop.
Performance Comparison
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! Needs to go into ic.mod.f90 and then be called from default_ic | |
subroutine ball_of_cells | |
real*8::r,r_max,phi,theta | |
nd = 10000 | |
nda = nd | |
ncels = nd | |
ncals = nd | |
if (allocated(node)) deallocate(node) | |
if (allocated(cels)) deallocate(cels) | |
allocate(node(nda),cels(ncals)) | |
call iniarrays | |
!******* #2 DEFINING MODEL PARAMETERS ******* | |
!implementation and initializations | |
getot=0 | |
itacc=0 | |
nparti=1000 | |
idum=-11111 | |
idumoriginal=idum | |
realtime=0 | |
nvarglobal_out=5 | |
!physical | |
temp=1d0 !low value is low temperature | |
desmax=0.01 | |
resmax=1d-3 | |
prop_noise=0.0d0 | |
deltamax=1d-2 ! miguel 14-10-13 | |
dmax=1 | |
screen_radius=0.85d0 | |
deltamin=1d-2 | |
khold=1d0 | |
angletor=0.05 | |
k_bu=5d0 | |
ramax=0.35d0 | |
k_press=0.0d0!5d-1 | |
m_xwall=0.0d0!0.75 !tooth | |
mi_xwall=0d0 !tooth | |
ndmax=9d4 | |
!biological | |
!functions used | |
ffu=0 | |
!spring of the ellipse | |
ffu(1)=1 | |
ffu(2)=0 !to quit if there are too many cells | |
ffu(3)=0 !screening | |
ffu(4)=0 !torsion | |
ffu(5)=0 !external signal source | |
ffu(6)=0 !buoyancy | |
ffu(11)=0 !epithelial node plastic deformation | |
ffu(12)=1 !0 dynamic delta, 1 fixed delta | |
ffu(13)=0 !neighboring by triangulation | |
ffu(14)=1 !physical boundaries (walls) | |
ffu(17)=0 !volume conservation (epithelial) | |
ffu(22)=1 !0 = noise biased by energies , 1 = unbiased noise | |
ffu(24)=0 | |
do i=1,nd | |
node(i)%you=0d0 ; node(i)%adh=5d-1 | |
node(i)%rep=0d0 ; node(i)%repcel=5d-1 | |
node(i)%req=0.4d0 | |
node(i)%reqcr=0.4d0 | |
node(i)%reqs=0d0 | |
node(i)%da=0.5d0; | |
node(i)%ke=5d0 | |
node(i)%tor=0d0 | |
node(i)%stor=0d0 | |
node(i)%mo=temp | |
node(i)%dmo=0 | |
node(i)%diffe=0d0 | |
node(i)%khold=0d0 | |
node(i)%kplast=0d0 | |
node(i)%kvol=0d0 | |
end do | |
!General parameters that depend on node parameters | |
rv=2*maxval(node(:)%da) | |
node(:)%hold=0 | |
r_max = (nd/ 0.64)**(1d0/3d0) * 0.4d0; | |
do i=1,nd | |
cels(i)%nunodes=1 | |
cels(i)%nodela=1 | |
allocate(cels(i)%node(1)) | |
call random_number(a) | |
r = r_max * a**(1d0/3d0); | |
call random_number(a) | |
phi = a * 2d0 * pi; | |
call random_number(a) | |
theta = acos(2d0 * a - 1); | |
node(i)%x=r * sin(theta) * cos(phi) | |
node(i)%y=r * sin(theta) * sin(phi) | |
node(i)%z=r * cos(theta) | |
node(i)%marge=0 | |
node(i)%tipus=3 | |
cels(i)%node(1)=i | |
node(i)%icel=i | |
node(i)%altre=0 | |
cels(i)%ctipus=3 | |
cels(i)%cex=node(i)%x;cels(i)%cey=node(i)%y;cels(i)%cez=node(i)%z | |
end do | |
!******* #3 DEFINING CELL PARAMETERS ******* | |
do i=1,ncels | |
cels(i)%fase=0d0 | |
mmae=node(cels(i)%node(1))%req | |
cels(i)%minsize_for_div=cels(i)%nunodes*2 | |
cels(i)%maxsize_for_div=10000 !>>> Is 5-2-14 | |
end do | |
do i=1,ncels !cells start with at random points of the cell cycle, so the divisions are not synchronous | |
!if(i<=7.or.(i>ncelsepi.and.i<=ncelsepi+7))then | |
call random_number(a) | |
cels(i)%fase=a | |
!end if | |
end do | |
!******* #4 DEFINING GENETIC PARAMETERS ******* | |
!Number of genes | |
ng=1 | |
call initiate_gene | |
!Gene parameters | |
!gen(:)%kindof= ; gen(:)%diffu= ; gen(:)%mu= | |
gen(1)%kindof=1 ; gen(1)%diffu=0d0 ; gen(1)%mu=0d0 ;gen(1)%name="does nothing" | |
call update_npag | |
node(:)%talone=0.0d0 | |
end subroutine |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Performance Comparison\n", | |
"\n", | |
"We compare the performance of our code to Chaste and EmbryoMaker. To this end we simulate cells with a limited interaction range, starting from a spherical, uncompressed, random distribution until the forces were calculated 1200 times. We use an Intel i7-4770 CPU @ 3.40GHz × 8 with an NVidia GeForce GTX 1060 6GB running Ubuntu 16.04." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"import pandas as pd\n", | |
"import seaborn as sns\n", | |
"import matplotlib.pyplot as plt" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"performance = pd.DataFrame({'Package': ['Chaste']*4 + ['EmbryoMaker']*3 + ['bolls']*5,\n", | |
" '# cells': [100, 250, 500, 1000] + [100, 1000, 10000] + [100, 1000, 10000, 55000, 100000],\n", | |
" 'Time [s]': [9, 32, 94, 4*60 + 35] + [0.55, 3.9, 48] + [0.3, 0.4, 0.7, 1.55, 2.85]})\n", | |
"\n", | |
"compilation = pd.DataFrame(index=['Chaste', 'EmbryoMaker', 'bolls'],\n", | |
" data={'Min [s]': [28, 13.8, 4],\n", | |
" 'Max [s]': [47, 15.2, 5.3]})" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<matplotlib.figure.Figure at 0x7fec9cf92be0>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"sns.set_context('paper')#, font_scale=1) # {paper, notebook, talk, poster}\n", | |
"plt.figure(figsize=(5, 5))\n", | |
"\n", | |
"plt.subplot2grid(shape=(3, 1), loc=(0, 0), rowspan=2)\n", | |
"plt.title('Simulation (1200 steps)')\n", | |
"plt.xlabel('# cells')\n", | |
"plt.ylabel('Time [s]')\n", | |
"for package, group in performance.groupby('Package'):\n", | |
" plt.loglog(group['# cells'], group['Time [s]'], label=package, marker='o')\n", | |
"\n", | |
"plt.subplot2grid(shape=(3, 1), loc=(2, 0))\n", | |
"plt.title('Compilation')\n", | |
"plt.xlabel('Time [s]')\n", | |
"plt.yticks(-np.arange(3), compilation.index)\n", | |
"for i, pkg in enumerate(compilation.index):\n", | |
" color = sns.color_palette(n_colors=i + 1)[-1]\n", | |
" plt.barh(-i, compilation.loc[pkg, 'Min [s]'], color=color, label=pkg)\n", | |
" plt.barh(-i, compilation.loc[pkg, 'Max [s]'], color=color, alpha=0.5)\n", | |
"\n", | |
"sns.despine()\n", | |
"plt.tight_layout()\n", | |
"plt.savefig('performance.svg')\n", | |
"plt.show()" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python [conda root]", | |
"language": "python", | |
"name": "conda-root-py" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.5.4" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Integrate N-body problem with limited range springs between all bodies | |
#include "../include/dtypes.cuh" | |
#include "../include/inits.cuh" | |
#include "../include/solvers.cuh" | |
#include "../include/vtk.cuh" | |
const auto L_0 = 0.75f; // Relaxed spring length | |
const auto n_cells = 1000; | |
const auto n_time_steps = 600u; // Half of Chaste, because 2nd order | |
const auto dt = 0.001f; | |
__device__ float3 spring(float3 Xi, float3 r, float dist, int i, int j) | |
{ | |
float3 dF{0}; | |
if (i == j) return dF; | |
if (dist > 1) return dF; | |
dF = r * (L_0 - dist) / dist; | |
return dF; | |
} | |
int main(int argc, const char* argv[]) | |
{ | |
// Prepare initial state | |
Solution<float3, Grid_solver> bolls{n_cells}; | |
random_sphere(L_0, bolls); | |
// Integrate positions | |
Vtk_output output("performance"); | |
for (auto time_step = 0; time_step <= n_time_steps; time_step++) { | |
bolls.copy_to_host(); | |
bolls.take_step<spring, friction_on_background>(dt); | |
output.write_positions(bolls); | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Copyright (c) 2017, European Molecular Biology Laboratory. | |
Copyright (c) 2005-2017, University of Oxford. | |
All rights reserved. | |
University of Oxford means the Chancellor, Masters and Scholars of the | |
University of Oxford, having an administrative office at Wellington | |
Square, Oxford OX1 2JD, UK. | |
This file is part of Chaste. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
* Redistributions of source code must retain the above copyright notice, | |
this list of conditions and the following disclaimer. | |
* Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
* Neither the name of the University of Oxford nor the names of its | |
contributors may be used to endorse or promote products derived from this | |
software without specific prior written permission. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
*/ | |
#pragma once | |
#include <cxxtest/TestSuite.h> | |
#include "CheckpointArchiveTypes.hpp" | |
#include "AbstractCellBasedTestSuite.hpp" | |
#include "CellsGenerator.hpp" | |
#include "GeneralisedLinearSpringForce.hpp" | |
#include "HoneycombMeshGenerator.hpp" | |
#include "NodeBasedCellPopulation.hpp" | |
#include "NodesOnlyMesh.hpp" | |
#include "OffLatticeSimulation.hpp" | |
#include "SmartPointers.hpp" | |
#include "SphereGeometryBoundaryCondition.hpp" | |
#include "TransitCellProliferativeType.hpp" | |
#include "UniformCellCycleModel.hpp" | |
#include "PetscSetupAndFinalize.hpp" | |
#include "AbstractSimpleGenerationalCellCycleModel.hpp" | |
class TestPerformance : public AbstractCellBasedTestSuite | |
{ | |
public: | |
void TestSpheroid() | |
{ | |
EXIT_IF_PARALLEL; | |
// Prepare initial state | |
auto t_0 = time(NULL); | |
auto n_cells = 100; | |
auto dist_to_nb = 0.75; | |
auto r_max = pow(n_cells / 0.64, 1. / 3) * dist_to_nb / 2; | |
std::vector<Node<3>*> nodes; | |
for (auto i = 0; i < n_cells; i++) | |
{ | |
auto r = r_max * pow(rand() / (RAND_MAX + 1.), 1. / 3); | |
auto phi = rand() / (RAND_MAX + 1.) * 2 * M_PI; | |
auto theta = acos(2. * rand() / (RAND_MAX + 1.) - 1); | |
nodes.push_back(new Node<3>(i, false, r * sin(theta) * cos(phi), | |
r * sin(theta) * sin(phi), r * cos(theta))); | |
} | |
NodesOnlyMesh<3> mesh; | |
mesh.ConstructNodesWithoutMesh(nodes, 1.0); // Distance cut-off | |
std::vector<CellPtr> cells; | |
MAKE_PTR(TransitCellProliferativeType, p_transit_type); | |
CellsGenerator<UniformCellCycleModel, 3> cells_generator; | |
cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes(), p_transit_type); | |
NodeBasedCellPopulation<3> cell_population(mesh, cells); | |
// Setup simulation | |
OffLatticeSimulation<3> simulator(cell_population); | |
simulator.SetOutputDirectory("TestPerformance"); | |
simulator.SetSamplingTimestepMultiple(100); // Writes twelve timesteps | |
simulator.SetEndTime(10.0); | |
simulator.SetNoBirth(true); | |
MAKE_PTR(GeneralisedLinearSpringForce<3>, p_force); | |
p_force->SetMeinekeDivisionRestingSpringLength(0.75); | |
simulator.AddForce(p_force); | |
// Run simulation | |
simulator.Solve(); | |
auto t_f = time(NULL); | |
auto duration = t_f - t_0; | |
if (duration < 60) | |
std::cout << duration << " seconds"; | |
else if (duration < 60 * 60) | |
std::cout << duration / 60 << "m " << duration % 60 << "s"; | |
else | |
std::cout << duration / 60 / 60 << "h " << duration % 60 * 60 << "m"; | |
std::cout << " taken." << std::endl; | |
std::cout << "Timestep: " << simulator.GetDt() << std::endl; // Is 0.00833333 | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment