<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://jtt94.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://jtt94.github.io/" rel="alternate" type="text/html" /><updated>2025-02-17T09:51:34-08:00</updated><id>https://jtt94.github.io/feed.xml</id><title type="html">James Thornton</title><subtitle>personal description</subtitle><author><name>James</name><email>jamestomthornton@gmail.com</email></author><entry><title type="html">A taxonomy of diffusion, flow and bridge matching through the lens of optimal transport</title><link href="https://jtt94.github.io/posts/2023/09/taxonomy/" rel="alternate" type="text/html" title="A taxonomy of diffusion, flow and bridge matching through the lens of optimal transport" /><published>2023-09-01T00:00:00-07:00</published><updated>2023-09-01T00:00:00-07:00</updated><id>https://jtt94.github.io/posts/2023/09/diffusion_flow_ot</id><content type="html" xml:base="https://jtt94.github.io/posts/2023/09/taxonomy/"><![CDATA[<p><img width="724" alt="BridgeOT" src="https://github.com/user-attachments/assets/b546d51c-9f34-4314-bef5-2c3781ab54d2" /></p>]]></content><author><name>James</name><email>jamestomthornton@gmail.com</email></author><category term="ot" /><category term="diffusion" /><category term="flowmatching" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Resource Management with Slurm</title><link href="https://jtt94.github.io/posts/2020/11/slurm/" rel="alternate" type="text/html" title="Resource Management with Slurm" /><published>2020-11-13T00:00:00-08:00</published><updated>2020-11-13T00:00:00-08:00</updated><id>https://jtt94.github.io/posts/2020/11/slurm</id><content type="html" xml:base="https://jtt94.github.io/posts/2020/11/slurm/"><![CDATA[<p><a href="https://slurm.schedmd.com/slurm.conf.html">slurm</a> (Simple Linux Utility for Resource Management) is a resouce manager for running compute jobs across multiple servers. Although this has the benefit of additional control, it imposes constraints on compute resources and constrains interaction with servers to the slurm interface, this can be a pain. This post aims to be a useful go-to guide to common slurm commands and examples of how slurm may be used without the pain.</p>

<h2 id="background">Background</h2>

<h2 id="commmon-commands">Commmon commands</h2>
<ul>
  <li>Remote Bash (debug)
Typically one may access a commandline interface on remote machines through debug partition. This would be equivalent of ssh’ing into a remote machine. 
    <ul>
      <li><code class="language-plaintext highlighter-rouge">srun --pty -t 0:30:00 --partition=&lt;machine&gt;-debug bash</code></li>
    </ul>
  </li>
  <li>Check partitions
    <ul>
      <li><code class="language-plaintext highlighter-rouge">sinfo</code>
        <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>greytail{thornton}% sinfo
PARTITION           AVAIL  TIMELIMIT  NODES  STATE NODELIST
swan01-debug*          up      30:00      1   idle swan01.cpu.stats.ox.ac.uk
swan02-debug           up      30:00      1   idle swan02.cpu.stats.ox.ac.uk
swan03-debug           up      30:00      1    mix swan03.cpu.stats.ox.ac.uk
swan11-debug           up      30:00      1   idle swan11.cpu.stats.ox.ac.uk
swan12-debug           up      30:00      1   idle swan12.cpu.stats.ox.ac.uk
grey01-debug           up      30:00      1   idle grey01.cpu.stats.ox.ac.uk
greyheron-debug        up      30:00      1   idle greyheron.stats.ox.ac.uk
greyplover-debug       up      30:00      1   idle greyplover.stats.ox.ac.uk
greywagtail-debug      up      30:00      1   idle greywagtail.stats.ox.ac.uk
greypartridge-debug    up      30:00      1   idle greypartridge.stats.ox.ac.uk
greyostrich-debug      up      30:00      1    mix greyostrich.stats.ox.ac.uk
grey-standard          up 7-00:00:00      4   idle greyheron.stats.ox.ac.uk,greypartridge.stats.ox.ac.uk,greyplover.stats.ox.ac.uk,greywagtail.stats.ox.ac.uk
grey-fast              up 7-00:00:00      1   idle grey01.cpu.stats.ox.ac.uk
grey-gpu               up 7-00:00:00      1    mix greyostrich.stats.ox.ac.uk
swan-1hr               up    1:00:00      1    mix swan03.cpu.stats.ox.ac.uk
swan-1hr               up    1:00:00      2   idle swan01.cpu.stats.ox.ac.uk,swan02.cpu.stats.ox.ac.uk
swan-6hrs              up    6:00:00      1    mix swan03.cpu.stats.ox.ac.uk
swan-6hrs              up    6:00:00      1   idle swan02.cpu.stats.ox.ac.uk
swan-2day              up 2-00:00:00      1    mix swan03.cpu.stats.ox.ac.uk
swan-large             up 7-00:00:00      2   idle swan11.cpu.stats.ox.ac.uk,swan12.cpu.stats.ox.ac.uk
stats-7day             up 7-00:00:00      1   idle emu.stats.ox.ac.uk
</code></pre></div>        </div>
      </li>
    </ul>
  </li>
  <li>Check running jobs
    <ul>
      <li><code class="language-plaintext highlighter-rouge">squeue</code>
        <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>greytail{thornton}% squeue
         JOBID PARTITION     NAME   ST       TIME  NODES NODELIST(REASON)
        845457 swan03-de     bash   R      14:54      1 swan03.cpu.stats.ox.ac.uk
        845455 swan03-de     bash   R      17:22      1 swan03.cpu.stats.ox.ac.uk
        845215 swan-2day      SCI   R    6:33:10      1 swan03.cpu.stats.ox.ac.uk
        845400  grey-gpu    job01   R    3:06:28      1 greyostrich.stats.ox.ac.uk
        845397  grey-gpu    job01   R    3:10:17      1 greyostrich.stats.ox.ac.uk
        841508  grey-gpu eff_n_12   R 1-07:35:22      1 greyostrich.stats.ox.ac.uk
        838246  grey-gpu    eff_n   R 2-18:29:05      1 greyostrich.stats.ox.ac.uk
</code></pre></div>        </div>
      </li>
    </ul>
  </li>
</ul>

<h2 id="running-scripts">Running Scripts</h2>
<ul>
  <li>Create a file <code class="language-plaintext highlighter-rouge">launch.sh</code> on head node</li>
  <li>Populate file with preamble to specify resources required
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>preamble = """#!/bin/bash
#SBATCH -A oxwasp
#SBATCH --time=20:00:00
#SBATCH --mail-user=james.thornton@stats.ox.ac.uk
#SBATCH --mail-type=ALL
#SBATCH --partition=grey-standard
#SBATCH --nodelist="greyheron.stats.ox.ac.uk"
#SBATCH --output="/tmp/slurm-JT-output"
#SBATCH --mem "15G"
#SBATCH --cpus-per-task 10
#SBATCH --gres=gpu:1

"""

</code></pre></div>    </div>
  </li>
  <li>Add commands to run something in the same file, after preamble (see below for example)</li>
  <li>Launch slurm job <code class="language-plaintext highlighter-rouge">sbatch launch.sh</code></li>
</ul>

<h2 id="hosting-a-jupyter-notebook">Hosting a Jupyter Notebook</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
#!/bin/bash
#SBATCH -A oxwasp                       # Account to be used, e.g. academic, acadrel, aims, bigbayes, opig, oxcsml, oxwasp, rstudent, statgen, statml, visitors
#SBATCH -J job01                          # Job name, can be useful but optional
#SBATCH --time=7-00:00:00                   # Walltime - run time of just 30 seconds
#SBATCH --mail-user=james.thornton@stats.ox.ac.uk     # set email address to use, change to your own email address instead of "me"
#SBATCH --mail-type=ALL                   # Caution: fine for debug, but not if handling hundreds of jobs!
#SBATCH --partition=grey-gpu                # Select the swan one hour partition
#SBATCH --nodelist=greyostrich.stats.ox.ac.uk
#SBATCH --output="/tmp/slurm-JT-output"
#SBATCH --mem 20g
#SBATCH --cpus-per-task 5
#SBATCH --gres=gpu:1

cd /data/greyostrich/oxwasp/oxwasp18/thornton

source ./miniconda3/bin/activate bridge
pip install tornado
python -m ipykernel install --user --name=bridge

