getkeops / keops

KErnel OPerationS, on CPUs and GPUs, with autodiff and without memory overflows
https://www.kernel-operations.io
MIT License
1.04k stars 64 forks source link

How to ship pre-built binaries? #85

Closed maddenp closed 1 year ago

maddenp commented 4 years ago

I am trying to follow the instructions for installing keops / pykeops from source from a git clone, here: http://www.kernel-operations.io/keops/python/installation.html?highlight=cmake#from-source-using-git. I don't understand where /path/to/libkeops should come from: Normally I'd assume that I need to build the underlying library before trying to use the Python bindings, but I'm not finding instructions for that. If I start at the top-level keops installation instructions (http://www.kernel-operations.io/keops/introduction/installation.html), I immediately find myself back at the Python instructions. Assuming I'm not misunderstanding the requirements, could someone point me to the build instructions?

Ultimately, my goal is to build a conda package with keops and its Python bindings (for colleagues -- unfortunately I know little about keops' problem domain), so if I'm able to build the core library, I'd then be curious about how to install the Python code, presumably via setup.py. Out of curiosity I tried running python setup.py install and was met immediately with

FileNotFoundError: [Errno 2] No such file or directory: '/<path>/keops/pykeops/keops/lib/sequences/include/tao/seq/

Are there instructions elsewhere on installing the Python bindings after the core library is built?

My vague understanding is that (py)keops needs compilers available at run time to build kernels for execution, and so needs an environment in which the various dependencies (e.g. g++, nvcc) are available. That's normally easy enough to arrange with conda environments, but it seems that some other preparation (core library build, and maybe Python library installation) need to be performed first. Is that right? I'd be grateful for any corrections if I've misunderstood, and certainly for pointers to documentation I've missed.

Thanks in advance!

maddenp commented 4 years ago

I'm looking at Jenkinsfile now -- that might help me.

jeanfeydy commented 4 years ago

Hi @maddenp ,

Thanks for your interest in the library! First of all, with respect to your error: did you clone the repository using the --recursive option, as documented here? The sequences/include/tao/seq folder should be imported recursively from the sequences sub-repository.

Going further: KeOps compiles binaries on-the-fly, whenever the engine meets a new "formula" or reduction of a symbolic LazyTensor. As of today, no build is required at installation time: compilation happens when a script is executed for the first time on a machine.

Now, if you intend to ship binaries to colleagues who don't have a working C++ or CUDA environment, this may be a problem. As of today, the best workaround is to pre-compile the routines on your machine (they will be stored in the PyKeOps build folder, that you can find with import pykeops; print(pykeops.bin_folder)) and distribute them to users directly: if PyKeOps finds the required binaries in the KeOps build folder, it won't try to call the compiler. I don't have much experience with conda, but assume that this is do-able. Making this pre-compilation + deployment step easy for "downstream" packages is something that we are targeting for future releases: @joanglaunes and @bcharlier may have more to say on this. What do you think?

Best regards, Jean

maddenp commented 4 years ago

Hi @jeanfeydy -- thank you for your help.

I should have posted again to note that I'd made some progress on this. As you suspected, I'd neglected to add the --recursive option to my git clone, but I also found the git submodule update --init command in Jenkinsfile and, after loading the git submodules correctly, python setup.py install worked fine for me.

At the moment, also borrowing from Jenkinsfile, I have been doing a cmake / make step to produce keops.so, and bundling that into my conda package. Is this step unnecessary, or will keops.so (assuming it's needed) also be compiled on-the-fly? This step takes a little time, so compiling it once and packaging it seems worthwhile.

The keops build / run strategy is starting to come into focus for me, but may I ask two related questions?

  1. What determines whether code is built for and run on GPU vs CPU? Is GPU hardware actually required at build time? For example, I can create a conda environment that has all required dependency libraries, as well as nvcc, etc. But will it be possible to build binaries on, for example, a CI system with no actual GPU? Of course, they will need to run on a system with a GPU, but we normally build our conda packages on a CI system and then deploy/run them on appropriate hardware elsewhere. I (maybe obviously) don't have a lot of GPU experience, but I thought it possible that the build phase might only require the right software. Assuming this might work, do need to set an environment variable (CXX, maybe) to specify a CUDA build? I think I tried export CXX=nvcc, but just see a message like No GPU detected. USE_CUDA set to FALSE. Do I really need a GPU present just to build?

  2. Is it possible to set as well as query pykeops.bin_folder, i.e. can I arrange for compiled kernels to be placed in a specific location? That would help with deployment, avoid duplication between users of the same application using keops, etc. I might or might not also package compiled kernels with conda, but at least controlling their location in the filesystem would be helpful.

Thanks again for your help explaining this. I would be happy to share my conda-packaging results here in case others find them useful, once I have it working correctly.

joanglaunes commented 4 years ago

Hello @maddenp , About your first question, currently the cmake script does require to have a working Gpu on the system because it runs a small Cuda program to query the Gpu devices installed and detect some parameters for each one (this can be seen in file keops/cuda.cmake). More precisely the parameters detected are the number of threads per block and the maximum shared memory per block. These parameters are then passed to the compiler as macro definitions. In the first versions of KeOps we were doing this detection at runtime, but we found out that it was slowing down the execution. Maybe it is no longer true with recent versions of Cuda though.... Anyway these constants do not differ that much between Gpu cards, and we could easily add an option where we bypass this device query and provide default values that would be ok for all cards. But then maybe there are other things that may prevent from compiling the Gpu code on a system without Gpu. I think @bcharlier would know more about this. About your second question, in pykeops/common/set_path.py there is a set_bin_folder for this purpose, so it should be ok if you use it I guess.

Best regards, Joan

maddenp commented 4 years ago

Thank you @joanglaunes.

It looks like set_bin_folder() does exactly what I need.

I think it would be valuable to have GPU default values as an option; even better (for my use case) might be a way to execute the logic that determines optimal parameters manually, and then to provide these parameters to keops at run time. We could then collect the optimal parameters from the GPU we will later execute on, but use a no-GPU CI system to actually build the keops conda package. For now, I will try to do my conda build manually on a GPU system, but it would be great to do this via CI in the future.

Back to my current attemps to package, I have disabled running cmake and conda-build/package time, so that the only things from the keops git repo present packaged by conda are those installed by running setup.py, which I hope is the correct way to install keops / pykeops.

In a conda environment with (I think) all the pykeops dependencies available, I can now get

>>> pykeops.test_numpy_bindings()
...
pyKeOps with numpy bindings is working!

and

>>> pykeops.test_torch_bindings()
...
pyKeOps with torch bindings is working!

and if I previously did pykeops.verbose = True, I also get an information block that includes some messages indicating that GPU support might be correct:

-- The CXX compiler identification is GNU 8.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /dev/shm/pm/miniconda/envs/keops/bin/x86_64-conda-linux-gnu-c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Compute properties automatically set to: -DMAXIDGPU=0;-DMAXTHREADSPERBLOCK0=1024;-DSHAREDMEMPERBLOCK0=49152
-- The CUDA compiler identification is NVIDIA 10.1.243
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Check for working CUDA compiler: /dev/shm/pm/miniconda/envs/keops/bin/nvcc - skipped
-- Detecting CUDA compile features
-- Detecting CUDA compile features - done
-- The CUDA Host CXX Compiler: /dev/shm/pm/miniconda/envs/keops/bin/x86_64-conda-linux-gnu-c++
-- Autodetected CUDA architecture(s):  6.0
-- Using shared_obj_name: libKeOpstorch007a6dd708
-- First i variables detected is 0
-- First j variables detected is 1
-- Compiled formula is Sum_Reduction(SqNorm2(x - y),1); auto x = Vi(0,3); auto y = Vj(1,3); where the number of args is 2.
-- Found PythonInterp: /dev/shm/pm/miniconda/envs/keops/bin/python3.7 (found suitable version "3.7.8", minimum required is "3.7") 
-- Found PythonLibs: /dev/shm/pm/miniconda/envs/keops/lib/libpython3.7m.so
-- pybind11 v2.3.dev1
-- Performing Test HAS_FLTO
-- Performing Test HAS_FLTO - Success
-- LTO enabled
-- Configuring done
-- Generating done
-- Build files have been written to: /users/PYS0343/pmadden/.cache/pykeops-1.4-cpython-37/build-libKeOpstorch007a6dd708

So this looks promising.

I'll note, in case it helps someone, that I did unset CFLAGS CMAKE_ARGS CMAKE_PREFIX_PATH CXXFLAGS DEBUG_CFLAGS DEBUG_CXXFLAGS LDFLAGS (this may be unsetting more than necessary, I'll try to trim this to the minimum) as set by conda, because otherwise I got compilation errors when pykeops tries to compile.

I do stil get a block of warnings, though, all similar to:

  Policy CMP0104 is not set: CMAKE_CUDA_ARCHITECTURES now detected for NVCC,
  empty CUDA_ARCHITECTURES not allowed.  Run "cmake --help-policy CMP0104"
  for policy details.  Use the cmake_policy command to set the policy and
  suppress this warning.

  CUDA_ARCHITECTURES is empty for target "fshape_gpu".

I'm happy to share more environment information (specific package versions, etc.) if it would be helpful.

joanglaunes commented 4 years ago

Hello @maddenp , About your previous question, I just suppressed the line (in the CMake code) that caused Cuda to be disabled when no Gpu device was found, and I think this should be enough to compile on a CI without Gpu installed. But I cannot check it myself because I do not have any system with Cuda and no Gpu to test. So if you can try it, please let us know if it works. Technically it means CMake will not pass any macro defintion to the compiler, and then in the C++ code, in the file keops/core/utils/CudaSizes.h, the parameters should be set to default values : 1024 for nb of threads per block, and 49152 for shared mem per block).This will be ok for all cards. Maybe later we could add the possibility to pass optimal parameters at runtime, but this is currently really not important I think. In fact currently in KeOps we set a default upper limit of 192 for Cuda block sizes, and the parameters of the Gpu card have an influence only in the case where the formula implies many variables or variables with large dimensions, so that the block size has to be set to a lower value in order not so saturate memory. But in most typical use cases this is not true, and the value 192 will be used whatever the card. And even if the block size has to be decreased, it will cause only a small decrease of performance unless the block size gets to very small values like below 10. Also this value of 192 was set somewhat arbitrary, we should investigate more carefully its influence on performance depending on the formula.

maddenp commented 4 years ago

I'll test the no-GPU build and share the results here. Thanks for the ideas.

I think I spoke too soon about the alternate binaries path, though. pykeops.set_bin_dir() does set the directory, but things fail later:

% rm -rf /tmp/keops/ ~/.cache/pykeops-1.4-cpython-37/
% python
Python 3.7.8 | packaged by conda-forge | (default, Jul 31 2020, 02:25:08) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pykeops
>>> pykeops.set_bin_folder('/tmp/keops')
>>> pykeops.bin_folder
'/tmp/keops/'
>>> pykeops.clean_pykeops()
>>> pykeops.test_numpy_bindings()
...
ModuleNotFoundError: No module named 'libKeOpsnumpyd46837e05c'

However, it does look like the .so file was created where specified:

% tree /tmp/keops
/tmp/keops
├── keops_hash.log
├── libKeOpsnumpyd46837e05c.cpython-37m-x86_64-linux-gnu.so
└── libKeOpsnumpyd46837e05c.so

0 directories, 3 files

Also, despite changing the path, the directory under ~/.cache still gets created (though it remains empty):

% test -d ~/.cache/pykeops-1.4-cpython-37/ && echo exists
exists

This makes me wonder whether the default path is still being used in some places despite setting bin_folder.

maddenp commented 4 years ago

I patched the keops tree (see the patch file, below) at conda build time and was able to build CUDA binary kernels on a non-GPU system, as suggested.

My conda recipe looks like this:

.
├── etc
│   └── conda
│       ├── activate.d
│       │   └── activate.sh
│       └── deactivate.d
│           └── deactivate.sh
└── recipe
    ├── build.sh
    ├── meta.yaml
    └── patch

with etc/conda/activate.d/activate.sh

export TORCH_USE_RTLD_GLOBAL=YES # see https://github.com/getkeops/keops/issues/59
unset CXXFLAGS # flags set by the conda compiler packages are problematic for keops

etc/conda/deactivate.d/deactivate.sh

unset TORCH_USE_RTLD_GLOBAL # see https://github.com/getkeops/keops/issues/59

recipe/build.sh

set -eux
git submodule update --init
python setup.py install --single-version-externally-managed --record=record.txt --prefix=$PREFIX
rsync -av $(readlink -f $RECIPE_DIR/..)/etc/ $PREFIX/etc/

recipe/meta.yaml

{% set python = 'python 3.7' %}
{% set version = '1.4' %}

package:
  name: pykeops
  version: {{ version }}

build:
  number: 0

requirements:
  build:
    - numpy # because setup.py somehow imports numpy
    - {{ python }}
  run:
    - cmake >=3.10
    - cudatoolkit-dev >=10.0
    - gputil
    - numpy
    - pytorch 1.5.*
    - {{ compiler('cxx') }} 8.*
    - {{ python }}

source:
  git_url: https://github.com/getkeops/keops.git
  git_rev: v{{ version }}
  patches:
      - patch

about:
  license: OTHER

and recipe/patch

diff --git a/keops/cuda.cmake b/keops/cuda.cmake
index 748d7fa1..6973edc5 100644
--- a/keops/cuda.cmake
+++ b/keops/cuda.cmake
@@ -61,15 +60,0 @@ if(CUDA_FOUND AND USE_CUDA)
-  # run the detection
-  if(NOT gpu_compute_props)
-    caffe_detect_installed_gpus(gpu_compute_props)
-    if(NOT gpu_compute_props)
-      set(USE_CUDA FALSE)
-      message(STATUS "No GPU detected. USE_CUDA set to FALSE.")
-    else()
-      message(STATUS "Compute properties automatically set to: ${gpu_compute_props}")
-      add_definitions(${gpu_compute_props})
-    endif()
-  else()
-    message(STATUS "Compute properties manually set to ${gpu_compute_props}")
-    add_definitions(${gpu_compute_props})
-  endif()

The package can be built with conda build -c pytorch -c conda-forge recipe and then an environment created with conda create -y -n pykeops -c local -c pytorch -c conda-forge pykeops=1.4.

I hope this might be useful to someone.

I think the only thing missing now (unless my previous post was wrong) for an ideal deployment story is the ability to control the location of the compiled binaries.

jeanfeydy commented 4 years ago

Hi @maddenp ,

Thanks a lot for this very detailed report! @joanglaunes , @bcharlier will definitely discuss this over the next few weeks: we will document this properly, and try to make the deployment process as easy as possible for the 1.5 release.

Best regards, and thanks again, Jean

maddenp commented 4 years ago

One more thing occurred to me, which may be another motivation for a custom output directory capability: We use an HPC with a batch-queueing system to get access to nodes with GPUs, where we would then run keops. Like most HPCs, the filesystems (including the home filesystem) are networked and shared across all nodes. So, it may be the case that two batch jobs running concurrently will be building the same kernel and writing it to the same location at the same time -- a race condition which could lead to corruption. So it would seem that being able to control the storage location would be a prerequisite for parallel keops jobs. Thanks for your consideration.

joanglaunes commented 4 years ago

Hello @maddenp, Indeed definitely the custom folder setting is buggy, it seems to be a problem with the importlib module. I think @bcharlier will have more insight on this. Also he has already dealt with the case of a server with multiple GPU nodes. Unfortunately both of us are on vacations at the moment ! We will come back to you as soon as possible.

bcharlier commented 4 years ago

Hi everyone,

commit 2c96e93e should fix the pb with the set_bin_path() function:

>>> import pykeops
>>> pykeops.set_bin_folder("~/toto/../tutu") # create the dir  /home/bcharlier/tutu and put the bin there
>>> pykeops.clean_pykeops()
>>> pykeops.test_numpy_bindings()
Compiling libKeOpsnumpyd46837e05c in /home/bcharlier/tutu/build-libKeOpsnumpyd46837e05c:
       formula: Sum_Reduction(SqNorm2(x - y),1)
       aliases: x = Vi(0,3); y = Vj(1,3); 
       dtype  : float64
... Generated /home/bcharlier/tutu/build-libKeOpsnumpyd46837e05c/CMakeFiles/keopslibKeOpsnumpyd46837e05c.dir/keops/core/./keopslibKeOpsnumpyd46837e05c_generated_link_autodiff.cu.o successfully.
Done.

pyKeOps with numpy bindings is working!

>>> import os
>>> os.listdir(pykeops.bin_folder)
['libKeOpsnumpyd46837e05c.so', 'libKeOpsnumpyd46837e05c.cpython-38-x86_64-linux-gnu.so', 'build-libKeOpsnumpyd46837e05c', 'keops_hash.log']

Remember that you will need two .so files for a given formula : ['libKeOps.so', 'libKeOps.cpython-38-x86_64-linux-gnu.so']. You should be able to move those files anywhere you need, provided they are in the same dir (and this dir is in the python_path...).

maddenp commented 4 years ago

@bcharlier This worked for me in my tests, thank you. It would be nice if the ~/.cache/pykeops-1.4.1-cpython-37 directory were not created when the user is overriding the bin path, but that is a minor point and not a blocker.

trenta3 commented 4 years ago

I've played with keops a bit on google colab and wanted to integrate into my models in pytorch, but unfortunately I failed to install it with conda and the official instructions until I found this thread and run the conda recipe of @maddenp, thanks a lot!

I think that deploying conda packages on every release should definitely be considered to ease the usage of this wonderful package and I look forward to see them for the v1.5 release.

bcharlier commented 4 years ago

At the moment, also borrowing from Jenkinsfile, I have been doing a cmake / make step to produce keops.so, and bundling that into my conda package. Is this step unnecessary, or will keops.so (assuming it's needed) also be compiled on-the-fly? This step takes a little time, so compiling it once and packaging it seems worthwhile.

@maddenp you don't need to compile keops.so for the python bindings.

maddenp commented 4 years ago

@bcharlier Thank you, yes, I did finally figure that out, but I'm glad you mentioned it here in case others are confused as I was.

bcharlier commented 4 years ago

it would be nice if the ~/.cache/pykeops-1.4.1-cpython-37 directory were not created when the user is overriding the bin path, but that is a minor point and not a blocker.

@maddenp done in 724bcf2fe19a0f122ab747ba65494054e42549d3

bcharlier commented 4 years ago

@maddenp , @trenta3 : by chance, one of you guys have some time to make a PR with a conda recipe script? I don't know much on conda stuff... But with your help, it seems to be easy to deploy this.

trenta3 commented 4 years ago

I'm actually more of a user of conda rather than a recipe builder, I just tried out the recipe given by @maddenp and it worked. I tried adding a test section to it but I'm failing in doing it. I guess @maddenp would be better qualified, although if he refuses I guess I could figure something out

maddenp commented 4 years ago

@bcharlier I think a good approach for conda packaging might be to integrate with conda-forge, which would provide pre-built packages to your users (and, of course, the recipe would be available in the conda-forge "feedstock" GitHub repo, so others could also take that and use it however they like).

I haven't contributed feedstock code to conda-forge, but the process is probably straightforward. I have used conda-forge packages extensively, and have worked with their (heroic volunteer) maintainers on reporting issues, testing fixes, etc.

So, assuming my company (which wants to use pykeops!) supports me in the small effort to create a pykeops conda-forge package, I would offer to help with that. I may only be able to provide a Linux build, though, and others would have to contribute Mac and Windows additions if they needed those. The feedstock repos are all public on GitHub, so anyone can contribute.

I'll follow up here if I get some news on this from my company. And please let me know if the idea seems helpful to you.

maddenp commented 4 years ago

There appears to have been a regression between 2c96e93e06c3d0de6ed46baf03dafb56917ef17d, mentioned in https://github.com/getkeops/keops/issues/85#issuecomment-678653887, and https://github.com/getkeops/keops/commit/724bcf2fe19a0f122ab747ba65494054e42549d3, mentioned in https://github.com/getkeops/keops/issues/85#issuecomment-682409061.

Using the former (and note that I am not doing anything to change bin_folder, to keep things simple), I get:

>>> pykeops.test_torch_bindings()
Compiling libKeOpstorch9115532fd5 in /users/PYS0343/pmadden/.cache/pykeops-1.4.1-cpython-37/build-libKeOpstorch9115532fd5:
       formula: Sum_Reduction(SqNorm2(x - y),1)
       aliases: x = Vi(0,3); y = Vj(1,3);
       dtype  : float32
... -- The CXX compiler identification is GNU 8.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /users/PYS0343/pmadden/.conda/envs/foo/bin/x86_64-conda-linux-gnu-c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Compute properties automatically set to: -DMAXIDGPU=0;-DMAXTHREADSPERBLOCK0=1024;-DSHAREDMEMPERBLOCK0=49152
-- The CUDA compiler identification is NVIDIA 10.1.243
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Check for working CUDA compiler: /users/PYS0343/pmadden/.conda/envs/foo/bin/nvcc - skipped
-- Detecting CUDA compile features
-- Detecting CUDA compile features - done
-- The CUDA Host CXX Compiler: /users/PYS0343/pmadden/.conda/envs/foo/bin/x86_64-conda-linux-gnu-c++
-- Autodetected CUDA architecture(s):  6.0
-- Using shared_obj_name: libKeOpstorch9115532fd5
-- First i variables detected is 0
-- First j variables detected is 1
-- Compiled formula is Sum_Reduction(SqNorm2(x - y),1); auto x = Vi(0,3); auto y = Vj(1,3);  where the number of args is 2.
-- Found PythonInterp: /users/PYS0343/pmadden/.conda/envs/foo/bin/python (found suitable version "3.7.8", minimum required is "3.7")
-- Found PythonLibs: /users/PYS0343/pmadden/.conda/envs/foo/lib/libpython3.7m.so
-- pybind11 v2.3.dev1
-- Performing Test HAS_FLTO
-- Performing Test HAS_FLTO - Success
-- LTO enabled
-- Configuring done
-- Generating done
-- Build files have been written to: /users/PYS0343/pmadden/.cache/pykeops-1.4.1-cpython-37/build-libKeOpstorch9115532fd5
...
pyKeOps with torch bindings is working!

With the latter (or with 816249793519a9fcbab1e692c1cea3d81af12e47 the current HEAD of master), I get what you see in the attached file. Also note that I am cleaning out the cache directory between experiments.

I realize that you may not intend for everything to work between releases, but I thought I should share this with you.

error.txt

mihai-spire commented 4 years ago

@bcharlier It seems that commit 2c96e93 did not completely fix the problem with the bin_folder.

test_torch_bindings does behave as expected after that commit. However, a simple pykeops + gpytorch test shows that kernels are not stored in bin_folder despite this being set to an explicit non-$home path.

How to test:

Run the following code:

from typing import Any
import argparse
import os
import time
import numpy as np

import torch
import gpytorch
import pykeops

# create a synthetic dataset
def make_target(X: np.ndarray) -> np.ndarray:
    '''Create synthetic targets'''
    # y_train = 1 + sum(x^2) + noise
    y = 1.0 + np.square(X).sum(axis=-1) + 0.1*np.random.randn(X.shape[0])
    return y.astype(np.float32)

def eval_fit(model: Any, likelihood: Any, val_X: torch.Tensor, y_val: np.ndarray) -> float:
    '''
        Evaluate model fit.
        Args: model, likelihood objects
        Returns: MSE on holdout set
    '''
    # Get into evaluation (predictive posterior) mode
    model.eval()
    likelihood.eval()

    # Test points are regularly spaced along [0,1]
    # Make predictions by feeding model through likelihood
    with torch.no_grad(), gpytorch.settings.fast_pred_var():
        y_pred = likelihood(model(val_X))
        y_pred_mean = y_pred.mean.cpu().numpy()

    return np.sqrt(np.mean(np.square(y_pred_mean - y_val)))

class ExactGPModel(gpytorch.models.ExactGP):
    def __init__(self, train_x, train_y, likelihood):
        '''GP model constructor: constant mean and composite Scale-Matern kernel'''
        super(ExactGPModel, self).__init__(train_x, train_y, likelihood)
        self.mean_module = gpytorch.means.ConstantMean()
        self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.keops.MaternKernel(nu=2.5))

    def forward(self, x):
        '''Forward propagator.'''
        mean_x = self.mean_module(x)
        covar_x = self.covar_module(x)
        return gpytorch.distributions.MultivariateNormal(mean_x, covar_x)

