mojo icon indicating copy to clipboard operation
mojo copied to clipboard

[Request]: Implement '__matmul__' method on 'PythonObject'

Open jcoombes opened this issue 1 year ago • 2 comments

Bug description

I'm writing some 'hello-gpu' code which works with pytorch.

/home/user/code/obvs/obvs/gputest.🔥:29:15: error: 'PythonObject' does not implement the 'matmul' method z = x @ y

Steps to reproduce

  • Include relevant code snippet or link to code that did not work as expected.
from python import Python

fn main() raises:
    let pt = Python.import_module("torch")

    # Print CUDA details
    print("CUDA available:" + pt.cuda.is_available())
    print("CUDA device count:" + pt.cuda.device_count())

    # Create random input and output tensors
    let x = pt.randn(3, 3)
    let y = pt.randn(3, 3)

    if pt.cuda.is_available():
        # Move tensors to GPU
        x = x.cuda()
        y = y.cuda()

        # Perform matrix multiplication on GPU
        let z = x @ y
        print("Matrix multiplication result on GPU:\n")
        print(z)

        # Move result back to CPU
        z = z.cpu()
    else:
        # Perform computation on CPU
        z = x @ y
        print("Matrix multiplication result on CPU:\n")
        print(z)
  • Include anything else that might help us debug the issue. I have a rough intuition this should be a relatively straightforward bug, I think we just need the PythonObject to call matmul() directly.

Running this code in a similar .py file returns a result as below:

import torch as pt

def main():
    # Print CUDA details
    print("CUDA available:" + str(pt.cuda.is_available()))
    print("CUDA device count:" + str(pt.cuda.device_count()))

    # Create random input and output tensors
    x = pt.randn(3, 3)
    y = pt.randn(3, 3)

    if pt.cuda.is_available():
        # Move tensors to GPU
        x = x.cuda()
        y = y.cuda()

        # Perform matrix multiplication on GPU
        z = x @ y
        print("Matrix multiplication result on GPU:\n")
        print(z)

        # Move result back to CPU
        z = z.cpu()
    else:
        # Perform computation on CPU
        z = x @ y
        print("Matrix multiplication result on CPU:\n")
        print(z)

if __name__ == "__main__":
    main()

(obvs) ➜ obvs git:(main) ✗ python -m obvspython.gputest CUDA available:True CUDA device count:1 Matrix multiplication result on GPU:

tensor([[-3.0339, -1.0613, 2.1943], [ 1.4992, -0.0329, -1.5515], [ 0.8386, -0.8523, 0.2062]], device='cuda:0')

System information

- What OS did you do install Mojo on ?
Ubuntu 22.04

- Provide version information for Mojo by pasting the output of `mojo -v`
mojo 0.7.0 (af002202)

- Provide Modular CLI version by pasting the output of `modular -v`
modular 0.4.1 (2d8afe15)

jcoombes avatar Feb 03 '24 19:02 jcoombes

from python import Python

fn main() raises:
    let pt = Python.import_module("torch")

    # Print CUDA details
    print("CUDA available:" + pt.cuda.is_available())
    print("CUDA device count:" + pt.cuda.device_count())

    # Create random input and output tensors
    var x = pt.randn(3, 3)
    var y = pt.randn(3, 3)

    if pt.cuda.is_available():
        # Move tensors to GPU
        x = x.cuda()
        y = y.cuda()

        # Perform matrix multiplication on GPU
        var z = pt.matmul(x, y)
        print("Matrix multiplication result on GPU:\n")
        print(z)

        # Move result back to CPU
        z = z.cpu()
    else:
        # Perform computation on CPU
        let z = pt.matmul(x, y)
        print("Matrix multiplication result on CPU:\n")
        print(z)

This should fix your problem, and btw remember that when u declare a variable with let, it'll immutable, means u cant change it

 let x = pt.randn(3, 3)
    let y = pt.randn(3, 3)

    if pt.cuda.is_available():
        # Move tensors to GPU
        x = x.cuda()
        y = y.cuda()

Like this part right here.

trongnamdz1 avatar Feb 04 '24 02:02 trongnamdz1

Here's the new code...

from python import Python


fn main() raises:
    let pt = Python.import_module("torch")

    # Print CUDA details
    print("CUDA available:" + pt.cuda.is_available())
    print("CUDA device count:" + pt.cuda.device_count())

    # Create random input and output tensors
    var x = pt.randn(3, 3)
    var y = pt.randn(3, 3)

    if pt.cuda.is_available():
        # Move tensors to GPU
        x = x.cuda()
        y = y.cuda()

        # Perform matrix multiplication on GPU
        var z = pt.matmul(x, y)
        print("Matrix multiplication result on GPU:\n")
        print(z)

        # Move result back to CPU
        z = z.cpu()
    else:
        # Perform computation on CPU
        var z = pt.matmul(x, y)
        print("Matrix multiplication result on CPU:\n")
        print(z)

...and here's the new result.

(obvs) ➜  obvs git:(gputest) ✗ mojo obvs/gputest.🔥 
[3491:3491:20240204,142857.179610:ERROR file_io_posix.cc:144] open /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq: No such file or directory (2)
[3491:3491:20240204,142857.179908:ERROR file_io_posix.cc:144] open /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq: No such file or directory (2)
[3491:3492:20240204,142857.180769:ERROR directory_reader_posix.cc:42] opendir /home/user/.modular/crashdb/attachments/7dcd4a38-54b0-4b89-810e-5bc12b36905d: No such file or directory (2)
Please submit a bug report to https://github.com/modularml/mojo/issues and include the crash backtrace along with all the relevant source codes.
Stack dump:
0.      Program arguments: mojo obvs/gputest.\360\237\224\245
#0 0x0000563aafcef1b7 (/home/user/.modular/pkg/packages.modular.com_mojo/bin/mojo+0x6211b7)
#1 0x0000563aafcecd8e (/home/user/.modular/pkg/packages.modular.com_mojo/bin/mojo+0x61ed8e)
#2 0x0000563aafcef88f (/home/user/.modular/pkg/packages.modular.com_mojo/bin/mojo+0x62188f)
#3 0x00007f13fe042520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
[1]    3489 segmentation fault (core dumped)  mojo obvs/gputest.🔥

jcoombes avatar Feb 04 '24 14:02 jcoombes