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

[Mojo] Initial version #514

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ RUN wget https://github.com/ldc-developers/ldc/releases/download/v1.36.0/ldc2-1.
RUN rm -rf /usr/local/ldc2* && tar -C /usr/local -xvf ldc2-1.36.0-linux-x86_64.tar.xz
ENV PATH="$PATH:/usr/local/ldc2-1.36.0-linux-x86_64/bin"

# install mojo
# probably Modular Auth token should be saved in .env
python <(curl -sSL https://raw.githubusercontent.com/Sharktheone/arch-mojo/main/src/install.py)

# install neat
RUN wget https://github.com/Neat-Lang/neat/releases/download/v0.5.2/neat-v0.5.2-llvm.tar.xz
RUN tar -C /home/builduser -xvf neat-v0.5.2-llvm.tar.xz && rm neat-v0.5.2-llvm.tar.xz
Expand Down
186 changes: 186 additions & 0 deletions mojo/related.mojo
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
from collections import Dict, List
from collections.vector import InlinedFixedVector
from time import now
from python import Python

struct Post(CollectionElement):
var _id: String
var title: String
var tags: List[String]

fn __init__(inout self, _id: String, title: String, tags: List[String]):
self._id = _id
self.title = title
self.tags = tags

fn __copyinit__(inout self, existing: Self):
self._id = existing._id
self.title = existing.title
self.tags = existing.tags

fn __moveinit__(inout self, owned existing: Self):
self._id = existing._id^
self.title = existing.title^
self.tags = existing.tags^

struct RelatedPosts(CollectionElement):
var _id: String
var tags: List[String]
var related: List[Post]

fn __init__(inout self, _id: String, tags: List[String], related: List[Post]):
self._id = _id
self.tags = tags
self.related = related

fn __copyinit__(inout self, existing: Self):
self._id = existing._id
self.tags = existing.tags
self.related = existing.related

fn __moveinit__(inout self, owned existing: Self):
self._id = existing._id^
self.tags = existing.tags^
self.related = existing.related^

struct PostsWithSharedTags(CollectionElement):
var post: Int
var sharedTags: Int

fn __init__(inout self, post: Int = 0, sharedTags: Int = 0):
self.post = post
self.sharedTags = sharedTags

fn __copyinit__(inout self, existing: Self):
self.post= existing.post
self.sharedTags = existing.sharedTags

fn __moveinit__(inout self, owned existing: Self):
self.post = existing.post
self.sharedTags = existing.sharedTags

fn deser_tags(tags: List[String]) raises -> String:
var res = String("[")
for i in range(len(tags)):
res += '"' + tags[i] + '"'
if (i != len(tags) - 1):
res += ','
res += "]"
return res

fn deser_post(post: Post) raises -> String:
var res = String("{")
res += '"_id":"' + post._id + '","title":"' + post.title + '","tags":' + deser_tags(post.tags)
res += "}"
return res

fn deser_list_posts(posts: List[Post]) raises -> String:
var res = String("[")
for i in range(len(posts)):
res += deser_post(posts[i])
if (i != len(posts) - 1):
res += ','
res += "]"
return res

fn deser_relpost(relpost: RelatedPosts) raises -> String:
var res = String("{")
res += '"_id":"'+ relpost._id + '",'
res += '"tags":' + deser_tags(relpost.tags) + ','
res += '"related":' + deser_list_posts(relpost.related) + '}'
return res

fn deser_list_relpost(relposts: List[RelatedPosts]) raises -> String:
var res = String("[")
for i in range(len(relposts)):
var x = relposts[i]
res += deser_relpost(x)
if (i != len(relposts) - 1):
res += ","
res += "]"
return res

fn write_json(posts: List[RelatedPosts]) raises:
var js = Python.import_module("json")
with open("../related_posts_mojo.json", "wb") as f:
var res = deser_list_relpost(posts)
f.write(res)

fn read_json() raises -> List[Post]:
var js = Python.import_module("json")
with open("../posts.json", "rb") as f:
var s = f.read()
var posts = js.loads(s)
var result = List[Post]()
for post in posts:
var t = List[String]()
for ta in post["tags"]:
t.append(String(ta))
result.append(Post(String(post["_id"]), String(post["title"]), t))
return result

fn process_posts(posts: List[Post]) raises -> List[RelatedPosts]:
var posts_count = len(posts)
var related_posts = List[RelatedPosts]()
var tagged_post_count = InlinedFixedVector[Int](posts_count)
var top_posts = List[Post]()
var tag_map = Dict[String, List[Int]]()

for i in range(posts_count):
var x = posts[i].tags
for tag in x:
var xt = tag[]
if xt in tag_map:
tag_map[xt].append(i)
else:
tag_map[xt] = List[Int](i)

for k in range(posts_count):
for z in range(posts_count):
tagged_post_count[z] = 0

var top5 = List[PostsWithSharedTags]()
top5.reserve(5)

var y = posts[k].tags
for tag in y:
var local_list = tag_map[tag[]]
for other_idx in local_list:
var deref_idx = other_idx[]
tagged_post_count[deref_idx] += 1

tagged_post_count[k] = 0

var min_tags = 0
for j in range(posts_count):
var count = tagged_post_count[j]
if (count > min_tags):
var upper_bound = 5 - 2
while ((upper_bound >= 0) and (count > top5[upper_bound].sharedTags)):
top5[upper_bound + 1] = top5[upper_bound]
upper_bound -= 1

top5[upper_bound + 1] = PostsWithSharedTags(j, count)
min_tags = top5[5 - 1].sharedTags

top_posts.clear()
for i in range(5):
top_posts.append(posts[top5[i].post])

related_posts.append(RelatedPosts(
posts[k]._id,
posts[k].tags,
top_posts
))

return related_posts

fn main():
try:
var posts = read_json()
var start = now()
var result = process_posts(posts)
print("Processing time (w/o IO): ", (now() - start)/1e6, "ms", sep = "")
write_json(result)
except:
print("exception")
17 changes: 15 additions & 2 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,13 @@ run_haskell() {
check_output "related_posts_haskell.json"
}

run_mojo() {
echo "Running Mojo" &&
cd ./mojo &&
run_command "Mojo" $slow_lang_runs mojo ./related.mojo &&
check_output "related_posts_mojo.json"
}

run_d() {
echo "Running D" &&
cd ./d &&
Expand Down Expand Up @@ -865,6 +872,10 @@ elif [ "$first_arg" = "haskell" ]; then

run_haskell

elif [ "$first_arg" = "mojo" ]; then

run_mojo

elif [ "$first_arg" = "d" ]; then

run_d
Expand Down Expand Up @@ -949,7 +960,7 @@ elif [ "$first_arg" = "all" ]; then
run_pypy || echo -e "\n" &&
run_python_np || echo -e "\n" &&
numba_con || echo -e "\n" &&

run_mojo || echo -e "\n" &&
# run_python_numba || echo -e "\n" && break rules but very interesting
run_crystal || echo -e "\n" &&
run_zig || echo -e "\n" &&
Expand Down Expand Up @@ -1016,6 +1027,8 @@ elif [ "$first_arg" = "clean" ]; then
cd .. &&
cd d_con_v2 && rm -f related_concurrent &&
cd .. &&
cd mojo && rm -f related &&
cd .. &&
cd erlang && rm -rf _build/ rebar.lock &&
cd .. &&
cd python && rm -rf venv/ &&
Expand All @@ -1032,6 +1045,6 @@ elif [ "$first_arg" = "clean" ]; then

else

echo "Valid args: go | go_con | rust | rust_con | d | d_con | r | py | numpy | erlang | cl | numba | numba_con | cr | zig | odin | jq | julia | julia_highly_optimized | julia_con | v | dart | swift | swift_con | node | bun | deno | java | java_graal | java_graal_con | nim | luajit | lua | fsharp | fsharp_aot | fsharp_con | csharp | csharp_aot | dascript | all | clean. Unknown argument: $first_arg"
echo "Valid args: go | go_con | rust | rust_con | d | d_con | r | py | mojo | numpy | erlang | cl | numba | numba_con | cr | zig | odin | jq | julia | julia_highly_optimized | julia_con | v | dart | swift | swift_con | node | bun | deno | java | java_graal | java_graal_con | nim | luajit | lua | fsharp | fsharp_aot | fsharp_con | csharp | csharp_aot | dascript | all | clean. Unknown argument: $first_arg"

fi