def get_args():
    '''
    Parses arguments passed to main.
    '''
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--bin-folder',
        dest='bin_folder',
        required=True,
        help='KeOps bin folder: compiled kernels will be stored here'
    )
    return parser.parse_args()

def main():
    args = get_args()

    pykeops.verbose = True
    pykeops.set_bin_folder(args.bin_folder)
    print(f'pyKeOps bin_folder was set to {pykeops.bin_folder} ...')

    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')  # pylint: disable=no-member
    print(f'Device torch is running on: {device} ...')

    n_samples = 2500
    n_samples_val = 500
    n_features = 5

    # train data
    X_train = np.random.randn(n_samples, n_features).astype(np.float32)
    y_train = make_target(X_train)

    # validation data
    X_val = np.random.randn(n_samples_val, n_features).astype(np.float32)
    y_val = make_target(X_val)

    train_X = torch.as_tensor(X_train, device=device).contiguous()  # pylint: disable=no-member
    train_y = torch.as_tensor(y_train, device=device).contiguous()  # pylint: disable=no-member

    val_X = torch.as_tensor(X_val, device=device).contiguous()  # pylint: disable=no-member
    # val_y = torch.as_tensor(y_val, device=device).contiguous()  # pylint: disable=no-member

    # initialize likelihood and model
    likelihood = gpytorch.likelihoods.GaussianLikelihood().to(device)
    model = ExactGPModel(train_X, train_y, likelihood).to(device)

    model.train()
    likelihood.train()

    # Use the adam optimizer
    optimizer = torch.optim.Adam(
        [
            # Includes GaussianLikelihood parameters
            {'params': model.parameters()},
        ],
        lr=0.01
    )

    # "Loss" for GPs - the marginal log likelihood
    mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)

    # Keep it short - two iterations only
    training_iter = 2

    for i in range(training_iter):
        start_time = time.time()
        # Zero gradients from previous iteration
        optimizer.zero_grad()
        # Output from model
        output = model(train_X)
        # Calc loss and backprop gradients
        loss = -mll(output, train_y)
        loss.backward()
        print('Iter %d/%d - Loss: %.3f   lengthscale: %.3f   noise: %.3f   time:%.3f' % (
            i + 1, training_iter, loss.item(),
            model.covar_module.base_kernel.lengthscale.item(),
            model.likelihood.noise.item(),
            time.time() - start_time
        ))
        optimizer.step()

        mse = eval_fit(model, likelihood, val_X, y_val)
        print(f'EVAL MSE: {mse:.3e}')
        model.train()
        likelihood.train()

    # check if bin_folder exists
    assert os.path.isdir(pykeops.bin_folder)
    # check that it's not empty
    assert os.listdir(pykeops.bin_folder)

    print('--- TEST COMPLETED OK ---')

if __name__ == '__main__':
    main()

Sample output:

$ python test_pykeops.py --bin-folder /scratch/keops
pyKeOps bin_folder was set to /scratch/keops/ ...
Device torch is running on: cuda:0 ...
Compiling libKeOpstorchb027bbfebd in /users/mihai/.cache/pykeops-1.4.1-cpython-37/build-libKeOpstorchb027bbfebd:
       formula: Sum_Reduction(((((Var(0,1,2) * Sqrt(Sum(Square((Var(1,10,0) - Var(2,10,1)))))) + (IntCst(1) + (Var(3,1,2) * Square(Sqrt(Sum(Square((Var(1,10,0) - Var(2,10,1))))))))) * Exp((Var(4,1,2) * Sqrt(Sum(Square((Var(1,10,0) - Var(2,10,1)))))))) * Var(5,11,1)),0)
       aliases: Var(0,1,2); Var(1,10,0); Var(2,10,1); Var(3,1,2); Var(4,1,2); Var(5,11,1); 
       dtype  : float32
... 

Expected behavior Kernels are compiled and stored under the --bin-folder path.

Actual behavior Kernels are always compiled and stored under $HOME/.cache/pykeops-*.

Other remarks Note that gpytorch does not appear to (re-)set the bin_folder in any way: there are no calls to set_bin_folder and pykeops.bin_folder is not explicitly set anywhere in that code.

Thank you for looking into this! We're really excited about using keops operationally as it is an amazing piece of software :)

bcharlier commented 4 years ago

Hi @mihai-spire ,

your script now works. I copy it with the syntax change (pykeops.bin_folder is now pykeops.config.bin_folder)

from typing import Any
import argparse
import os
import time
import numpy as np

import torch
import gpytorch
import pykeops

# create a synthetic dataset
def make_target(X: np.ndarray) -> np.ndarray:
    '''Create synthetic targets'''
    # y_train = 1 + sum(x^2) + noise
    y = 1.0 + np.square(X).sum(axis=-1) + 0.1*np.random.randn(X.shape[0])
    return y.astype(np.float32)

def eval_fit(model: Any, likelihood: Any, val_X: torch.Tensor, y_val: np.ndarray) -> float:
    '''
        Evaluate model fit.
        Args: model, likelihood objects
        Returns: MSE on holdout set
    '''
    # Get into evaluation (predictive posterior) mode
    model.eval()
    likelihood.eval()

    # Test points are regularly spaced along [0,1]
    # Make predictions by feeding model through likelihood
    with torch.no_grad(), gpytorch.settings.fast_pred_var():
        y_pred = likelihood(model(val_X))
        y_pred_mean = y_pred.mean.cpu().numpy()

    return np.sqrt(np.mean(np.square(y_pred_mean - y_val)))

class ExactGPModel(gpytorch.models.ExactGP):
    def __init__(self, train_x, train_y, likelihood):
        '''GP model constructor: constant mean and composite Scale-Matern kernel'''
        super(ExactGPModel, self).__init__(train_x, train_y, likelihood)
        self.mean_module = gpytorch.means.ConstantMean()
        self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.keops.MaternKernel(nu=2.5))

    def forward(self, x):
        '''Forward propagator.'''
        mean_x = self.mean_module(x)
        covar_x = self.covar_module(x)
        return gpytorch.distributions.MultivariateNormal(mean_x, covar_x)

def get_args():
    '''
    Parses arguments passed to main.
    '''
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--bin-folder',
        dest='bin_folder',
        required=True,
        help='KeOps bin folder: compiled kernels will be stored here'
    )
    return parser.parse_args()

def main():
    args = get_args()

    pykeops.verbose = True
    pykeops.set_bin_folder(args.bin_folder)
    print(f'pyKeOps bin_folder was set to {pykeops.config.bin_folder} ...')

    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')  # pylint: disable=no-member
    print(f'Device torch is running on: {device} ...')

    n_samples = 2500
    n_samples_val = 500
    n_features = 5

    # train data
    X_train = np.random.randn(n_samples, n_features).astype(np.float32)
    y_train = make_target(X_train)

    # validation data
    X_val = np.random.randn(n_samples_val, n_features).astype(np.float32)
    y_val = make_target(X_val)

    train_X = torch.as_tensor(X_train, device=device).contiguous()  # pylint: disable=no-member
    train_y = torch.as_tensor(y_train, device=device).contiguous()  # pylint: disable=no-member

    val_X = torch.as_tensor(X_val, device=device).contiguous()  # pylint: disable=no-member
    # val_y = torch.as_tensor(y_val, device=device).contiguous()  # pylint: disable=no-member

    # initialize likelihood and model
    likelihood = gpytorch.likelihoods.GaussianLikelihood().to(device)
    model = ExactGPModel(train_X, train_y, likelihood).to(device)

    model.train()
    likelihood.train()

    # Use the adam optimizer
    optimizer = torch.optim.Adam(
        [
            # Includes GaussianLikelihood parameters
            {'params': model.parameters()},
        ],
        lr=0.01
    )

    # "Loss" for GPs - the marginal log likelihood
    mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)

    # Keep it short - two iterations only
    training_iter = 2

    for i in range(training_iter):
        start_time = time.time()
        # Zero gradients from previous iteration
        optimizer.zero_grad()
        # Output from model
        output = model(train_X)
        # Calc loss and backprop gradients
        loss = -mll(output, train_y)
        loss.backward()
        print('Iter %d/%d - Loss: %.3f   lengthscale: %.3f   noise: %.3f   time:%.3f' % (
            i + 1, training_iter, loss.item(),
            model.covar_module.base_kernel.lengthscale.item(),
            model.likelihood.noise.item(),
            time.time() - start_time
        ))
        optimizer.step()

        mse = eval_fit(model, likelihood, val_X, y_val)
        print(f'EVAL MSE: {mse:.3e}')
        model.train()
        likelihood.train()

    # check if bin_folder exists
    assert os.path.isdir(pykeops.config.bin_folder)
    # check that it's not empty
    assert os.listdir(pykeops.config.bin_folder)

    print('--- TEST COMPLETED OK ---')

if __name__ == '__main__':
    main()
mihai-spire commented 4 years ago

@bcharlier thanks a lot for looking into this!

However, I can't get my script above to work with gpytorch 1.2.0 and your latest master.

Error:

Traceback (most recent call last):
  File "test_pykeops.py", line 151, in <module>
    main()
  File "test_pykeops.py", line 100, in main
    model = ExactGPModel(train_X, train_y, likelihood).to(device)
  File "test_pykeops.py", line 47, in __init__
    self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.keops.MaternKernel(nu=2.5))
  File "conda/envs/DEV/lib/python3.7/site-packages/gpytorch/kernels/keops/matern_kernel.py", line 78, in __init__
    super().__init__()
  File "conda/envs/DEV/lib/python3.7/site-packages/gpytorch/kernels/keops/keops_kernel.py", line 20, in __init__
    raise RuntimeError("You must have KeOps installed to use a KeOpsKernel")
RuntimeError: You must have KeOps installed to use a KeOpsKernel

Potential reason:

