Thank you, it really helped)
So I’ve done something like that:
import torch
from concurrent.futures import ThreadPoolExecutor

import MyCustomCudaModule as my_module

class MyClass:
    def __init__(self, data):
        self.gpus = [0, 1]  #  set devices I'd like to use

        # Split some data to chunks and allocate on its own GPU
        self.tensor0 = torch.tensor(data[0], dtype=torch.float64).chunk(len(self.gpus))
        self.tensor0 = [self.tensor0[idx].to(f'cuda:{gpu}') for idx, gpu in enumerate(self.gpus)]

        self.tensor1 = torch.tensor(data[1], dtype=torch.float64).chunk(len(self.gpus))
        self.tensor1 = [self.tensor1[idx].to(f'cuda:{gpu}') for idx, gpu in enumerate(self.gpus)]

    def calculate(self):
        # Prepare input data to use my CUDA method
        chunks = list()
        for idx in range(len(self.gpus)):
            chunk = [self.tensor0[idx], self.tensor1[idx]]
            chunks.append(chunk)

        # Start my calculations asynced 
        futures = self.executor.map(lambda ch: my_module.calculate(*ch), chunks)

        total_result = 0.0
        for result in futures:
            total_result += result.item()  # return calculations result from GPU to CPU

        return result

It splits my data between GPUs and correctly calculates but I have no speedup (the speed is the same as I use 1 GPU).
What should I do to calculate faster?