docs: @Override
      public PointersPair alloc(AllocationStatus targetMode, AllocationPoint point, AllocationShape shape,
                      boolean initialize) {
  
          long reqMemory = AllocationUtils.getRequiredMemory(shape);
          CudaContext context = getCudaContext();
          switch (targetMode) {
              case HOST: {
                  if (MemoryTracker.getInstance().getActiveHostAmount() + reqMemory >= configuration.getMaximumZeroAllocation()) {
  
                      while (MemoryTracker.getInstance().getActiveHostAmount() + reqMemory >= configuration.getMaximumZeroAllocation()) {
  
                          val before = MemoryTracker.getInstance().getActiveHostAmount();
                          memoryProvider.purgeCache();
                          Nd4j.getMemoryManager().invokeGc();
                          val after = MemoryTracker.getInstance().getActiveHostAmount();
  
                          log.debug("[HOST] before: {}; after: {};", before, after);
  
                          if (MemoryTracker.getInstance().getActiveHostAmount() + reqMemory >= configuration.getMaximumZeroAllocation()) {
                              try {
                                  log.warn("No available [HOST] memory, sleeping for a while... Consider increasing -Xmx next time.");
                                  log.debug("Currently used: [" + zeroUseCounter.get() + "], allocated objects: [" + zeroAllocations.get(0) + "]");
  
                                  memoryProvider.purgeCache();
                                  Nd4j.getMemoryManager().invokeGc();
                                  Thread.sleep(1000);
                              } catch (Exception e) {
                                  throw new RuntimeException(e);
                              }
                          }
                      }
                  }
  
  
                  PointersPair pair = memoryProvider.malloc(shape, point, targetMode);
  
  
                  if (initialize) {
                      org.bytedeco.javacpp.Pointer.memset(pair.getHostPointer(), 0, reqMemory);
                      point.tickHostWrite();
                  }
  
  
                  pickupHostAllocation(point);
  
                  return pair;
              }
              case DEVICE: {
                  int deviceId = getDeviceId();
  
                  PointersPair returnPair = new PointersPair();
                  PointersPair tmpPair = new PointersPair();
  
                  // if the initial memory location is device, there's a chance we don't have zero memory allocated
                  if (point.getPointers() == null || point.getPointers().getHostPointer() == null) {
                      tmpPair = alloc(AllocationStatus.HOST, point, point.getShape(), initialize);
  
                      returnPair.setDevicePointer(tmpPair.getHostPointer());
                      returnPair.setHostPointer(tmpPair.getHostPointer());
  
                      point.setAllocationStatus(AllocationStatus.HOST);
                      point.setPointers(tmpPair);
                  }
  /*
                  if (reqMemory < configuration.getMaximumSingleHostAllocation()
                                  && deviceMemoryTracker.getAllocatedSize(deviceId) + reqMemory < configuration
                                                  .getMaximumDeviceAllocation()) {
  */
  
  
                      //val timeStart = System.nanoTime();
                      //long free = NativeOpsHolder.getInstance().getDeviceNativeOps().getDeviceFreeMemory();
                      //val timeEnd = System.nanoTime();
  
                      //log.info("Free time: {} ns; Free memory: {} bytes", (timeEnd - timeStart), free);
  
                      if (deviceMemoryTracker.reserveAllocationIfPossible(Thread.currentThread().getId(), deviceId, reqMemory)) {
                          point.setDeviceId(deviceId);
                          val pair = memoryProvider.malloc(shape, point, targetMode);
                          if (pair != null) {
                              returnPair.setDevicePointer(pair.getDevicePointer());
  
                              point.setAllocationStatus(AllocationStatus.DEVICE);
  
                              if (point.getPointers() == null)
                                  throw new RuntimeException("PointersPair can't be null");
  
                              point.getPointers().setDevicePointer(pair.getDevicePointer());
  
                              deviceAllocations.get(deviceId).put(point.getObjectId(), point.getObjectId());
  
  
                              val p = point.getBucketId();
  
                              if (p != null) {
                                  val m = zeroAllocations.get(point.getBucketId());
  
                                  // m can be null, if that's point from workspace - just no bucketId for it
                                  if (m != null)
                                      m.remove(point.getObjectId());
                              }
  
                              deviceMemoryTracker.addToAllocation(Thread.currentThread().getId(), deviceId, reqMemory);
  
                              //  point.tickDeviceWrite();
                              point.tickHostWrite();
  
                              if (!initialize) {
                                  point.tickDeviceWrite();
                                  point.tickHostRead();
                              } else {
                                  nativeOps.memsetAsync(pair.getDevicePointer(), 0, reqMemory, 0,
                                                  context.getSpecialStream());
                                  context.getSpecialStream().synchronize();
  
                                  point.tickDeviceWrite();
                                  point.tickHostRead();
  
                                  //AtomicAllocator.getInstance().getFlowController().registerAction(ctx, point);
                              }
                          } else {
                              log.warn("Out of [DEVICE] memory, host memory will be used instead: deviceId: [{}], requested bytes: [{}]; Approximate free bytes: {}; Real free bytes: {}", deviceId, reqMemory, MemoryTracker.getInstance().getApproximateFreeMemory(deviceId), MemoryTracker.getInstance().getPreciseFreeMemory(deviceId));
                              log.info("Total allocated dev_0: {}", MemoryTracker.getInstance().getActiveMemory(0));
                              log.info("Cached dev_0: {}", MemoryTracker.getInstance().getCachedAmount(0));
                              log.info("Allocated dev_0: {}", MemoryTracker.getInstance().getAllocatedAmount(0));
                              log.info("Workspace dev_0: {}", MemoryTracker.getInstance().getWorkspaceAllocatedAmount(0));
                              //log.info("Total allocated dev_1: {}", MemoryTracker.getInstance().getActiveMemory(1));
                              // if device memory allocation failed (aka returned NULL), keep using host memory instead
  
                              returnPair.setDevicePointer(tmpPair.getHostPointer());
  
                              point.setAllocationStatus(AllocationStatus.HOST);
  
                              Nd4j.getMemoryManager().invokeGc();
                              try {
                                  Thread.sleep(100);
                              } catch (Exception e) {
  
                              }
                          }
                      } else {
                          log.warn("Hard limit on [DEVICE] memory hit, please consider tuning memory parameters, deviceId [{}]",
                                          deviceId);
  
                          Nd4j.getMemoryManager().invokeGc();
                          try {
                              Thread.sleep(100);
                          } catch (InterruptedException e) {
                              //
                          }
                      }
  
                  return returnPair;
              }
              default:
                  throw new IllegalStateException("Can't allocate memory on target [" + targetMode + "]");
          }
      }