A recent commit seems to have broken the pykeops interface within gpytorch. The path to LazyTensor seems to have changed in master - gpytorch looks for the file under pykeops/torch (see https://github.com/cornellius-gp/gpytorch/blob/master/gpytorch/kernels/keops/keops_kernel.py) but LazyTensor.py is now under pykeops/torch/lazytensor?

bcharlier commented 4 years ago

Ok, I have tested with gpytorch v1.1.1 and v1.2 on my system... It seems to works:

$ CXX=g++-9 python test.py --bin-folder /home/bcharlier/stupid_name
pyKeOps bin_folder was set to /home/bcharlier/stupid_name/ ...
Device torch is running on: cuda:0 ...
Iter 1/2 - Loss: 6.590   lengthscale: 0.693   noise: 0.693   time:0.282
EVAL MSE: 3.183e+00
Iter 2/2 - Loss: 6.482   lengthscale: 0.698   noise: 0.698   time:0.146
EVAL MSE: 3.160e+00
--- TEST COMPLETED OK ---

I guess that the try ... catch is hiding another error. Can you test that compilation works on pykeops side ?

bcharlier commented 4 years ago

By the way, the refactoring of the LazyTensor class should be (hopefully!) transparent to the user and to gpytorch interface...

mihai-spire commented 4 years ago

Hmm.. okay. I may have jumped the gun on this. Let me try running this again!

mihai-spire commented 4 years ago

@bcharlier __init__.py appears to be missing from pykeops/torch/lazytensor - this is what is probably messing up my conda build...

i'm now trying to re-build the conda package using @maddenp 's recipe from a patched local repo (same as master + the missing __init__.py). could you please patch this in master if you get a chance? it'd make my job much easier... :) thank you!

bcharlier commented 4 years ago

should be ok on the last commit on master

mihai-spire commented 4 years ago

@bcharlier i was looking at https://github.com/getkeops/keops/tree/master/pykeops/torch/lazytensor - there's no __init__.py in there, are you saying that is not really needed?

For some reason, the conda build doesn't pick up on the new torch/lazytensor/LazyTensor.py code. Hence my import error above. Here's part of the package contents i get with conda build (as stated previously, i used the conda recipe above and the latest code from master):

$ ll lib/python3.7/site-packages/pykeops/torch
total 48
-rw-r----- 1 mihai-spire USER  1404 Oct  6 08:47 __init__.py
drwxr-x--- 2 mihai-spire USER  4096 Oct  7 06:14 __pycache__
drwxr-x--- 3 mihai-spire USER  4096 Oct  7 06:14 cluster
drwxr-x--- 3 mihai-spire USER  4096 Oct  7 06:14 generic
-rw-r----- 1 mihai-spire USER  3876 Sep  8 08:38 half2_convert.py
drwxr-x--- 3 mihai-spire USER  4096 Oct  7 06:14 kernel_product
-rw-r----- 1 mihai-spire USER 17728 Oct  6 08:47 operations.py
-rw-r----- 1 mihai-spire USER  3194 Oct  6 08:47 utils.py

same for the numpy bindings:

$ ll lib/python3.7/site-packages/pykeops/numpy/
total 44
-rw-r----- 1 mihai-spire USER   635 Oct  6 08:47 __init__.py
drwxr-x--- 2 mihai-spire USER  4096 Oct  7 06:14 __pycache__
drwxr-x--- 3 mihai-spire USER  4096 Oct  7 06:14 cluster
drwxr-x--- 3 mihai-spire USER  4096 Oct  7 06:14 convolutions
drwxr-x--- 3 mihai-spire USER  4096 Oct  7 06:14 generic
-rw-r----- 1 mihai-spire USER 11217 Oct  6 08:47 operations.py
drwxr-x--- 3 mihai-spire USER  4096 Oct  7 06:14 shape_distance
-rw-r----- 1 mihai-spire USER  5363 Oct  6 08:47 utils.py
bcharlier commented 4 years ago

@mihai-spire , my bad. I added missing __init__.py files and the conda recipe to master. Once tested, we will put this in the doc.

mihai-spire commented 4 years ago

@bcharlier thank you! 👍

With your changes, I was able to build a new conda package that passes my test. I'll run a couple more tests and get back to you if i run into any problems.

Do you have any plans to publish an official pykeops conda package in the near future?

dvolgyes commented 3 years ago

Any problems or progress? I also would highly appreciate prebuilt conda package, official or unofficial. My pip/git installations take a long time, every machine has its own unique problems (different compiler, different cuda location, cmake issues, etc.) By my estimates, i spent almost as much time to install pykeops as i actually spent on using it.

mihai-spire commented 3 years ago

@dvolgyes

I also would highly appreciate prebuilt conda package, official or unofficial.

Have you tried to build a private (local) conda package using the recipe @maddenp posted above? See https://github.com/getkeops/keops/issues/85#issuecomment-675265331 I don't think the recipe/patch is needed anymore - that issue was fixed in a recent commit. Good luck!

bcharlier commented 3 years ago

@dvolgyes ,

the last commit on master includes the conda recipe. See the header of the recipe for the commandline to built the conda package locally (to be executed from the keops/.conda dir).

If it works on your side I will consider to deploy the conda package on some repo.

dvolgyes commented 3 years ago

Well, actually I am trying, but it fails with various errors. (And i also hoped that duplicated efforts could be avoided.)

A few remarks:

The log is huge, see in the next comment.

dvolgyes commented 3 years ago

conda build -c pytorch -c conda-forge recipe For this command an a RHEL linux with CUDA 10.2 (after installing conda-build, conda-verify) I get this error:

No numpy version specified in conda_build_config.yaml.  Falling back to default numpy value of 1.11
WARNING:conda_build.metadata:No numpy version specified in conda_build_config.yaml.  Falling back to default numpy value of 1.11
Adding in variants from internal_defaults
INFO:conda_build.variants:Adding in variants from internal_defaults
Attempting to finalize metadata for pykeops
INFO:conda_build.metadata:Attempting to finalize metadata for pykeops
Collecting package metadata (repodata.json): ...working... done
Solving environment: ...working... done
Collecting package metadata (repodata.json): ...working... done
Solving environment: ...working... done
BUILD START: ['pykeops-1.4.2-py38h6bb024c_0.tar.bz2']
Collecting package metadata (repodata.json): ...working... done
Solving environment: ...working... done
Collecting package metadata (repodata.json): ...working... done
Solving environment: ...working... done

## Package Plan ##

  environment location: /scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/_build_env

The following NEW packages will be INSTALLED:

    _libgcc_mutex:    0.1-conda_forge          conda-forge
    _openmp_mutex:    4.5-1_gnu                conda-forge
    ca-certificates:  2020.6.20-hecda079_0     conda-forge
    certifi:          2020.6.20-py38h924ce5b_2 conda-forge
    ld_impl_linux-64: 2.35-h769bd43_9          conda-forge
    libffi:           3.2.1-he1b5a44_1007      conda-forge
    libgcc-ng:        9.3.0-h5dbcf3e_17        conda-forge
    libgomp:          9.3.0-h5dbcf3e_17        conda-forge
    libstdcxx-ng:     9.3.0-h2ae2ef3_17        conda-forge
    ncurses:          6.2-he1b5a44_2           conda-forge
    openssl:          1.1.1h-h516909a_0        conda-forge
    pip:              20.2.3-py_0              conda-forge
    python:           3.8.6-h852b56e_0_cpython conda-forge
    python_abi:       3.8-1_cp38               conda-forge
    readline:         8.0-he28a2e2_2           conda-forge
    setuptools:       49.6.0-py38h924ce5b_2    conda-forge
    sqlite:           3.33.0-h4cf870e_1        conda-forge
    tk:               8.6.10-hed695b0_1        conda-forge
    wheel:            0.35.1-pyh9f0ad1d_0      conda-forge
    xz:               5.2.5-h516909a_1         conda-forge
    zlib:             1.2.11-h516909a_1009     conda-forge

Preparing transaction: ...working... done
Verifying transaction: ...working... done
Executing transaction: ...working... done
X11 forwarding request failed on channel 0
Cloning into '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work'...
done.
checkout: 'HEAD'
Your branch is up to date with 'origin/_conda_cache_origin_head'.
Submodule 'keops/lib/benchmark' (https://github.com/google/benchmark.git) registered for path 'keops/lib/benchmark'
Submodule 'keops/lib/gtest' (https://github.com/google/googletest.git) registered for path 'keops/lib/gtest'
Submodule 'keops/lib/sequences' (https://github.com/taocpp/sequences.git) registered for path 'keops/lib/sequences'
Submodule 'pykeops/pybind11' (https://github.com/pybind/pybind11.git) registered for path 'pykeops/pybind11'
Cloning into '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work/keops/lib/benchmark'...
X11 forwarding request failed on channel 0
Cloning into '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work/keops/lib/gtest'...
X11 forwarding request failed on channel 0
Cloning into '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work/keops/lib/sequences'...
X11 forwarding request failed on channel 0
Cloning into '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work/pykeops/pybind11'...
X11 forwarding request failed on channel 0
Submodule path 'keops/lib/benchmark': checked out '140db8a22901f666577b7516febf184e9764f4e2'
Submodule path 'keops/lib/gtest': checked out 'c205468b65a5b6f3239c4e68af860f6c82895f9d'
Submodule path 'keops/lib/sequences': checked out '0bd061fd65d2794bf729c85a7ceeea94106e9dd6'
Submodule path 'pykeops/pybind11': checked out 'c9d32a81f40ad540015814edf13b29980c63e39c'
Submodule 'tools/clang' (https://github.com/wjakob/clang-cindex-python3) registered for path 'pykeops/pybind11/tools/clang'
Cloning into '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work/pykeops/pybind11/tools/clang'...
X11 forwarding request failed on channel 0
Submodule path 'pykeops/pybind11/tools/clang': checked out '6a00cbc4a9b8e68b71caf7f774b3f9c753ae84d5'
==> git log -n1 <==

commit 34c2d9ba0821eb52cea3cbc6e5b100689ef8d1a9
Author: Charlier Benjamin <benjamin.charlier@umontpellier.fr>
Date:   Wed Oct 7 16:12:26 2020 +0200

    Add missing __init__.py

==> git describe --tags --dirty <==

v1.4.1-86-g34c2d9ba

==> git status <==

On branch _conda_cache_origin_head
Your branch is up to date with 'origin/_conda_cache_origin_head'.

nothing to commit, working tree clean

source tree in: /scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work
export PREFIX=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla
export BUILD_PREFIX=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/_build_env
export SRC_DIR=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work
+ git submodule update --init
+ python setup.py install --single-version-externally-managed --record=record.txt --prefix=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/pykeops
copying pykeops/__init__.py -> build/lib/pykeops
copying pykeops/config.py -> build/lib/pykeops
creating build/lib/pykeops/common
copying pykeops/common/__init__.py -> build/lib/pykeops/common
copying pykeops/common/compile_routines.py -> build/lib/pykeops/common
copying pykeops/common/get_options.py -> build/lib/pykeops/common
copying pykeops/common/keops_io.py -> build/lib/pykeops/common
copying pykeops/common/lazy_tensor.py -> build/lib/pykeops/common
copying pykeops/common/operations.py -> build/lib/pykeops/common
copying pykeops/common/parse_type.py -> build/lib/pykeops/common
copying pykeops/common/set_path.py -> build/lib/pykeops/common
copying pykeops/common/utils.py -> build/lib/pykeops/common
creating build/lib/pykeops/numpy
copying pykeops/numpy/__init__.py -> build/lib/pykeops/numpy
copying pykeops/numpy/operations.py -> build/lib/pykeops/numpy
copying pykeops/numpy/utils.py -> build/lib/pykeops/numpy
creating build/lib/pykeops/numpy/cluster
copying pykeops/numpy/cluster/__init__.py -> build/lib/pykeops/numpy/cluster
copying pykeops/numpy/cluster/grid_cluster.py -> build/lib/pykeops/numpy/cluster
copying pykeops/numpy/cluster/matrix.py -> build/lib/pykeops/numpy/cluster
copying pykeops/numpy/cluster/utils.py -> build/lib/pykeops/numpy/cluster
creating build/lib/pykeops/numpy/convolutions
copying pykeops/numpy/convolutions/__init__.py -> build/lib/pykeops/numpy/convolutions
copying pykeops/numpy/convolutions/radial_kernel.py -> build/lib/pykeops/numpy/convolutions
creating build/lib/pykeops/numpy/generic
copying pykeops/numpy/generic/__init__.py -> build/lib/pykeops/numpy/generic
copying pykeops/numpy/generic/generic_ops.py -> build/lib/pykeops/numpy/generic
copying pykeops/numpy/generic/generic_red.py -> build/lib/pykeops/numpy/generic
creating build/lib/pykeops/numpy/lazytensor
copying pykeops/numpy/lazytensor/LazyTensor.py -> build/lib/pykeops/numpy/lazytensor
copying pykeops/numpy/lazytensor/__init__.py -> build/lib/pykeops/numpy/lazytensor
creating build/lib/pykeops/numpy/shape_distance
copying pykeops/numpy/shape_distance/__init__.py -> build/lib/pykeops/numpy/shape_distance
copying pykeops/numpy/shape_distance/fshape_scp.py -> build/lib/pykeops/numpy/shape_distance
copying pykeops/numpy/shape_distance/fshape_scp_dx.py -> build/lib/pykeops/numpy/shape_distance
creating build/lib/pykeops/test
copying pykeops/test/__init__.py -> build/lib/pykeops/test
copying pykeops/test/install.py -> build/lib/pykeops/test
copying pykeops/test/unit_tests_numpy.py -> build/lib/pykeops/test
copying pykeops/test/unit_tests_pytorch.py -> build/lib/pykeops/test
creating build/lib/pykeops/torch
copying pykeops/torch/__init__.py -> build/lib/pykeops/torch
copying pykeops/torch/half2_convert.py -> build/lib/pykeops/torch
copying pykeops/torch/operations.py -> build/lib/pykeops/torch
copying pykeops/torch/utils.py -> build/lib/pykeops/torch
creating build/lib/pykeops/torch/cluster
copying pykeops/torch/cluster/__init__.py -> build/lib/pykeops/torch/cluster
copying pykeops/torch/cluster/grid_cluster.py -> build/lib/pykeops/torch/cluster
copying pykeops/torch/cluster/matrix.py -> build/lib/pykeops/torch/cluster
copying pykeops/torch/cluster/utils.py -> build/lib/pykeops/torch/cluster
creating build/lib/pykeops/torch/generic
copying pykeops/torch/generic/__init__.py -> build/lib/pykeops/torch/generic
copying pykeops/torch/generic/generic_ops.py -> build/lib/pykeops/torch/generic
copying pykeops/torch/generic/generic_red.py -> build/lib/pykeops/torch/generic
creating build/lib/pykeops/torch/lazytensor
copying pykeops/torch/lazytensor/LazyTensor.py -> build/lib/pykeops/torch/lazytensor
copying pykeops/torch/lazytensor/__init__.py -> build/lib/pykeops/torch/lazytensor
creating build/lib/pykeops/torch/kernel_product
copying pykeops/torch/kernel_product/__init__.py -> build/lib/pykeops/torch/kernel_product
copying pykeops/torch/kernel_product/features_kernels.py -> build/lib/pykeops/torch/kernel_product
copying pykeops/torch/kernel_product/formula.py -> build/lib/pykeops/torch/kernel_product
copying pykeops/torch/kernel_product/kernels.py -> build/lib/pykeops/torch/kernel_product
copying pykeops/readme.md -> build/lib/pykeops
copying pykeops/licence.txt -> build/lib/pykeops
copying pykeops/CMakeLists.txt -> build/lib/pykeops
copying pykeops/torch_headers.h.in -> build/lib/pykeops
copying pykeops/numpy/convolutions/radial_kernel_conv.cpp -> build/lib/pykeops/numpy/convolutions
copying pykeops/numpy/convolutions/radial_kernel_grad1conv.cpp -> build/lib/pykeops/numpy/convolutions
copying pykeops/numpy/generic/generic_red.cpp -> build/lib/pykeops/numpy/generic
copying pykeops/numpy/shape_distance/fshape_scp.cpp -> build/lib/pykeops/numpy/shape_distance
copying pykeops/torch/generic/generic_red.cpp -> build/lib/pykeops/torch/generic
copying pykeops/common/keops_io.h -> build/lib/pykeops/common
creating build/lib/pykeops/keops
copying pykeops/keops/cuda.cmake -> build/lib/pykeops/keops
copying pykeops/keops/formula.h.in -> build/lib/pykeops/keops
copying pykeops/keops/headers.cmake -> build/lib/pykeops/keops
copying pykeops/keops/keops_includes.h -> build/lib/pykeops/keops
copying pykeops/version -> build/lib/pykeops
creating build/lib/pykeops/keops/binders
copying pykeops/keops/binders/checks.h -> build/lib/pykeops/keops/binders
copying pykeops/keops/binders/include.h -> build/lib/pykeops/keops/binders
copying pykeops/keops/binders/keops_cst.h -> build/lib/pykeops/keops/binders
copying pykeops/keops/binders/switch.h -> build/lib/pykeops/keops/binders
copying pykeops/keops/binders/utils.h -> build/lib/pykeops/keops/binders
creating build/lib/pykeops/keops/core
creating build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/BinaryOp.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/ChunkableBinaryOp.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/ChunkableUnaryOp.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/CountIn.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/Grad.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/IdOrZero.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/TernaryOp.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/UnaryOp.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/Var.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/VectorizedScalarBinaryOp.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/VectorizedScalarTernaryOp.h -> build/lib/pykeops/keops/core/autodiff
copying pykeops/keops/core/autodiff/VectorizedScalarUnaryOp.h -> build/lib/pykeops/keops/core/autodiff
creating build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/Call.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/CheckAllDistinct.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/ConcatPack.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/CondType.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/CountInPack.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/Get.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/GetDims.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/GetInds.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/IndVal.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/IsSame.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/IterReplace.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/Load.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/Load_Chunks.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/Load_Indref.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/MergePacks.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/Pack.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/PackVal.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/RemoveFromPack.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/ReplaceInPack.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/UnivPack.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/Val.h -> build/lib/pykeops/keops/core/pack
copying pykeops/keops/core/pack/ZeroPack.h -> build/lib/pykeops/keops/core/pack
creating build/lib/pykeops/keops/core/formulas
copying pykeops/keops/core/formulas/Factorize.h -> build/lib/pykeops/keops/core/formulas
copying pykeops/keops/core/formulas/PrintFormula.h -> build/lib/pykeops/keops/core/formulas
copying pykeops/keops/core/formulas/deprecated.h -> build/lib/pykeops/keops/core/formulas
creating build/lib/pykeops/keops/core/formulas/constants
copying pykeops/keops/core/formulas/constants/IntConst.h -> build/lib/pykeops/keops/core/formulas/constants
copying pykeops/keops/core/formulas/constants/Zero.h -> build/lib/pykeops/keops/core/formulas/constants
creating build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/CauchyKernel.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/CurlFreeGaussKernel.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/DivFreeGaussKernel.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/GaussKernel.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/InverseMultiquadricKernel.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/Kernel.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/LaplaceKernel.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/ScalarRadialKernels.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/SumGaussKernel.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/TRIGaussKernel.h -> build/lib/pykeops/keops/core/formulas/kernels
copying pykeops/keops/core/formulas/kernels/TRI_Kernel.h -> build/lib/pykeops/keops/core/formulas/kernels
creating build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Abs.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Acos.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Add.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/ArgMax.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/ArgMin.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Clamp.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/ClampInt.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Concat.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Cos.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/DiffClampInt.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Divide.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Elem.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/ElemT.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Exp.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Extract.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/ExtractT.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/GradMatrix.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/IntInv.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Inv.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Log.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/MatVecMult.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Max.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Min.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Minus.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Mult.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/OneHot.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Pow.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Powf.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/ReLu.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Rsqrt.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Scal.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/ScalOrMult.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Sign.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Sin.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Sqrt.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Square.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Step.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Subtract.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/Sum.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/SumT.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/TensorDot.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/TensorProd.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/VecMatMult.h -> build/lib/pykeops/keops/core/formulas/maths
copying pykeops/keops/core/formulas/maths/XLogX.h -> build/lib/pykeops/keops/core/formulas/maths
creating build/lib/pykeops/keops/core/formulas/norms
copying pykeops/keops/core/formulas/norms/Norm2.h -> build/lib/pykeops/keops/core/formulas/norms
copying pykeops/keops/core/formulas/norms/Normalize.h -> build/lib/pykeops/keops/core/formulas/norms
copying pykeops/keops/core/formulas/norms/Scalprod.h -> build/lib/pykeops/keops/core/formulas/norms
copying pykeops/keops/core/formulas/norms/SqDist.h -> build/lib/pykeops/keops/core/formulas/norms
copying pykeops/keops/core/formulas/norms/SqNorm2.h -> build/lib/pykeops/keops/core/formulas/norms
copying pykeops/keops/core/formulas/norms/SqNormDiag.h -> build/lib/pykeops/keops/core/formulas/norms
copying pykeops/keops/core/formulas/norms/SqNormIso.h -> build/lib/pykeops/keops/core/formulas/norms
copying pykeops/keops/core/formulas/norms/WeightedSqDist.h -> build/lib/pykeops/keops/core/formulas/norms
copying pykeops/keops/core/formulas/norms/WeightedSqNorm.h -> build/lib/pykeops/keops/core/formulas/norms
creating build/lib/pykeops/keops/core/reductions
copying pykeops/keops/core/reductions/KMin_Reduction.h -> build/lib/pykeops/keops/core/reductions
copying pykeops/keops/core/reductions/Max_Reduction.h -> build/lib/pykeops/keops/core/reductions
copying pykeops/keops/core/reductions/Max_SumShiftExp_Reduction.h -> build/lib/pykeops/keops/core/reductions
copying pykeops/keops/core/reductions/Min_Reduction.h -> build/lib/pykeops/keops/core/reductions
copying pykeops/keops/core/reductions/Reduction.h -> build/lib/pykeops/keops/core/reductions
copying pykeops/keops/core/reductions/Sum_Reduction.h -> build/lib/pykeops/keops/core/reductions
copying pykeops/keops/core/reductions/Zero_Reduction.h -> build/lib/pykeops/keops/core/reductions
creating build/lib/pykeops/keops/core/utils
copying pykeops/keops/core/utils/CudaErrorCheck.cu -> build/lib/pykeops/keops/core/utils
copying pykeops/keops/core/utils/CudaSizes.h -> build/lib/pykeops/keops/core/utils
copying pykeops/keops/core/utils/Infinity.h -> build/lib/pykeops/keops/core/utils
copying pykeops/keops/core/utils/TypesUtils.h -> build/lib/pykeops/keops/core/utils
copying pykeops/keops/core/utils/keops_math.h -> build/lib/pykeops/keops/core/utils
creating build/lib/pykeops/keops/core/mapreduce
copying pykeops/keops/core/mapreduce/Chunk_Mode_Constants.h -> build/lib/pykeops/keops/core/mapreduce
copying pykeops/keops/core/mapreduce/CpuConv.cpp -> build/lib/pykeops/keops/core/mapreduce
copying pykeops/keops/core/mapreduce/CpuConv_ranges.cpp -> build/lib/pykeops/keops/core/mapreduce
copying pykeops/keops/core/mapreduce/GpuConv1D.cu -> build/lib/pykeops/keops/core/mapreduce
copying pykeops/keops/core/mapreduce/GpuConv1D_ranges.cu -> build/lib/pykeops/keops/core/mapreduce
copying pykeops/keops/core/mapreduce/GpuConv2D.cu -> build/lib/pykeops/keops/core/mapreduce
copying pykeops/keops/core/mapreduce/broadcast_batch_dimensions.h -> build/lib/pykeops/keops/core/mapreduce
copying pykeops/keops/core/link_autodiff.cpp -> build/lib/pykeops/keops/core
copying pykeops/keops/core/link_autodiff.cu -> build/lib/pykeops/keops/core
copying pykeops/keops/core/pre_headers.h -> build/lib/pykeops/keops/core
creating build/lib/pykeops/keops/specific
copying pykeops/keops/specific/CMakeLists.txt -> build/lib/pykeops/keops/specific
creating build/lib/pykeops/keops/specific/radial_kernels
copying pykeops/keops/specific/radial_kernels/cuda_conv.cu -> build/lib/pykeops/keops/specific/radial_kernels
copying pykeops/keops/specific/radial_kernels/cuda_conv.cx -> build/lib/pykeops/keops/specific/radial_kernels
copying pykeops/keops/specific/radial_kernels/cuda_grad1conv.cu -> build/lib/pykeops/keops/specific/radial_kernels
copying pykeops/keops/specific/radial_kernels/cuda_grad1conv.cx -> build/lib/pykeops/keops/specific/radial_kernels
copying pykeops/keops/specific/radial_kernels/radial_kernels.h -> build/lib/pykeops/keops/specific/radial_kernels
creating build/lib/pykeops/keops/specific/shape_distance
copying pykeops/keops/specific/shape_distance/fshape_gpu.cu -> build/lib/pykeops/keops/specific/shape_distance
copying pykeops/keops/specific/shape_distance/fshape_gpu.cx -> build/lib/pykeops/keops/specific/shape_distance
copying pykeops/keops/specific/shape_distance/kernels.cx -> build/lib/pykeops/keops/specific/shape_distance
creating build/lib/pykeops/pybind11
creating build/lib/pykeops/pybind11/include
creating build/lib/pykeops/pybind11/include/pybind11
creating build/lib/pykeops/pybind11/include/pybind11/detail
copying pykeops/pybind11/include/pybind11/detail/class.h -> build/lib/pykeops/pybind11/include/pybind11/detail
copying pykeops/pybind11/include/pybind11/detail/common.h -> build/lib/pykeops/pybind11/include/pybind11/detail
copying pykeops/pybind11/include/pybind11/detail/descr.h -> build/lib/pykeops/pybind11/include/pybind11/detail
copying pykeops/pybind11/include/pybind11/detail/init.h -> build/lib/pykeops/pybind11/include/pybind11/detail
copying pykeops/pybind11/include/pybind11/detail/internals.h -> build/lib/pykeops/pybind11/include/pybind11/detail
copying pykeops/pybind11/include/pybind11/detail/typeid.h -> build/lib/pykeops/pybind11/include/pybind11/detail
copying pykeops/pybind11/include/pybind11/attr.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/buffer_info.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/cast.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/chrono.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/common.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/complex.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/eigen.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/embed.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/eval.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/functional.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/iostream.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/numpy.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/operators.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/options.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/pybind11.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/pytypes.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/stl.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/include/pybind11/stl_bind.h -> build/lib/pykeops/pybind11/include/pybind11
copying pykeops/pybind11/CMakeLists.txt -> build/lib/pykeops/pybind11
creating build/lib/pykeops/pybind11/tools
copying pykeops/pybind11/tools/FindPythonLibsNew.cmake -> build/lib/pykeops/pybind11/tools
copying pykeops/pybind11/tools/pybind11Tools.cmake -> build/lib/pykeops/pybind11/tools
copying pykeops/pybind11/tools/pybind11Config.cmake.in -> build/lib/pykeops/pybind11/tools
creating build/lib/pykeops/keops/lib
creating build/lib/pykeops/keops/lib/sequences
creating build/lib/pykeops/keops/lib/sequences/include
creating build/lib/pykeops/keops/lib/sequences/include/tao
creating build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/accumulate.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/at_index.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/concatenate.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/config.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/contains.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/difference.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/exclusive_scan.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/first.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/functional.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/head.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/inclusive_scan.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/index_of.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/index_of_seq.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/integer_sequence.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/is_all.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/is_any.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/make_integer_range.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/make_integer_sequence.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/map.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/max.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/min.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/minus.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/multiplies.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/partial_accumulate.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/partial_prod.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/partial_reduce.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/partial_sum.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/permutate.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/plus.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/prod.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/reduce.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/reverse.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/scale.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/select.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/sequence_helper.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/sort.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/sort_index.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/sum.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/tail.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
copying pykeops/keops/lib/sequences/include/tao/seq/zip.hpp -> build/lib/pykeops/keops/lib/sequences/include/tao/seq
running install_lib
creating $PREFIX/lib
creating $PREFIX/lib/python3.8
creating $PREFIX/lib/python3.8/site-packages
creating $PREFIX/lib/python3.8/site-packages/pykeops
copying build/lib/pykeops/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops
copying build/lib/pykeops/config.py -> $PREFIX/lib/python3.8/site-packages/pykeops
creating $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/compile_routines.py -> $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/get_options.py -> $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/keops_io.py -> $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/lazy_tensor.py -> $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/operations.py -> $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/parse_type.py -> $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/set_path.py -> $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/utils.py -> $PREFIX/lib/python3.8/site-packages/pykeops/common
copying build/lib/pykeops/common/keops_io.h -> $PREFIX/lib/python3.8/site-packages/pykeops/common
creating $PREFIX/lib/python3.8/site-packages/pykeops/numpy
copying build/lib/pykeops/numpy/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy
copying build/lib/pykeops/numpy/operations.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy
copying build/lib/pykeops/numpy/utils.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy
creating $PREFIX/lib/python3.8/site-packages/pykeops/numpy/cluster
copying build/lib/pykeops/numpy/cluster/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/cluster
copying build/lib/pykeops/numpy/cluster/grid_cluster.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/cluster
copying build/lib/pykeops/numpy/cluster/matrix.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/cluster
copying build/lib/pykeops/numpy/cluster/utils.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/cluster
creating $PREFIX/lib/python3.8/site-packages/pykeops/numpy/convolutions
copying build/lib/pykeops/numpy/convolutions/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/convolutions
copying build/lib/pykeops/numpy/convolutions/radial_kernel.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/convolutions
copying build/lib/pykeops/numpy/convolutions/radial_kernel_conv.cpp -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/convolutions
copying build/lib/pykeops/numpy/convolutions/radial_kernel_grad1conv.cpp -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/convolutions
creating $PREFIX/lib/python3.8/site-packages/pykeops/numpy/generic
copying build/lib/pykeops/numpy/generic/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/generic
copying build/lib/pykeops/numpy/generic/generic_ops.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/generic
copying build/lib/pykeops/numpy/generic/generic_red.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/generic
copying build/lib/pykeops/numpy/generic/generic_red.cpp -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/generic
creating $PREFIX/lib/python3.8/site-packages/pykeops/numpy/lazytensor
copying build/lib/pykeops/numpy/lazytensor/LazyTensor.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/lazytensor
copying build/lib/pykeops/numpy/lazytensor/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/lazytensor
creating $PREFIX/lib/python3.8/site-packages/pykeops/numpy/shape_distance
copying build/lib/pykeops/numpy/shape_distance/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/shape_distance
copying build/lib/pykeops/numpy/shape_distance/fshape_scp.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/shape_distance
copying build/lib/pykeops/numpy/shape_distance/fshape_scp_dx.py -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/shape_distance
copying build/lib/pykeops/numpy/shape_distance/fshape_scp.cpp -> $PREFIX/lib/python3.8/site-packages/pykeops/numpy/shape_distance
creating $PREFIX/lib/python3.8/site-packages/pykeops/test
copying build/lib/pykeops/test/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/test
copying build/lib/pykeops/test/install.py -> $PREFIX/lib/python3.8/site-packages/pykeops/test
copying build/lib/pykeops/test/unit_tests_numpy.py -> $PREFIX/lib/python3.8/site-packages/pykeops/test
copying build/lib/pykeops/test/unit_tests_pytorch.py -> $PREFIX/lib/python3.8/site-packages/pykeops/test
creating $PREFIX/lib/python3.8/site-packages/pykeops/torch
copying build/lib/pykeops/torch/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch
copying build/lib/pykeops/torch/half2_convert.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch
copying build/lib/pykeops/torch/operations.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch
copying build/lib/pykeops/torch/utils.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch
creating $PREFIX/lib/python3.8/site-packages/pykeops/torch/cluster
copying build/lib/pykeops/torch/cluster/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/cluster
copying build/lib/pykeops/torch/cluster/grid_cluster.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/cluster
copying build/lib/pykeops/torch/cluster/matrix.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/cluster
copying build/lib/pykeops/torch/cluster/utils.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/cluster
creating $PREFIX/lib/python3.8/site-packages/pykeops/torch/generic
copying build/lib/pykeops/torch/generic/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/generic
copying build/lib/pykeops/torch/generic/generic_ops.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/generic
copying build/lib/pykeops/torch/generic/generic_red.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/generic
copying build/lib/pykeops/torch/generic/generic_red.cpp -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/generic
creating $PREFIX/lib/python3.8/site-packages/pykeops/torch/lazytensor
copying build/lib/pykeops/torch/lazytensor/LazyTensor.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/lazytensor
copying build/lib/pykeops/torch/lazytensor/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/lazytensor
creating $PREFIX/lib/python3.8/site-packages/pykeops/torch/kernel_product
copying build/lib/pykeops/torch/kernel_product/__init__.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/kernel_product
copying build/lib/pykeops/torch/kernel_product/features_kernels.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/kernel_product
copying build/lib/pykeops/torch/kernel_product/formula.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/kernel_product
copying build/lib/pykeops/torch/kernel_product/kernels.py -> $PREFIX/lib/python3.8/site-packages/pykeops/torch/kernel_product
copying build/lib/pykeops/readme.md -> $PREFIX/lib/python3.8/site-packages/pykeops
copying build/lib/pykeops/licence.txt -> $PREFIX/lib/python3.8/site-packages/pykeops
copying build/lib/pykeops/CMakeLists.txt -> $PREFIX/lib/python3.8/site-packages/pykeops
copying build/lib/pykeops/torch_headers.h.in -> $PREFIX/lib/python3.8/site-packages/pykeops
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops
copying build/lib/pykeops/keops/cuda.cmake -> $PREFIX/lib/python3.8/site-packages/pykeops/keops
copying build/lib/pykeops/keops/formula.h.in -> $PREFIX/lib/python3.8/site-packages/pykeops/keops
copying build/lib/pykeops/keops/headers.cmake -> $PREFIX/lib/python3.8/site-packages/pykeops/keops
copying build/lib/pykeops/keops/keops_includes.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/binders
copying build/lib/pykeops/keops/binders/checks.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/binders
copying build/lib/pykeops/keops/binders/include.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/binders
copying build/lib/pykeops/keops/binders/keops_cst.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/binders
copying build/lib/pykeops/keops/binders/switch.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/binders
copying build/lib/pykeops/keops/binders/utils.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/binders
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/BinaryOp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/ChunkableBinaryOp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/ChunkableUnaryOp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/CountIn.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/Grad.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/IdOrZero.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/TernaryOp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/UnaryOp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/Var.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/VectorizedScalarBinaryOp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/VectorizedScalarTernaryOp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
copying build/lib/pykeops/keops/core/autodiff/VectorizedScalarUnaryOp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/autodiff
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/Call.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/CheckAllDistinct.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/ConcatPack.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/CondType.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/CountInPack.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/Get.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/GetDims.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/GetInds.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/IndVal.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/IsSame.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/IterReplace.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/Load.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/Load_Chunks.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/Load_Indref.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/MergePacks.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/Pack.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/PackVal.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/RemoveFromPack.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/ReplaceInPack.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/UnivPack.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/Val.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
copying build/lib/pykeops/keops/core/pack/ZeroPack.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/pack
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas
copying build/lib/pykeops/keops/core/formulas/Factorize.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas
copying build/lib/pykeops/keops/core/formulas/PrintFormula.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas
copying build/lib/pykeops/keops/core/formulas/deprecated.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/constants
copying build/lib/pykeops/keops/core/formulas/constants/IntConst.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/constants
copying build/lib/pykeops/keops/core/formulas/constants/Zero.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/constants
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/CauchyKernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/CurlFreeGaussKernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/DivFreeGaussKernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/GaussKernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/InverseMultiquadricKernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/Kernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/LaplaceKernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/ScalarRadialKernels.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/SumGaussKernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/TRIGaussKernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
copying build/lib/pykeops/keops/core/formulas/kernels/TRI_Kernel.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/kernels
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Abs.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Acos.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Add.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/ArgMax.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/ArgMin.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Clamp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/ClampInt.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Concat.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Cos.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/DiffClampInt.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Divide.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Elem.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/ElemT.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Exp.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Extract.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/ExtractT.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/GradMatrix.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/IntInv.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Inv.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Log.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/MatVecMult.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Max.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Min.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Minus.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Mult.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/OneHot.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Pow.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Powf.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/ReLu.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Rsqrt.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Scal.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/ScalOrMult.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Sign.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Sin.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Sqrt.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Square.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Step.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Subtract.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/Sum.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/SumT.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/TensorDot.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/TensorProd.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/VecMatMult.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
copying build/lib/pykeops/keops/core/formulas/maths/XLogX.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/maths
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
copying build/lib/pykeops/keops/core/formulas/norms/Norm2.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
copying build/lib/pykeops/keops/core/formulas/norms/Normalize.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
copying build/lib/pykeops/keops/core/formulas/norms/Scalprod.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
copying build/lib/pykeops/keops/core/formulas/norms/SqDist.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
copying build/lib/pykeops/keops/core/formulas/norms/SqNorm2.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
copying build/lib/pykeops/keops/core/formulas/norms/SqNormDiag.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
copying build/lib/pykeops/keops/core/formulas/norms/SqNormIso.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
copying build/lib/pykeops/keops/core/formulas/norms/WeightedSqDist.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
copying build/lib/pykeops/keops/core/formulas/norms/WeightedSqNorm.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/formulas/norms
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/reductions
copying build/lib/pykeops/keops/core/reductions/KMin_Reduction.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/reductions
copying build/lib/pykeops/keops/core/reductions/Max_Reduction.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/reductions
copying build/lib/pykeops/keops/core/reductions/Max_SumShiftExp_Reduction.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/reductions
copying build/lib/pykeops/keops/core/reductions/Min_Reduction.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/reductions
copying build/lib/pykeops/keops/core/reductions/Reduction.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/reductions
copying build/lib/pykeops/keops/core/reductions/Sum_Reduction.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/reductions
copying build/lib/pykeops/keops/core/reductions/Zero_Reduction.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/reductions
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/utils
copying build/lib/pykeops/keops/core/utils/CudaErrorCheck.cu -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/utils
copying build/lib/pykeops/keops/core/utils/CudaSizes.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/utils
copying build/lib/pykeops/keops/core/utils/Infinity.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/utils
copying build/lib/pykeops/keops/core/utils/TypesUtils.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/utils
copying build/lib/pykeops/keops/core/utils/keops_math.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/utils
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/mapreduce
copying build/lib/pykeops/keops/core/mapreduce/Chunk_Mode_Constants.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/mapreduce
copying build/lib/pykeops/keops/core/mapreduce/CpuConv.cpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/mapreduce
copying build/lib/pykeops/keops/core/mapreduce/CpuConv_ranges.cpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/mapreduce
copying build/lib/pykeops/keops/core/mapreduce/GpuConv1D.cu -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/mapreduce
copying build/lib/pykeops/keops/core/mapreduce/GpuConv1D_ranges.cu -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/mapreduce
copying build/lib/pykeops/keops/core/mapreduce/GpuConv2D.cu -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/mapreduce
copying build/lib/pykeops/keops/core/mapreduce/broadcast_batch_dimensions.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core/mapreduce
copying build/lib/pykeops/keops/core/link_autodiff.cpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core
copying build/lib/pykeops/keops/core/link_autodiff.cu -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core
copying build/lib/pykeops/keops/core/pre_headers.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/core
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific
copying build/lib/pykeops/keops/specific/CMakeLists.txt -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/radial_kernels
copying build/lib/pykeops/keops/specific/radial_kernels/cuda_conv.cu -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/radial_kernels
copying build/lib/pykeops/keops/specific/radial_kernels/cuda_conv.cx -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/radial_kernels
copying build/lib/pykeops/keops/specific/radial_kernels/cuda_grad1conv.cu -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/radial_kernels
copying build/lib/pykeops/keops/specific/radial_kernels/cuda_grad1conv.cx -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/radial_kernels
copying build/lib/pykeops/keops/specific/radial_kernels/radial_kernels.h -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/radial_kernels
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/shape_distance
copying build/lib/pykeops/keops/specific/shape_distance/fshape_gpu.cu -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/shape_distance
copying build/lib/pykeops/keops/specific/shape_distance/fshape_gpu.cx -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/shape_distance
copying build/lib/pykeops/keops/specific/shape_distance/kernels.cx -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/specific/shape_distance
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao
creating $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/accumulate.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/at_index.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/concatenate.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/config.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/contains.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/difference.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/exclusive_scan.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/first.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/functional.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/head.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/inclusive_scan.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/index_of.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/index_of_seq.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/integer_sequence.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/is_all.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/is_any.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/make_integer_range.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/make_integer_sequence.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/map.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/max.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/min.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/minus.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/multiplies.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/partial_accumulate.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/partial_prod.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/partial_reduce.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/partial_sum.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/permutate.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/plus.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/prod.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/reduce.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/reverse.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/scale.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/select.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/sequence_helper.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/sort.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/sort_index.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/sum.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/tail.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/keops/lib/sequences/include/tao/seq/zip.hpp -> $PREFIX/lib/python3.8/site-packages/pykeops/keops/lib/sequences/include/tao/seq
copying build/lib/pykeops/version -> $PREFIX/lib/python3.8/site-packages/pykeops
creating $PREFIX/lib/python3.8/site-packages/pykeops/pybind11
creating $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include
creating $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
creating $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11/detail
copying build/lib/pykeops/pybind11/include/pybind11/detail/class.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11/detail
copying build/lib/pykeops/pybind11/include/pybind11/detail/common.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11/detail
copying build/lib/pykeops/pybind11/include/pybind11/detail/descr.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11/detail
copying build/lib/pykeops/pybind11/include/pybind11/detail/init.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11/detail
copying build/lib/pykeops/pybind11/include/pybind11/detail/internals.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11/detail
copying build/lib/pykeops/pybind11/include/pybind11/detail/typeid.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11/detail
copying build/lib/pykeops/pybind11/include/pybind11/attr.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/buffer_info.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/cast.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/chrono.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/common.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/complex.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/eigen.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/embed.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/eval.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/functional.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/iostream.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/numpy.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/operators.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/options.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/pybind11.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/pytypes.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/stl.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/include/pybind11/stl_bind.h -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/include/pybind11
copying build/lib/pykeops/pybind11/CMakeLists.txt -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11
creating $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/tools
copying build/lib/pykeops/pybind11/tools/FindPythonLibsNew.cmake -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/tools
copying build/lib/pykeops/pybind11/tools/pybind11Tools.cmake -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/tools
copying build/lib/pykeops/pybind11/tools/pybind11Config.cmake.in -> $PREFIX/lib/python3.8/site-packages/pykeops/pybind11/tools
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/config.py to config.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/common/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/common/compile_routines.py to compile_routines.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/common/get_options.py to get_options.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/common/keops_io.py to keops_io.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/common/lazy_tensor.py to lazy_tensor.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/common/operations.py to operations.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/common/parse_type.py to parse_type.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/common/set_path.py to set_path.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/common/utils.py to utils.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/operations.py to operations.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/utils.py to utils.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/cluster/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/cluster/grid_cluster.py to grid_cluster.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/cluster/matrix.py to matrix.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/cluster/utils.py to utils.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/convolutions/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/convolutions/radial_kernel.py to radial_kernel.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/generic/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/generic/generic_ops.py to generic_ops.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/generic/generic_red.py to generic_red.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/lazytensor/LazyTensor.py to LazyTensor.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/lazytensor/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/shape_distance/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/shape_distance/fshape_scp.py to fshape_scp.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/numpy/shape_distance/fshape_scp_dx.py to fshape_scp_dx.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/test/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/test/install.py to install.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/test/unit_tests_numpy.py to unit_tests_numpy.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/test/unit_tests_pytorch.py to unit_tests_pytorch.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/half2_convert.py to half2_convert.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/operations.py to operations.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/utils.py to utils.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/cluster/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/cluster/grid_cluster.py to grid_cluster.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/cluster/matrix.py to matrix.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/cluster/utils.py to utils.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/generic/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/generic/generic_ops.py to generic_ops.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/generic/generic_red.py to generic_red.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/lazytensor/LazyTensor.py to LazyTensor.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/lazytensor/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/kernel_product/__init__.py to __init__.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/kernel_product/features_kernels.py to features_kernels.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/kernel_product/formula.py to formula.cpython-38.pyc
byte-compiling $PREFIX/lib/python3.8/site-packages/pykeops/torch/kernel_product/kernels.py to kernels.cpython-38.pyc
running install_egg_info
running egg_info
creating pykeops.egg-info
writing pykeops.egg-info/PKG-INFO
writing dependency_links to pykeops.egg-info/dependency_links.txt
writing requirements to pykeops.egg-info/requires.txt
writing top-level names to pykeops.egg-info/top_level.txt
writing manifest file 'pykeops.egg-info/SOURCES.txt'
reading manifest file 'pykeops.egg-info/SOURCES.txt'
writing manifest file 'pykeops.egg-info/SOURCES.txt'
Copying pykeops.egg-info to $PREFIX/lib/python3.8/site-packages/pykeops-1.4.1.1-py3.8.egg-info
running install_scripts
writing list of installed files to 'record.txt'
++ readlink -f /uio/kant/ifi-ansatt-u02/davidvo/workspace/keops/.conda/recipe/..
+ rsync -av /uio/kant/ifi-ansatt-u02/davidvo/workspace/keops/.conda/etc/ /scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla/etc/
sending incremental file list
created directory $PREFIX/etc
./
conda/
conda/activate.d/
conda/activate.d/activate.sh
conda/deactivate.d/
conda/deactivate.d/deactivate.sh

sent 570 bytes  received 355 bytes  1,850.00 bytes/sec
total size is 245  speedup is 0.26

Resource usage statistics from building pykeops:
   Process count: 1
   CPU time: Sys=0:00:00.0, User=0:00:00.0
   Memory: 1.6M
   Disk usage: 49.4K
   Time elapsed: 0:00:02.2

Packaging pykeops
INFO:conda_build.build:Packaging pykeops
INFO conda_build.build:build(2208): Packaging pykeops
Packaging pykeops-1.4.2-py38h6bb024c_0
INFO:conda_build.build:Packaging pykeops-1.4.2-py38h6bb024c_0
INFO conda_build.build:bundle_conda(1451): Packaging pykeops-1.4.2-py38h6bb024c_0
compiling .pyc files...
number of files: 327
Fixing permissions
INFO :: Time taken to mark (prefix)
        0 replacements in 0 files was 0.06 seconds
TEST START: /scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/linux-64/pykeops-1.4.2-py38h6bb024c_0.tar.bz2
Nothing to test for: /scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/linux-64/pykeops-1.4.2-py38h6bb024c_0.tar.bz2
Renaming work directory '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work' to '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work_moved_pykeops-1.4.2-py38h6bb024c_0_linux-64_main_build_loop'
INFO:conda_build.utils:Renaming work directory '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work' to '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work_moved_pykeops-1.4.2-py38h6bb024c_0_linux-64_main_build_loop'
INFO conda_build.utils:shutil_move_more_retrying(2007): Renaming work directory '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work' to '/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work_moved_pykeops-1.4.2-py38h6bb024c_0_linux-64_main_build_loop'
shutil.move(work)=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work, dest=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work_moved_pykeops-1.4.2-py38h6bb024c_0_linux-64_main_build_loop)
INFO:conda_build.utils:shutil.move(work)=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work, dest=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work_moved_pykeops-1.4.2-py38h6bb024c_0_linux-64_main_build_loop)
INFO conda_build.utils:shutil_move_more_retrying(2014): shutil.move(work)=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work, dest=/scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/pykeops_1602608559315/work_moved_pykeops-1.4.2-py38h6bb024c_0_linux-64_main_build_loop)
Failed to rename work directory despite sleeping and retrying. This is some Windows file locking mis-bahaviour.
ERROR:conda_build.utils:Failed to rename work directory despite sleeping and retrying. This is some Windows file locking mis-bahaviour.
ERROR conda_build.utils:shutil_move_more_retrying(2029): Failed to rename work directory despite sleeping and retrying. This is some Windows file locking mis-bahaviour.
# Automatic uploading is disabled
# If you want to upload package(s) to anaconda.org later, type:

anaconda upload /scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/linux-64/pykeops-1.4.2-py38h6bb024c_0.tar.bz2

# To have conda build upload to anaconda.org automatically, use
# $ conda config --set anaconda_upload yes

anaconda_upload is not set.  Not uploading wheels: []
####################################################################################
Resource usage summary:

Total time: 0:01:37.3
CPU usage: sys=0:00:00.0, user=0:00:00.0
Maximum memory usage observed: 1.6M
Total disk usage observed (not including envs): 49.4K
bcharlier commented 3 years ago
dvolgyes commented 3 years ago

It doesn't work, and probably because of these lines around the end of the log:

ERROR:conda_build.utils:Failed to rename work directory despite sleeping and retrying. This is some Windows file locking mis-bahaviour.
ERROR conda_build.utils:shutil_move_more_retrying(2029): Failed to rename work directory despite sleeping and retrying. This is some Windows file locking mis-bahaviour.
bcharlier commented 3 years ago

ok I retry on my side

bcharlier commented 3 years ago

I have more or less the same logs (including the renaming error). But I can still create the new working env with pykeops...

do you ?

dvolgyes commented 3 years ago

I cannot, neither installing the package in the current environment, or creating a new one, regardless if i specify pykeops version or i don't. (And obviously, the error message in conda_build.utils is wrong, i don't use windows. I try to look up the error on google, but so far i did not find anything useful.)

9:41:18 › conda create -y -n pykeops -c local -c pytorch -c conda-forge pykeops    
Collecting package metadata (current_repodata.json): done
Solving environment: failed with repodata from current_repodata.json, will retry with next repodata source.
Collecting package metadata (repodata.json): done
Solving environment: failed

PackagesNotFoundError: The following packages are not available from current channels:

  - pykeops

Current channels:

  - https://conda.anaconda.org/pytorch/linux-64
  - https://conda.anaconda.org/pytorch/noarch
  - https://conda.anaconda.org/conda-forge/linux-64
  - https://conda.anaconda.org/conda-forge/noarch
  - https://repo.anaconda.com/pkgs/main/linux-64
  - https://repo.anaconda.com/pkgs/main/noarch
  - https://repo.anaconda.com/pkgs/r/linux-64
  - https://repo.anaconda.com/pkgs/r/noarch

To search for alternate channels that may provide the conda package you're
looking for, navigate to

    https://anaconda.org

and use the search bar at the top of the page.
maddenp commented 3 years ago

recipe.zip

I have a slightly simplified recipe, attached. Here, meta.yaml pins the keops source to a recent revision that my colleague suggested. Ultimately, it would probably be best to define a jinja2 variable for a specific release version of keops, and use that variable to define both the pykeops conda package version and the git_rev (in our usage, anyway, we tie the conda package version number to the version number of the underlying code, and increment the build number in meta.yaml if we need new builds of the same source version, e.g. between-releases commits to master).

Here's my package build and environment creation, using a fresh Miniconda install on Linux:

(base) ~ % conda build recipe -c conda-forge --override-channels
[lots of output]
(base) ~ % conda search -c local pykeops
Loading channels: done
# Name                       Version           Build  Channel             
pykeops                        1.4.1  py37ha8d69ae_0  home/pmadden/miniconda/conda-bld
(base) ~ % conda create -y -n pykeops -c local -c pytorch -c conda-forge -c defaults --override-channels pykeops=1.4.1=py37ha8d69ae_0
(base) ~ % conda activate pykeops
(pykeops) ~ % python
Python 3.7.8 | packaged by conda-forge | (default, Jul 31 2020, 02:25:08) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pykeops
>>>

I get errors trying to run pykeops.test_numpy_bindings() at this point, so maybe I picked a bad git_rev in meta.yaml, but I'm not seeing any issues with conda build, packaging, or environment creation. This is all on Linux. of course, so you may have different experiences with other OSes.

FWIW, conda often emits warning and error messages that can (and should) safely be ignored. It's unfortunate. @dvolgyes I see the same Windows-related (apparent) error on Linux, where it is obviously nonsense. If you're using Linux that should be safe to ignore; it has no affect on my builds, anyway.

bcharlier commented 3 years ago

@dvolgyes ,

as far as I understand your problem: the conda pykeops package has been correctly generated in /scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/linux-64/pykeops-1.4.2-py38h6bb024c_0.tar.bz2.

It means that you are already in a conda venv (called pytorch15 if I am not mistaken) when building the package. The option -c local does not work as expected as conda does not look in the /scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/linux-64/ folder. Can you try something like

conda create -y -n pykeops -c local -c pytorch -c conda-forge /scratch/davidvo/miniconda3/envs/pytorch15/conda-bld/linux-64/pykeops-1.4.2-py38h6bb024c_0.tar.bz2

dvolgyes commented 3 years ago

Hi,

Thanks for the hard work. Partial results: indeed the conva environment messed up the build, outside i can build the package and install it, somewhat. The create command above generates an incomplete environment, and i have some other issues, so i couldn't decide yet about whether it 'works' or not, but i work on it, and i will write update soon.

bcharlier commented 3 years ago

Dear @dvolgyes , @maddenp

I have simplified the conda recipe:

It build nicely on my system (arch linux).

# To build the conda package :
cd keops   # root folder of keops git
conda build -c pytorch -c nvidia .conda/recipe

# To create an environment
conda create -y -n pykeops_env -c local -c pytorch -c nvidia pykeops

May you test the conda recipe in the last commit of master on your system? Thank you for your help.

b.

dvolgyes commented 3 years ago

Hi, Thanks! I work on it, i have an ubuntu and a red hat machine, i will let you know soon what happens there.

dvolgyes commented 3 years ago

Hi,

Sorry for the slow response, it was a complicated week. I started to try it in docker, because the local computer changes were hard to manage in a reproducible manner. I made a short Dockerfile for compiling keops, but i got stock. (I used a nvidia-docker runtime, so the docker image actually have GPUs available.) The dockerfile looks like this:

FROM nvidia/cuda:10.1-base
MAINTAINER david.volgyes@ieee.org
RUN apt-get update && apt-get install -y wget bzip2 mc  git cmake make gcc g++ rsync
RUN wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O Miniconda.sh && /bin/bash Miniconda.sh -b -p /opt/conda && rm Miniconda.sh
ENV PATH /opt/conda/bin:$PATH

WORKDIR /opt/keops
RUN git clone https://github.com/getkeops/keops.git /opt/keops

RUN conda update --all
RUN conda install -y conda-build

When the docker image is finished, from the /opt/keops directory i tried to execute the above recommended commands, but i fail its in a strange way. I only copy the end of the log, the beginning seems to be OK, but it seems to miss a file "keops/pykeops/keops/lib/sequences/include/tao/seq/". Any idea why or how? Or any recommendation how to proceed? (Different cuda base images yield the same issue, 10.1 is just a random version.)

copying build/lib/pykeops/numpy/generic/generic_ops.py -> $PREFIX/lib/python3.7/site-packages/pykeops/numpy/generic
copying build/lib/pykeops/numpy/generic/generic_red.cpp -> $PREFIX/lib/python3.7/site-packages/pykeops/numpy/generic
copying build/lib/pykeops/torch_headers.h.in -> $PREFIX/lib/python3.7/site-packages/pykeops
copying build/lib/pykeops/version -> $PREFIX/lib/python3.7/site-packages/pykeops
warning: install_lib: byte-compiling is disabled, skipping.

running install_egg_info
running egg_info
creating pykeops.egg-info
writing pykeops.egg-info/PKG-INFO
writing dependency_links to pykeops.egg-info/dependency_links.txt
writing requirements to pykeops.egg-info/requires.txt
writing top-level names to pykeops.egg-info/top_level.txt
writing manifest file 'pykeops.egg-info/SOURCES.txt'
reading manifest file 'pykeops.egg-info/SOURCES.txt'
writing manifest file 'pykeops.egg-info/SOURCES.txt'
Copying pykeops.egg-info to $PREFIX/lib/python3.7/site-packages/pykeops-1.4.1.1-py3.7.egg-info
running install_scripts
writing list of installed files to 'record.txt'
++ readlink -f /opt/keops/.conda/recipe/..
+ rsync -av /opt/keops/.conda/etc/ /opt/conda/conda-bld/none_1603463655422/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehol/etc/
sending incremental file list
created directory $PREFIX/etc
./
conda/
conda/activate.d/
conda/activate.d/activate.sh
conda/deactivate.d/
conda/deactivate.d/deactivate.sh

sent 504 bytes  received 355 bytes  1,718.00 bytes/sec
total size is 245  speedup is 0.29

Resource usage statistics from building none:
   Process count: 11
   CPU time: Sys=0:00:01.0, User=0:00:01.9
   Memory: 47.7M
   Disk usage: 50.2K
   Time elapsed: 0:00:26.5

Packaging none
INFO:conda_build.build:Packaging none
INFO conda_build.build:build(2214): Packaging none
Packaging none-None-pyh6bb024c_0
INFO:conda_build.build:Packaging none-None-pyh6bb024c_0
INFO conda_build.build:bundle_conda(1454): Packaging none-None-pyh6bb024c_0
Traceback (most recent call last):
  File "/opt/conda/conda-bld/none_1603463655422/work/_load_setup_py_data.py", line 130, in <module>
    data = load_setup_py_data(**args.__dict__)
  File "/opt/conda/conda-bld/none_1603463655422/work/_load_setup_py_data.py", line 93, in load_setup_py_data
    exec(code, ns, ns)
  File "/opt/keops/setup.py", line 56, in <module>
    tao_seq_files = import_files('keops/lib/sequences/include/tao/seq/')
  File "/opt/keops/setup.py", line 20, in import_files
    res = [path.join(dirname, f) for f in os.listdir(_dirname) if any(f.endswith(ext) for ext in ext)]
FileNotFoundError: [Errno 2] No such file or directory: '/opt/keops/pykeops/keops/lib/sequences/include/tao/seq/'
Traceback (most recent call last):
  File "/opt/conda/bin/conda-build", line 11, in <module>
    sys.exit(main())
  File "/opt/conda/lib/python3.8/site-packages/conda_build/cli/main_build.py", line 474, in main
    execute(sys.argv[1:])
  File "/opt/conda/lib/python3.8/site-packages/conda_build/cli/main_build.py", line 463, in execute
    outputs = api.build(args.recipe, post=args.post, test_run_post=args.test_run_post,
  File "/opt/conda/lib/python3.8/site-packages/conda_build/api.py", line 186, in build
    return build_tree(
  File "/opt/conda/lib/python3.8/site-packages/conda_build/build.py", line 3008, in build_tree
    packages_from_this = build(metadata, stats,
  File "/opt/conda/lib/python3.8/site-packages/conda_build/build.py", line 2291, in build
    newly_built_packages = bundlers[pkg_type](output_d, m, env, stats)
  File "/opt/conda/lib/python3.8/site-packages/conda_build/build.py", line 1474, in bundle_conda
    top_build = metadata.get_top_level_recipe_without_outputs().get('build', {}) or {}
  File "/opt/conda/lib/python3.8/site-packages/conda_build/metadata.py", line 2294, in get_top_level_recipe_without_outputs
    top_no_outputs = yaml.safe_load(self._get_contents(False,
  File "/opt/conda/lib/python3.8/site-packages/conda_build/metadata.py", line 1544, in _get_contents
    rendered = template.render(environment=env)
  File "/opt/conda/lib/python3.8/site-packages/jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "/opt/conda/lib/python3.8/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/opt/conda/lib/python3.8/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 3, in top-level template code
  File "/opt/conda/lib/python3.8/site-packages/conda_build/jinja_context.py", line 120, in load_setup_py_data
    check_call_env(args, env=env)
  File "/opt/conda/lib/python3.8/site-packages/conda_build/utils.py", line 410, in check_call_env
    return _func_defaulting_env_to_os_environ('call', *popenargs, **kwargs)
  File "/opt/conda/lib/python3.8/site-packages/conda_build/utils.py", line 401, in _func_defaulting_env_to_os_environ
    subprocess.check_call(_args, **kwargs)
  File "/opt/conda/lib/python3.8/subprocess.py", line 364, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['/opt/conda/conda-bld/none_1603463655422/_build_env/bin/python', '/opt/conda/conda-bld/none_1603463655422/work/_load_setup_py_data.py', '/opt/conda/conda-bld/none_1603463655422/work', '../../setup.py', '--from-recipe-dir', '--recipe-dir', '/opt/keops/.conda/recipe']' returned non-zero exit status 1.
AdrianSosic commented 1 year ago

Hi folks, I was just looking for whether there have been any efforts to bring keops to conda forge and stumbled upon this conversation. Since it's been quite a while since the last post: has there been any progress or can someone tell what is the current state? Kind regards!

jeanfeydy commented 1 year ago

Hi @AdrianSosic ,

Thanks for your interest in the library! Our current understanding is that with KeOps v2.0, shipping pre-built binaries has stopped being a pressing issue:

Notably, we observe an order of magnitude less installation-related issues since the release of the v2.0 engine. Most remaining issues seem to be related to non-standard PATH for the CUDA toolkit, mostly on shared academic clusters. These can be set explicitly using the CUDA_PATH environment variable.

As a consequence, I would tend to close the issue - but please feel free to re-open if you see a motivation for it.

Best regards, Jean