Hi, I am new to nim but I plan to invest time to learn and use it for my
scientific computing work. Numpy in Python has an important place for computing
tasks and until we have an equivalent (or better) package in nim, we may need
to delegate some work to NumPy (or vice versa). Thus, I tried to pass a numpy
array to a nim proc and modify its data to practice.
A sample python code and nim code is given below:
Python code:
import numpy as np
import time
from copy import deepcopy
import nimpy_numpy as nn
a = np.random.rand(1000,1000)
b = deepcopy(a)
start_time = time.time()
b[b > 0.5] = 1
time_elapsed = time.time() - start_time
print(time_elapsed)
b = deepcopy(a)
start_time = time.time()
nn.clip_up(b, 0.5)
time_elapsed = time.time() - start_time
print(time_elapsed)
Run
Nim code:
import nimpy
import nimpy/raw_buffers
proc clip_up(o: PyObject, thres: float) {.exportpy.} =
var aBuf: RawPyBuffer
o.getBuffer(aBuf, PyBUF_WRITABLE or PyBUF_ND)
let num_of_items : int = int(aBuf.len / aBuf.itemsize)
for idx in 0..<num_of_items:
var x = cast[ptr cdouble](cast[uint](aBuf.buf) + cast[uint](idx *
aBuf.itemsize))
if x[] > thres:
x[] = 1
aBuf.release()
Run
nim compilation:
nim c --opt:speed --app:lib --out:nimpy_numpy.so nimpy_numpy
Run
processing time:
numpy: 0.7431097030639648
nim: 0.9256880283355713
I used nimpy and numpy example in tpyfromnim.nim in nimpy/tests based on python
buffer protocol.
Based on my attempt, I am interested in possible answers to the following
questions:
* Is there a way to make ptr casting generic in var x = cast[ptr
cdouble](cast[uint](aBuf.buf) + cast[uint](idx * aBuf.itemsize)) (a generic way
instead of cdouble)
* Is there a simpler way to access an element using indexes rather than ptr
casting?
* When compiled with --opt:speed flag, the speeds of numpy and nim are
comparable but nim implementation is still slow. What are possible bottleneck
points in the implementation?
* Can data access to numpy be performed in a simpler way?
Thanks, Zafer