python -m jupyter notebook --ip greyostrich.stats.ox.ac.uk --no-browser --port 8888

</code></pre></div></div>

<h2 id="python-interface-with-paramiko">Python Interface with Paramiko</h2>
<h3 id="set-up">Set-Up</h3>
<ul>
  <li>Install <code class="language-plaintext highlighter-rouge">parmiko</code> library for ssh utils</li>
  <li>Connect to slurm head node e.g. <code class="language-plaintext highlighter-rouge">greytail</code> via paramiko
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname='greytail')
</code></pre></div>    </div>
    <h3 id="launch-individual-commands">Launch individual commands</h3>
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>command = 'sinfo'
stdin, stdout, stderr = client.exec_command(command)
lines = stdout.readlines()
</code></pre></div>    </div>
    <h3 id="launch-scripts">Launch scripts</h3>
  </li>
  <li>Create sbatch file in Python
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>preamble = """#!/bin/bash
#SBATCH -A oxwasp
#SBATCH --time=20:00:00
#SBATCH --mail-user=james.thornton@stats.ox.ac.uk
#SBATCH --mail-type=ALL
#SBATCH --partition=grey-standard
#SBATCH --nodelist="greyheron.stats.ox.ac.uk"
#SBATCH --output="/tmp/slurm-JT-output"
#SBATCH --mem "15G"
#SBATCH --cpus-per-task 10
"""


command = preamble + "\n" + """

cd /data/localhost/oxwasp/oxwasp18/thornton
touch test_new_file2.txt
"""
</code></pre></div>    </div>
  </li>
  <li>Create new file on head node and write sbatch commands to file
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>slurm_wd = '/data/thornton'
slurm_file = 'test_batch.sh'
  
ftp = client.open_sftp()
ftp.chdir(slurm_wd)
file=ftp.file(slurm_file, "w", -1)
file.write(command)
file.flush()
ftp.close()
</code></pre></div>    </div>
  </li>
  <li>Launch slurm sbatch remotely
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sbatch_cmd = 'sbatch {0}'.format(os.path.join(slurm_wd, slurm_file))

stdin, stdout, stderr = client.exec_command(sbatch_cmd)
</code></pre></div>    </div>
  </li>
</ul>]]></content><author><name>James</name><email>jamestomthornton@gmail.com</email></author><category term="programming" /><category term="compute" /><summary type="html"><![CDATA[slurm (Simple Linux Utility for Resource Management) is a resouce manager for running compute jobs across multiple servers. Although this has the benefit of additional control, it imposes constraints on compute resources and constrains interaction with servers to the slurm interface, this can be a pain. This post aims to be a useful go-to guide to common slurm commands and examples of how slurm may be used without the pain.]]></summary></entry><entry><title type="html">Conda Environments</title><link href="https://jtt94.github.io/posts/2020/11/venv/" rel="alternate" type="text/html" title="Conda Environments" /><published>2020-11-08T00:00:00-08:00</published><updated>2020-11-08T00:00:00-08:00</updated><id>https://jtt94.github.io/posts/2020/11/Virtual%20Envs</id><content type="html" xml:base="https://jtt94.github.io/posts/2020/11/venv/"><![CDATA[<p>Virtual environments are a convenient way to manage library dependencies, environment variables, and ensure reproducibility. There are a couple of approaches to this: <code class="language-plaintext highlighter-rouge">virtualenv</code>,<code class="language-plaintext highlighter-rouge">conda</code>, and <code class="language-plaintext highlighter-rouge">docker</code> – see <a href="https://towardsdatascience.com/guide-of-choosing-package-management-tool-for-data-science-project-809a093efd46">here</a> for a discussion. This post will focus on <code class="language-plaintext highlighter-rouge">conda</code>, and give a few practical commands to get up and running.</p>

<ul>
  <li>Download and install miniconda
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sh curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o "$conda_dir/miniconda.sh"
sh -x miniconda.sh -b -p "./miniconda3" 
</code></pre></div>    </div>
  </li>
</ul>

<p><strong>Note:</strong> The default conda set-up requires editing the .bashrc file and setting environment variables to point to the conda executable. This is a pain when dealing with multiple servers, fortunately there are ways around this and the commands given here will not rely on editing the .bashrc.</p>

