Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

in javacpp-pytorch tensor slice batch broadcast opration how to do like python pytorch style ? #1563

Open
mullerhai opened this issue Jan 2, 2025 · 7 comments

Comments

@mullerhai
Copy link

HI ,
in python code , tensor slice batch broadcast opration is very easy and convient ,like this

//  encoding[::, 0 :: 2] = torch.sin(position * div_term)
//  encoding[::, 1 :: 2] = torch.cos(position * div_term)

but now in javacpp-pytorch ,I can not do that to set batch value ,so how to do like this

thanks

@mullerhai
Copy link
Author

if I write this code like this



    for (int ti = 0; ti < pTimeSize; ti++) {
        for (int ba = 0; ba < pBatchSize; ba++) {
            for (int ch = 0; ch < pChannelSize; ch++) {
                for (int ro = 0; ro < pRowSize; ro++) {
                    for (int co = 0; co < pColumnSize; co++) {
                        int   i = 0, pos = 0;
                        float div_term = 0, pe = 0;
                        i   = co / 2;
                        pos = ch;
                        div_term = pow(10000, 2 * i / (double)pColumnSize);
                        if (co % 2 == 0)
                            pe = sin(pos / div_term);
                        else
                            pe = cos(pos / div_term);
                        (*pPositionalEncoding)[Index5D(peShape, ti, ba, ch, ro, co)] = pe;
                    }
                }
            }
        }
    }


I think not suit pytorch

@mullerhai
Copy link
Author

or like this

  private def initializeEncodings(): Unit = {
    for (pos <- 0 until config.maxSeqLen; i <- 0 until config.embeddingDim) {
      val angle = pos / math.pow(10000, 2 * (i / 2) / config.embeddingDim)
      encodings(pos)(i) = if (i % 2 == 0) sin(angle) else cos(angle)
    }
  }

@HGuillemet
Copy link
Collaborator

HGuillemet commented Jan 2, 2025

See https://pytorch.org/cppdocs/notes/tensor_indexing.html.
One again, javacpp pytorch is a binding to C++ api, not to Python API.

@mullerhai
Copy link
Author

I see , thanks

See https://pytorch.org/cppdocs/notes/tensor_indexing.html. One again, javacpp pytorch is a binding to C++ api, not to Pytorch API.

in cpp libtorch , I see them write code like this

              auto pe = torch::zeros({1, this->max_len, this->d_model});
                    auto position = torch::arange(0, max_len).unsqueeze(1);
                    auto div_term = torch::exp(torch::arange(0, d_model, 2) * -std::log(10000.0) / d_model);
                    pe.slice(2, 0, pe.size(2), 2) = torch::sin(position * div_term);
                    pe.slice(2, 1, pe.size(2), 2) = torch::cos(position * div_term);

@HGuillemet
Copy link
Collaborator

In Java you don't have operator overloading, so, compared to C++, you must replace the operators like *, = ... on tensor objects to explicit method calls.
Also you don't have curly brace initializers. You must use explicit new.

@mullerhai
Copy link
Author

在 Java 中,没有运算符重载,因此与 C++ 相比,您必须将张量对象上的运算符(如*=...)替换为显式方法调用。 此外,您没有花括号初始化程序。您必须使用显式new

ok, I know ,thanks ,I will try another way do that

@mullerhai
Copy link
Author

last year ,I found I had write some code to do tensor index set value
python origin code

        batch_size, num_fields, embed_dim = x.shape
        a_prev = torch.ones((batch_size, num_fields + 1, embed_dim), dtype=torch.float).to(x.device)
        for t in range(self.order):
            a = torch.zeros((batch_size, num_fields + 1, embed_dim), dtype=torch.float).to(x.device)
            a[:, t+1:, :] += x[:, t:, :] * a_prev[:, t:-1, :]
            a = torch.cumsum(a, dim=1)
            a_prev = a

use javacpp-pytorch scala code


   val shape = xs.shape()
    val batch_size = shape(0)
    val num_fields = shape(1)
    val embed_dim = shape(2)
    var a_prev = torch.ones(Array(batch_size, num_fields + 1, embed_dim), new ScalarTypeOptional(ScalarType.Float), new LayoutOptional, new DeviceOptional(xs.device()), new BoolOptional())
    var a = torch.zeros(Array(batch_size, num_fields + 1, embed_dim), new ScalarTypeOptional(ScalarType.Float), new LayoutOptional, new DeviceOptional(xs.device()), new BoolOptional())
    for (t <- 0 until this.order by 1) {
      val sliceNone = new Slice()
      val sliceA = new Slice(new SymIntOptional(new SymInt(t+1)), new SymIntOptional(new SymInt(0)), new SymIntOptional(new SymInt(1)))
      val sliceA_prev = new Slice(new SymIntOptional(new SymInt(t)), new SymIntOptional(new SymInt(-1)), new SymIntOptional(new SymInt(1)))
      val sliceX = new Slice(new SymIntOptional(new SymInt(t)), new SymIntOptional(new SymInt(0)), new SymIntOptional(new SymInt(1)))
      val indexSliceNone = new TensorIndex(sliceNone)
      val indexSliceA = new TensorIndex(sliceA)
      val indexSliceA_prev = new TensorIndex(sliceA_prev)
      val indexSliceX = new TensorIndex(sliceX)

      val indexVectorA = new TensorIndexVector(indexSliceNone, indexSliceA, indexSliceNone)
      val indexArrayRefA = new TensorIndexArrayRef(indexVectorA)

      val indexVectorX = new TensorIndexVector(indexSliceNone, indexSliceX, indexSliceNone)
      val indexArrayRefX = new TensorIndexArrayRef(indexVectorX)

      val indexVectorA_prev = new TensorIndexVector(indexSliceNone, indexSliceA_prev, indexSliceNone)
      val indexArrayRefA_prev = new TensorIndexArrayRef(indexVectorA_prev)

      a.index(indexArrayRefA).add_(torch.mul(x.index(indexArrayRefX), a_prev.index(indexArrayRefA_prev)))
      a = torch.cumsum(a, 1)
      a_prev = a

use javacpp-pytorch for tensor index slice batch broadcast opration is so hard and more line than python pytorch, do we has easy way ? thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants