Martin Dudek
Martin Dudek
MModular
Created by Martin Dudek on 10/18/2024 in #community-showcase
Mojo added to SpeedTests repo on github
No description
16 replies
MModular
Created by Martin Dudek on 10/18/2024 in #questions
List of references in Mojo
I'm a bit out of the loop with the latest Mojo developments, so I could use some guidance. In Python, creating a list of references is simple:
m1 = [1, 2]
m2 = [3, 4]
l = [m1, m2]
l[0][0] = 5
print(m1[0]) # -> 5
m1 = [1, 2]
m2 = [3, 4]
l = [m1, m2]
l[0][0] = 5
print(m1[0]) # -> 5
How would we achieve similar functionality in Mojo nowadays? Is UnsafePointer still the way to go, something like:
from memory import UnsafePointer
fn main():
var m1 = UnsafePointer[Int].alloc(2)
var m2 = UnsafePointer[Int].alloc(2)

m1[0] = 1
m1[1] = 2
m2[0] = 3
m2[1] = 4

var l = List[UnsafePointer[Int]](capacity=2)
l.append(m1)
l.append(m2)

l[0][0] = 5
print(m1[0]) # -> 5
from memory import UnsafePointer
fn main():
var m1 = UnsafePointer[Int].alloc(2)
var m2 = UnsafePointer[Int].alloc(2)

m1[0] = 1
m1[1] = 2
m2[0] = 3
m2[1] = 4

var l = List[UnsafePointer[Int]](capacity=2)
l.append(m1)
l.append(m2)

l[0][0] = 5
print(m1[0]) # -> 5
Or is there now a more elegant/safer way to achieve this using References? Thx 🙏
8 replies
MModular
Created by Martin Dudek on 10/16/2024 in #questions
How to publish on github in these magic times
I'm wondering if there's a recommended way to publish Mojo/Max projects on GitHub , now that we have Magic as the recommended installation tool. Among other questions: * In mojoproject.toml, how should we set platforms = ["osx-arm64", "linux-64"]? * Should we recommend users to use magic shell or magic run? * ... To cut it short, I think it would be fantastic if Modular could publish a template github project for us to follow, including a concise instruction what magic is about and how to use it, suitable for Mojo newcomer on github. Having a standard approach to introduce Magic on GitHub and standard setup would in my opinion be a huge help in making Mojo popular. Right now its a bit wild west on github and must feel confusing for many ... Thx 🙏
2 replies
MModular
Created by Martin Dudek on 10/11/2024 in #community-showcase
Mojo dictionary benchmarks
No description
69 replies
MModular
Created by Martin Dudek on 9/19/2024 in #questions
parallelize and @parameter issue in Mojo 24.5
I am trying to convert my projects to Mojo 24.5. Right now I face the following issue. When running
from algorithm import parallelize

fn main():
var t = 5
@parameter
fn whatever(ip:Int):
print(t)
parallelize[whatever](1)
from algorithm import parallelize

fn main():
var t = 5
@parameter
fn whatever(ip:Int):
print(t)
parallelize[whatever](1)
I get 4507533440 printed as result. In the @parameter doc https://docs.modular.com/mojo/manual/decorators/parameter it says This is an unsafe feature because we currently do not model the lifetimes of capture-by-reference. but up to 24.4 i never had this issue. Did i miss some fundamental change here? Any advice how to handle this would be great. Thx 🙏 ps adding
'_ = t'
'_ = t'
at the end of this demo would solve the issue but that gets complicated and ugly in my projects ...
6 replies
MModular
Created by Martin Dudek on 9/16/2024 in #questions
to_numpy with Mojo 24.5
I try to convert the to_numpy method from the Mojo 24.4 based KMeans tutorial https://www.modular.com/blog/fast-k-means-clustering-in-mojo-guide-to-porting-python-to-mojo-for-accelerated-k-means-clustering to Mojo 24.5 but get the following error:
error: 'pop.index_to_pointer' op MLIR verification error: unregistered operation 'pop.index_to_pointer' found in dialect ('pop') that does not allow unknown operations
error: 'pop.index_to_pointer' op MLIR verification error: unregistered operation 'pop.index_to_pointer' found in dialect ('pop') that does not allow unknown operations
The orginal method is implemented as follows:
fn to_numpy(self) raises -> PythonObject:
var np = Python.import_module("numpy")
var np_arr = np.zeros((self.rows,self.cols))
var npArrayPtr = DTypePointer[dtype](
__mlir_op.`pop.index_to_pointer`[
_type = __mlir_type[`!kgen.pointer<scalar<`, dtype.value, `>>`]
](
SIMD[DType.index,1](np_arr.__array_interface__['data'][0].__index__()).value
)
)
memcpy(npArrayPtr, self._matPtr, len(self))
return np_arr ^
fn to_numpy(self) raises -> PythonObject:
var np = Python.import_module("numpy")
var np_arr = np.zeros((self.rows,self.cols))
var npArrayPtr = DTypePointer[dtype](
__mlir_op.`pop.index_to_pointer`[
_type = __mlir_type[`!kgen.pointer<scalar<`, dtype.value, `>>`]
](
SIMD[DType.index,1](np_arr.__array_interface__['data'][0].__index__()).value
)
)
memcpy(npArrayPtr, self._matPtr, len(self))
return np_arr ^
I replaced DTypePointer[dtype] with UnsafePointer[Scalar[dtype]] Any advice highly appreciated 😉
9 replies
MModular
Created by Martin Dudek on 6/17/2024 in #questions
Seeking Clarification on Current and Future Tensor Library Support in Mojo
I wonder if someone can clarify the current state and future direction of a Tensor library for Mojo. I understand that Tensor won't stay in the standard library and i think to understand the rationale behind it. We have also NuMojo, which looks very promising. It is currently based on Tensor but aims to have "Native array types" as a long-term goal. Not clear about the situation, I implemented my own vectorized yet simple Vector and Matrix structs for my KAN experiments. They work, my KAN implementaton outperforms the Python implementation i ported to Mojo (which is numpy based). However, I just found out these are extremely slow compared to torch.matmul, etc. I would greatly appreciate it if someone could clarify what is possible right now for Tensor-based applications and where Mojo is headed in that regard (let's say within this year). To be clear, I'm not demanding anything of course — just looking for some clarification on what is possible right now and where we are going as community. Also feedback how others handle the current situation would be great. Thx 🙏
26 replies
MModular
Created by Martin Dudek on 6/13/2024 in #community-showcase
KANs in Mojo - second attempt
This week I finally found time to dive into Kolmogorov–Arnold Networks again and give a Mojo implementation another shot. https://github.com/dorjeduck/kamo I decided to scrap my original source code and port A from-scratch implementation of Kolmogorov-Arnold Networks (KAN)…and MLP to Mojo. Turns out, this base made it much easier for me to grasp the topic, especially after all the confusion around the many derivatives involved in KANs. 😉 Right now, the implementation is just a learning project for me, and it doesn't have any particular wider benefits for the community I am afraid. I might improve on it to make it more competitive within the ever-growing ocean of KAN implementations, but it's not a top priority for me at the moment ...
3 replies
MModular
Created by Martin Dudek on 6/11/2024 in #questions
How to understand Mojo's compiler optimization capabilities?
This is something that’s been bugging me for a while. I am afraid there’s no clear answer, but I’m curious how you guys handle it. How can I figure out what optimizations the compiler is doing anyway instead of implementing them myself (vectorize etc) ? Implementing them myself is often easy with Mojo, but still it’s prone to errors, makes the code harder to read, and things like choosing simd_width in the code might be less optimal than letting the compiler decide based on the machine the code is running on.
To clarify what i mean with the last point, it seems that on Apple Sillicon
alias simd_width = 4 * simdwidthof[dtype]()
alias simd_width = 4 * simdwidthof[dtype]()
is the best choice but on other machines maybe
alias simd_width = 2 * simdwidthof[dtype]()
alias simd_width = 2 * simdwidthof[dtype]()
Who knows? I hope the compiler does depending on the machine it is compiling for. It feels a bit insane to actually hardcode this factor. 😉 Thanks
8 replies
MModular
Created by Martin Dudek on 6/7/2024 in #questions
Best way to make a struct of CollectionElements to conform to CollectionElement.
I am still confused about best practices for __moveinit__ and __copyinit__. Let's say i have a struct with two variables, which are both structs which conform to the CollectionElement trait, how to define __moveinit__ and __copyinit__ for this struct. Will this do?
struct A:
var b:B # B conforms to CollectionElement
var c:C # C conforms to CollectionElement
fn __init__(...

fn __copyinit__(inout self, existing: Self):
# ????
self.b = existing.b
self.c = existing.c

fn __moveinit__(inout self, owned existing: Self):
# ???
self.b = existing.b
self.c = existing.c
struct A:
var b:B # B conforms to CollectionElement
var c:C # C conforms to CollectionElement
fn __init__(...

fn __copyinit__(inout self, existing: Self):
# ????
self.b = existing.b
self.c = existing.c

fn __moveinit__(inout self, owned existing: Self):
# ???
self.b = existing.b
self.c = existing.c
Any advice highly appreciated
6 replies
MModular
Created by Martin Dudek on 5/31/2024 in #questions
Seeking Advice on Porting Python Classes to Mojo Structs
I still struggle with how to port Python classes to Mojo structs in the current state of Mojo and seek some help. Here I post a Python class and suggest four ways to port it to Mojo that I came up with. All of them work in this simple example but seem to have some major drawbacks when the class is more complex. It would be great to get feedback on how you handle this. Here an example Python class to port to Mojo
class Animal:
def __init__(self, name):
self.name = name
def whoareyou(self):
return f"I am {self.name}!"
def speak(self):
raise NotImplementedError("Subclass must implement abstract method")

class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"

class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"

dog = Dog("Buddy")
cat = Cat("Whiskers")

print(dog.whoareyou()) # Output: I am Buddy!
print(cat.whoareyou()) # Output: I am Whiskers!
print(dog.speak()) # Output: Buddy says Woof!
print(cat.speak()) # Output: Whiskers says Meow!
class Animal:
def __init__(self, name):
self.name = name
def whoareyou(self):
return f"I am {self.name}!"
def speak(self):
raise NotImplementedError("Subclass must implement abstract method")

class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"

class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"

dog = Dog("Buddy")
cat = Cat("Whiskers")

print(dog.whoareyou()) # Output: I am Buddy!
print(cat.whoareyou()) # Output: I am Whiskers!
print(dog.speak()) # Output: Buddy says Woof!
print(cat.speak()) # Output: Whiskers says Meow!
11 replies
MModular
Created by Martin Dudek on 5/27/2024 in #community-showcase
Basic Progress Bar for Mojo
Based on a discussion we had here on Discord, I implemented a basic progress bar in Mojo and put it on Github https://github.com/dorjeduck/mopro Just when i published it, @Ryulord pointed out another progress bar implementation to me, which he is about to introduce here. His implementation looks for sure more advanced, so look out for it (i leave it to him to post the link here .when he is ready) Nevertheless, I wiill keep my implementation on github for the time being, may it benefit.
8 replies
MModular
Created by Martin Dudek on 5/27/2024 in #questions
tqdm progress bar for Mojo?
I cant get tqdm to work via Python interface , so i am wondering if any of you managed to use it in Mojo or if we have something similar already implemented in Mojo. Thx.
18 replies
MModular
Created by Martin Dudek on 5/26/2024 in #questions
Why are you using Mojo?
Just curious: why are you using Mojo? i will start with the obvious, lets see where this goes 😉
23 replies
MModular
Created by Martin Dudek on 5/23/2024 in #questions
Roadmap for classes, dynamic polymorphism ...
I noticed that object-oriented programming features like classes and dynamic polymorphins weren't addressed in the last community meeting. Given that Mojo development is tightly coupled with the Max Engine and its assumingly different requirements, I'm wondering if there is a long-term roadmap available for these features. To put it brief, will Mojo have classes in 2024? 😉 Thx
8 replies
MModular
Created by Martin Dudek on 5/18/2024 in #questions
How to implement Dependency Injection in Mojo?
The following doesnt work (yet) in Mojo it seems
trait Printer:
fn print_it(self,text:String):
...
@value
struct BoringPrinter(Printer):
fn print_it(self,text:String):
print(text)

fn lets_print(p:Printer,text:String):
p.print_it(text)

fn main():
var bp = BoringPrinter()
lets_print(bp,"let's sing a song")
trait Printer:
fn print_it(self,text:String):
...
@value
struct BoringPrinter(Printer):
fn print_it(self,text:String):
print(text)

fn lets_print(p:Printer,text:String):
p.print_it(text)

fn main():
var bp = BoringPrinter()
lets_print(bp,"let's sing a song")
i get the following error:
error: invalid call to 'lets_print': argument #0 cannot be converted from 'BoringPrinter' to 'Printer'
error: invalid call to 'lets_print': argument #0 cannot be converted from 'BoringPrinter' to 'Printer'
Is there a way to implement in Mojo what i am trying to do here. As we don't have inheritence yet i want to use Dependency Injection but without this i feel loooooost. Any advice on this highly appreciated. Not knowing how to implement this discourages me to think of more interesting framework like Mojo projects unfortunately.
10 replies
MModular
Created by Martin Dudek on 5/16/2024 in #questions
Python integration and performance
I am looking into the performance of the Python Integration in Mojo. I use Dict here as example but that is just random, my question is not about a `Dict but in general The following python program measures
time: 0.585089921951294 sec
time: 0.585089921951294 sec
on my computer to fill and modify a dictionary. as follows
import time
NUM = 1_000_000
start = time.time()
dic = {}
for i in range(NUM):
dic[str(i*2)] = i%3
for i in range(NUM):
dic[str(i*2)] *= 2
elapsed = (time.time()-start)
print("time:",elapsed,"sec")
import time
NUM = 1_000_000
start = time.time()
dic = {}
for i in range(NUM):
dic[str(i*2)] = i%3
for i in range(NUM):
dic[str(i*2)] *= 2
elapsed = (time.time()-start)
print("time:",elapsed,"sec")
When I include the dict into Mojo the performance drops significantly
time: 15.87300 sec
time: 15.87300 sec
from python import Python
from time import now
alias NUM = 1_000_000
fn main() raises:
var start = now()
var dict = Python.dict()
for i in range(NUM):
dict[str(i*2)] = i%3
for i in range(NUM):
dict[str(i*2)] *=2
var elapsed = (now()-start)/1_000_000_000
print("time:",elapsed,"sec")
_ = dict["112"]
from python import Python
from time import now
alias NUM = 1_000_000
fn main() raises:
var start = now()
var dict = Python.dict()
for i in range(NUM):
dict[str(i*2)] = i%3
for i in range(NUM):
dict[str(i*2)] *=2
var elapsed = (now()-start)/1_000_000_000
print("time:",elapsed,"sec")
_ = dict["112"]
Now when i shift the first loop into a python program
def get_dict(num):
dict = {}
for i in range(num):
dict[str(i*2)] = i%3
return dict
def get_dict(num):
dict = {}
for i in range(num):
dict[str(i*2)] = i%3
return dict
` and use this in Mojo as follows:
from python import Python
from time import now
alias NUM = 1_000_000
fn main() raises:
start = now()
Python.add_to_path("./utils")
var utils: PythonObject = Python.import_module("utils")
var dict = utils.get_dict(NUM)
for i in range(NUM):
dict[str(i*2)] *= 2
var elapsed = (now()-start)/1_000_000_000
print("time:",elapsed,"sec")
_ = dict["112"]
from python import Python
from time import now
alias NUM = 1_000_000
fn main() raises:
start = now()
Python.add_to_path("./utils")
var utils: PythonObject = Python.import_module("utils")
var dict = utils.get_dict(NUM)
for i in range(NUM):
dict[str(i*2)] *= 2
var elapsed = (now()-start)/1_000_000_000
print("time:",elapsed,"sec")
_ = dict["112"]
i get
time: 11.133032 sec
time: 11.133032 sec
which is 1,5 times faster. What I am mainly wondering about now are the last 2 examples. If performance is crucial, is it in certain cases when we need to rely on Python Integration advisable to perform some calculations directly in Python instead of just importing the Python object to Mojo, It feels odd but here it brings speedup. Thanks for any thoughts on that.
10 replies
MModular
Created by Martin Dudek on 5/14/2024 in #questions
Regular Expression Engine for Mojo, any plans?
Do we have a regular expression engine implemented in Mojo?I haven't come across one yet, but it would be fantastic to have. Or is there a native solution planned for Mojo? If not, what could be our approach to developing one? I have no clue about the complexity involved in this task. Would we base it on some existing C engine or write it from scratch in Mojo. Thx
87 replies
MModular
Created by Martin Dudek on 5/13/2024 in #community-showcase
Mojo port of Andrjey Karpathy's minbpe
https://github.com/dorjeduck/minbpe.mojo Minbpe is an implementation of various Tokenizers as they are commonly used in LLM application. This Mojo port is work in progress, particular looking into performance optimizations. One interesting aspect of this project for me is that there is a Rust port of minbpe and in some aspects of Tokenization this Mojo port is not yet a performant as the Rust implemention (which seems to be done very well). Not so much a competition with Rust for me, but extremely helpful to have this performance comparison to find aspect of my implemention which can be optimized ... Any feedback most welcome
2 replies
MModular
Created by Martin Dudek on 5/11/2024 in #community-showcase
MoString - fast String concatenation for Mojo
https://github.com/dorjeduck/mostring MoString is a simple yet fast String concatenation struct in Mojo. The idea behind the repo is also a bit of a community experiment, wondering if people are interested in contribtung their own implementation of this task to the repo so we can explore options which might flow into the Mojo Standard at one point. Very happy to accept PRs for that.
2 replies