<h2 id="basic-commands">Basic commands</h2>
<ul>
  <li><strong>Create environment called conda_venv, for Python version 3.8</strong> <br />
<code class="language-plaintext highlighter-rouge">./miniconda3/bin/conda create -n conda_venv python=3.8</code></li>
  <li><strong>Activate environment</strong> <br />
<code class="language-plaintext highlighter-rouge">source ./miniconda3/bin/activate conda_venv</code></li>
  <li><strong>De-activate environment</strong> <br />
<code class="language-plaintext highlighter-rouge">conda deactivate conda_venv</code><br />
This adds the environment executables such as Python, pip and conda to the executable path.</li>
  <li><strong>Install/ uninstall:</strong> (once env is activated)
    <ul>
      <li>Through conda: <code class="language-plaintext highlighter-rouge">conda install -c anaconda numpy</code></li>
      <li>Through pip: <code class="language-plaintext highlighter-rouge">pip install numpy</code> <br />
<strong>Note:</strong> this pip executable will be installed when installing python, and the libraries installed via pip will be specific to the conda environment and not the global environment</li>
    </ul>
  </li>
  <li>
    <p><strong>Export installed dependencies to file</strong><br />
<code class="language-plaintext highlighter-rouge">conda env export &gt; env.yaml</code></p>
  </li>
  <li><strong>Install dependencies from file</strong>: this is actually creating an environment from a yaml file, so no need to create an empty env first
<code class="language-plaintext highlighter-rouge">conda env create -f environment.yml</code></li>
</ul>

<h2 id="conda-environments-with-jupyter-notebook">Conda environments with jupyter notebook</h2>
<ul>
  <li><strong>Make sure jupyter is installed</strong> <br />
<code class="language-plaintext highlighter-rouge">pip install jupyter</code></li>
  <li><strong><em>Add kernel for environment</em></strong> <br />
<code class="language-plaintext highlighter-rouge">python -m ipykernel install --user --name=conda_venv</code>
<img src="/images/nb_snap.PNG" alt="conda_kernel" /></li>
  <li>For windows <code class="language-plaintext highlighter-rouge">conda install pywin32</code></li>
</ul>]]></content><author><name>James</name><email>jamestomthornton@gmail.com</email></author><category term="programming" /><category term="software" /><category term="python" /><summary type="html"><![CDATA[Virtual environments are a convenient way to manage library dependencies, environment variables, and ensure reproducibility. There are a couple of approaches to this: virtualenv,conda, and docker – see here for a discussion. This post will focus on conda, and give a few practical commands to get up and running.]]></summary></entry><entry><title type="html">Speeding up Python with C++ and Pybind11</title><link href="https://jtt94.github.io/posts/2020/08/pythoncpp/" rel="alternate" type="text/html" title="Speeding up Python with C++ and Pybind11" /><published>2020-08-01T00:00:00-07:00</published><updated>2020-08-01T00:00:00-07:00</updated><id>https://jtt94.github.io/posts/2020/08/Python%20C++</id><content type="html" xml:base="https://jtt94.github.io/posts/2020/08/pythoncpp/"><![CDATA[<p>A how-to set-up guide for using C++ with Python with Pybind11.</p>

<p>Instructions are based on <a href="https://docs.microsoft.com/en-us/visualstudio/python/working-with-c-cpp-python-in-visual-studio?view=vs-2019#create-the-core-c-projects">this</a> guide with some of the kinks worked out for common problems.</p>

<p>I am using <a href="https://docs.conda.io/en/latest/miniconda.html">conda</a> to manage dependencies and using the <a href="https://visualstudio.microsoft.com/downloads/">MS Visual Studio 2019 IDE</a> for C++.</p>

<p>Code <a href="https://github.com/JTT94/py_cpp_example">here</a></p>

<h3 id="1-set-up">1) Set-Up</h3>

<ul>
  <li>Create project environment, I will be using conda but other environment managers are available. Go to a command line and enter the following:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> conda create -n venv
 conda activate venv
 conda install pip
 pip install pybind11
</code></pre></div>    </div>
  </li>
  <li>Configure MS Visual Studio C++ settings
    <ul>
      <li>Create new C++ project called “superfastcode”</li>
      <li>Configure project properties, go to ribbon, <code class="language-plaintext highlighter-rouge">Project &gt; superfastcode Properties</code></li>
    </ul>
  </li>
