docs: public INDArray ndArrayFromTensor(TF_Tensor tensor) {
          int rank = TF_NumDims(tensor);
  
          int[] ndShape;
          if (rank == 0) {
              // scalar
              ndShape = new int[] { 1 };
          } else {
              ndShape = new int[rank];
              for (int i = 0; i < ndShape.length; i++) {
                  ndShape[i] = (int) TF_Dim(tensor,i);
              }
          }
  
          int tfType = TF_TensorType(tensor);
          DataType nd4jType = typeFor(tfType);
  
          int length = ArrayUtil.prod(ndShape);
          INDArray array;
          if (nd4jType == DataType.UTF8) {
              String[] strings = new String[length];
              BytePointer data = new BytePointer(TF_TensorData(tensor)).capacity(TF_TensorByteSize(tensor));
              BytePointer str = new BytePointer((Pointer)null);
              SizeTPointer size = new SizeTPointer(1);
              TF_Status status = TF_NewStatus();
              for (int i = 0; i < length; i++) {
                  long offset = data.position(8 * i).getLong();
                  TF_StringDecode(data.position(8 * length + offset), data.capacity() - data.position(), str, size, status);
                  if (TF_GetCode(status) != TF_OK) {
                      throw new IllegalStateException("ERROR: Unable to convert tensor " + TF_Message(status).getString());
                  }
                  strings[i] = str.position(0).capacity(size.get()).getString();
              }
              TF_DeleteStatus(status);
              array = Nd4j.create(strings);
          } else {
              Pointer pointer = TF_TensorData(tensor).capacity(length);
              Indexer indexer = indexerForType(nd4jType,pointer);
              DataBuffer d = Nd4j.createBuffer(indexer.pointer(),nd4jType,length,indexer);
              array = Nd4j.create(d,ndShape);
          }
          Nd4j.getAffinityManager().tagLocation(array, AffinityManager.Location.HOST);
          return array;
      }