</ul>

<table>
  <thead>
    <tr>
      <th>Tab</th>
      <th>Property</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>General</td>
      <td>General &gt; Target Name</td>
      <td>Specify the name of the module as you want to refer to it from Python in from…import statements. You use this same name in the C++ when defining the module for Python. If you want to use the name of the project as the module name, leave the default value of $(ProjectName).</td>
    </tr>
    <tr>
      <td> </td>
      <td>General (or Advanced) &gt; Target Extension</td>
      <td>.pyd</td>
    </tr>
    <tr>
      <td> </td>
      <td>Project Defaults &gt; Configuration Type</td>
      <td>Dynamic Library (.dll)</td>
    </tr>
    <tr>
      <td>C/C++ &gt; General</td>
      <td>Additional Include Directories</td>
      <td>Add the Python include folder as appropriate for your installation, for example C:\Users\james\Miniconda3\envs\venv\include.</td>
    </tr>
    <tr>
      <td>C/C++ &gt; Code Generation</td>
      <td>Runtime Library</td>
      <td>Multi-threaded DLL (/MD) (see Warning below)</td>
    </tr>
    <tr>
      <td>Linker &gt; General</td>
      <td>Additional Library Directories</td>
      <td>Add the Python libs folder containing .lib files as appropriate for your installation, for example, C:\Users\james\Miniconda3\venv\libs. (Be sure to point to the libs folder that contains .lib files, and not the Lib folder that contains .py files.)</td>
    </tr>
  </tbody>
</table>

<h3 id="2-write-some-code">2) Write some code</h3>
<ul>
  <li>Within MS Visual Studio, add a .cpp file called “module.cpp”. To do this, go to Solution Explorer, Source Files, then select ‘add’ and choose the .cpp file</li>
  <li>Copy the following code
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#include &lt;cmath&gt;
#include &lt;pybind11/pybind11.h&gt;

const double e = 2.7182818284590452353602874713527;

double sinh_impl(double x) {
    return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x));
}

double cosh_impl(double x) {
    return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x));
}

double tanh_impl(double x) {
    return sinh_impl(x) / cosh_impl(x);
}

namespace py = pybind11;

PYBIND11_MODULE(superfastcode, m) {
    m.def("fast_tanh", &amp;tanh_impl, R"pbdoc(
        Compute a hyperbolic tangent of a single argument expressed in radians.
    )pbdoc");

#ifdef VERSION_INFO
    m.attr("__version__") = VERSION_INFO;
#else
    m.attr("__version__") = "dev";
#endif
}
</code></pre></div>    </div>
  </li>
  <li>Check the solution builds, in MS VS, go to ribbon <code class="language-plaintext highlighter-rouge">ctrl+shift+B</code> or Build &gt; build solution, ensuring the correct configuration.</li>
</ul>

<h3 id="3-allow-access-to-your-c-code-from-python">3) Allow access to your C++ code from Python</h3>
<ul>
  <li>Create a setup.py file to expose function to Python
    <ul>
      <li>Add a .cpp file as above to the Source Files, but rename it to <code class="language-plaintext highlighter-rouge">setup.py</code></li>
      <li>Copy the following
        <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import os, sys

from distutils.core import setup, Extension
from distutils import sysconfig

cpp_args = ['-std=c++11', '-stdlib=libc++', '-mmacosx-version-min=10.7']

sfc_module = Extension(
    'superfastcode', sources=['module.cpp'],
    include_dirs=['pybind11/include'],
    language='c++',
    extra_compile_args=cpp_args,
    )

setup(
    name='superfastcode',
    version='1.0',
    description='Python package with superfastcode C++ extension (PyBind11)',
    ext_modules=[sfc_module],
)
</code></pre></div>        </div>
      </li>
    </ul>
  </li>
  <li>Back to the commandline with environment venv activated, install the C++ module using pip
    <ul>
      <li>Navigate to the directory containing ‘setup.py’ on the terminal</li>
      <li>Enter the following in ther terminal: <code class="language-plaintext highlighter-rouge">pip install . </code></li>
    </ul>
  </li>
  <li>Check it works
    <ul>
      <li>Again on the command line, go to a python interpretter for the venv environment
        <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> python 
 &gt;&gt; from superfastcode import fast_tanh
</code></pre></div>        </div>
      </li>
    </ul>
  </li>
</ul>

<h2 id="common-issues">Common Issues</h2>
<ul>
  <li>32 bit vs 64 bit
    <ul>
      <li>Errors such as “fatal error LNK1112: module machine type ‘x64’ conflicts with target machine type ‘X86’” are due to some bit configuratio mis-match</li>
      <li>Ensure that the bit version of Python and hence pybind11 installed matches the C++ bit chosen. At time of writing I installed Python 3.8 64 bit by default so chose x64 in the MS Visual Studio Configuaration Manager.</li>
      <li>Some more debugging issues <a href="https://stackoverflow.com/questions/3563756/fatal-error-lnk1112-module-machine-type-x64-conflicts-with-target-machine-typ">here</a></li>
    </ul>
  </li>
  <li>Cannot find pybind11.h
    <ul>
      <li>Ensure the Python “include” directory, which includes “pybind11.h”, is entered in the “Additional include directories” in the Project Properties setup as detailed above. Also ensure that project is being built using the configuration such as Platform x64 corresponding to the project properties with the correct include directories</li>
    </ul>
  </li>
</ul>

<h2 id="working-with-c-and-numpy">Working with C++ and NumPy</h2>

<p>NumPy arrays may be accessed through the protocol buffer. See more examples in the pybind11 docs <a href="https://pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html">here</a>.</p>

<ul>
  <li>Copy full C++ code below into “module.cpp”.</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    #include &lt;cmath&gt;
    #include &lt;pybind11/pybind11.h&gt;
    #include &lt;pybind11/numpy.h&gt;

    const double e = 2.7182818284590452353602874713527;

    double sinh_impl(double x) {
        return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x));
    }

    double cosh_impl(double x) {
        return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x));
    }

    double tanh_impl(double x) {
        return sinh_impl(x) / cosh_impl(x);
    }

    namespace py = pybind11;

    py::array_t&lt;double&gt; add_arrays(py::array_t&lt;double&gt; input1, py::array_t&lt;double&gt; input2) {
        py::buffer_info buf1 = input1.request(), buf2 = input2.request();

        if (buf1.ndim != 1 || buf2.ndim != 1)
            throw std::runtime_error("Number of dimensions must be one");

        if (buf1.size != buf2.size)
            throw std::runtime_error("Input shapes must match");

        /* No pointer is passed, so NumPy will allocate the buffer */
        auto result = py::array_t&lt;double&gt;(buf1.size);

        py::buffer_info buf3 = result.request();

        double* ptr1 = (double*)buf1.ptr,
            * ptr2 = (double*)buf2.ptr,
            * ptr3 = (double*)buf3.ptr;

        for (size_t idx = 0; idx &lt; buf1.shape[0]; idx++)
            ptr3[idx] = ptr1[idx] + ptr2[idx];

        return result;
    }

    PYBIND11_MODULE(superfastcode, m) {
        m.def("fast_tanh", &amp;tanh_impl, R"pbdoc(
            Compute a hyperbolic tangent of a single argument expressed in radians.
        )pbdoc");
        m.def("add_arrays", &amp;add_arrays, "Add two NumPy arrays");

    #ifdef VERSION_INFO
        m.attr("__version__") = VERSION_INFO;
    #else
        m.attr("__version__") = "dev";
    #endif
    }
</code></pre></div></div>

<ul>
  <li>Test in Python as follows, from terminal or otherwise
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python
&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; from superfastcode import add_arrays
&gt;&gt;&gt; a = np.array([1.,2.,3.])
&gt;&gt;&gt; b = a.copy()
&gt;&gt;&gt; add_arrays(a,b)
array([2., 4., 6.])
</code></pre></div>    </div>
  </li>
</ul>]]></content><author><name>James</name><email>jamestomthornton@gmail.com</email></author><category term="python" /><category term="cpp" /><category term="programming" /><category term="software" /><summary type="html"><![CDATA[A how-to set-up guide for using C++ with Python with Pybind11.]]></summary></entry></feed>