Open Forum > What's New

ScriptBasic JIT

(1/2) > >>

Support:
Charles Pegge (OxygenBasic / DLLC author) has done it again and added JIT (Just-In-Time) function scripting, compiling and calling all at runtime. The following example is interesting as it shows DLLC supporting the JAPI  (Java Application Programming Interface) and using JIT for the Mandelbrot Set calculation. (76,800 pixel calculations)




The following code is using DLLC to interface with the JAPI DLL to produce the Mandelbrot Set.


--- Code: ---' JAPI 2.0 DLLC

include "dllcinc.sb"

japi = dllfile("japi.dll")

j_start = dllproc(japi, "j_start i = ()")
j_frame = dllproc(japi, "j_frame i = (c * label)")
j_menubar = dllproc(japi, "j_menubar i = ( i obj)")
j_menu = dllproc(japi, "j_menu i = (i obj, c *label)")
j_menuitem = dllproc(japi, "j_menuitem i = (i obj, c *label)")
j_canvas = dllproc(japi, "j_canvas i = (i obj, i width , i height)")
j_setpos = dllproc(japi, "j_setpos (i obj, i xpos, i ypos)")
j_pack = dllproc(japi, "j_pack (i obj)")
j_show = dllproc(japi, "j_show (i obj)")
j_getaction = dllproc(japi, "j_getaction i = ()")
j_nextaction = dllproc(japi, "j_nextaction i = ()")
j_setcolor = dllproc(japi, "j_setcolor (i obj, i r, i g, i b)")
j_drawpixel = dllproc(japi, "j_drawpixel (i obj, i x, i y)")
j_quit = dllproc(japi, "j_quit ()")

CONST J_TRUE = 1
CONST J_FALSE = 0


xstart = -1.8
xend   =  0.8
ystart = -1.0
yend   =  1.0

hoehe  = 240
breite = 320

if (dllcall(j_start) = J_FALSE) then
  print("JAPI interface failed to start.\n")
  end
endif

jframe  = dllcall(j_frame,"JAPI 2.0 DLLC")
menubar = dllcall(j_menubar,jframe)
jfile   = dllcall(j_menu,menubar,"File")
calc    = dllcall(j_menu,menubar,"Calc")
quit    = dllcall(j_menuitem,jfile,"Quit")
start   = dllcall(j_menuitem,calc,"Start")
jstop   = dllcall(j_menuitem,calc,"Stop")

canvas  = dllcall(j_canvas,jframe,breite,hoehe)
dllcall(j_setpos,canvas,10,60)
dllcall(j_pack,jframe)
dllcall(j_show,jframe)

obj = 0
do_work = 0

while((obj <> jframe) and (obj <> quit))

    if(do_work = 1) then
        obj = dllcall(j_getaction)
    else
        obj = dllcall(j_nextaction)
    endif      

    if(obj = start) then
        x = -1
        y = -1
        do_work = 1
        st = dllsecs()
    endif

    if(obj = jstop) then
        do_work = 0
    endif
    
    if(do_work = 1) then
        x = (x+1) % breite
       if(x = 0) then
            y = (y+1) % hoehe
       endif
       if((x = breite-1) and (y = hoehe-1)) then
            do_work = 0
            PRINT format("%g",dllsecs() - st),"\n"
        else
            zre = xstart + x*(xend-xstart)/breite
            zim = ystart + y*(yend-ystart)/hoehe
            it = mandel(zre,zim,512)
            dllcall(j_setcolor,canvas,it*11,it*13,it*17)
            dllcall(j_drawpixel,canvas,x,y)
        endif
    endif

wend

dllcall(j_quit)


function mandel(zre,zim,maxiter)
    mx = 0.0
    my = 0.0
    iter=0
    betrag=0.0
 
    while ((iter < maxiter) and (betrag < 4.0))
        iter = iter+1
        tmp = mx*mx-my*my+zre
        my = 2*mx*my+zim
        mx = tmp
        betrag = (mx*mx + my*my)
    wend
    mandel=iter
end function

--- End code ---

This version uses the new JIT compiling feature of DLLC with the mandel() function compiled at runtime.


--- Code: ---' JAPI 2.0 DLLC JIT

include "dllcinc.sb"

oxy = dllfile("/sb22/modules/oxygen.dll")

o2_basic = dllproc( oxy, "o2_basic i =(c*source) " )
o2_exec  = dllproc( oxy, "o2_exec  i =(i call)   " )
o2_error = dllproc( oxy, "o2_error c*=()         " )
o2_errno = dllproc( oxy, "o2_errno i =()         " )
o2_len   = dllproc( oxy, "o2_len   i =()         " )
o2_mode  = dllproc( oxy, "o2_mode     (i mode)   " )

dllcall(o2_mode,1)

src = """
extern
function mandel(float zre,zim,sys maxiter) as sys
    float mx,my,betrag
    sys iter
 
    while iter < maxiter and betrag < 4.0
        iter = iter+1
        tmp = mx*mx-my*my+zre
        my = 2*mx*my+zim
        mx = tmp
        betrag = (mx*mx + my*my)
    wend
    return iter
end function

sub finish()
  terminate
end sub

function link(sys n) as sys
  select n
    case 0
      return @finish
    case 1
      return @mandel
  end select
end function

end extern

addr link
"""

dllcall(o2_basic, src)
dfn = dllcall(o2_exec,0)
mandel = dllproc(dfn,"mandel i = (f zre, f zim, i maxiter)", dllcald(dfn, 1))
finish = dllproc(dfn,"finish ()", dllcald(dfn, 0))

japi = dllfile("japi.dll")

j_start = dllproc(japi, "j_start i = ()")
j_frame = dllproc(japi, "j_frame i = (c * label)")
j_menubar = dllproc(japi, "j_menubar i = ( i obj)")
j_menu = dllproc(japi, "j_menu i = (i obj, c *label)")
j_menuitem = dllproc(japi, "j_menuitem i = (i obj, c *label)")
j_canvas = dllproc(japi, "j_canvas i = (i obj, i width , i height)")
j_setpos = dllproc(japi, "j_setpos (i obj, i xpos, i ypos)")
j_pack = dllproc(japi, "j_pack (i obj)")
j_show = dllproc(japi, "j_show (i obj)")
j_getaction = dllproc(japi, "j_getaction i = ()")
j_nextaction = dllproc(japi, "j_nextaction i = ()")
j_setcolor = dllproc(japi, "j_setcolor (i obj, i r, i g, i b)")
j_drawpixel = dllproc(japi, "j_drawpixel (i obj, i x, i y)")
j_quit = dllproc(japi, "j_quit ()")

CONST J_TRUE = 1
CONST J_FALSE = 0


xstart = -1.8
xend   =  0.8
ystart = -1.0
yend   =  1.0

hoehe  = 240
breite = 320

if (dllcall(j_start) = J_FALSE) then
  print("JAPI interface failed to start.\n")
  end
endif

jframe  = dllcall(j_frame,"JAPI 2.0 DLLC JIT")
menubar = dllcall(j_menubar,jframe)
jfile   = dllcall(j_menu,menubar,"File")
calc    = dllcall(j_menu,menubar,"Calc")
quit    = dllcall(j_menuitem,jfile,"Quit")
start   = dllcall(j_menuitem,calc,"Start")
jstop   = dllcall(j_menuitem,calc,"Stop")

canvas  = dllcall(j_canvas,jframe,breite,hoehe)
dllcall(j_setpos,canvas,10,60)
dllcall(j_pack,jframe)
dllcall(j_show,jframe)

obj = 0
do_work = 0

while((obj <> jframe) and (obj <> quit))
    if(do_work = 1) then
        obj = dllcall(j_getaction)
    else
        obj = dllcall(j_nextaction)
    endif      

    if(obj = start) then
        x = -1
        y = -1
        do_work = 1
        st = dllsecs()
    endif

    if(obj = jstop) then
        do_work = 0
    endif
    
    if(do_work = 1) then
        x = (x+1) % breite
       if(x = 0) then
            y = (y+1) % hoehe
       endif
       if((x = breite-1) and (y = hoehe-1)) then
            do_work = 0
            PRINT format("%g",dllsecs() - st),"\n"
        else
            zre = xstart + x*(xend-xstart)/breite
            zim = ystart + y*(yend-ystart)/hoehe
            it = dllcall(mandel,zre,zim,512)
            dllcall(j_setcolor,canvas,it*11,it*13,it*17)
            dllcall(j_drawpixel,canvas,x,y)
        endif
    endif
wend

dllcall(Finish)
dllcall(j_quit)
dllfile

--- End code ---

When the menu start option is clicked I record the time and print the results when the last pixel is displayed of the Mandelbrot Set.

ScriptBasic
C:\SB22\japi_dllc>scriba mandel_dllc.sb
56.9223

C:\SB22\japi_dllc>

ScriptBasic JIT

C:\SB22\japi_dllc>scriba mandel_dllc2.sb
17.608

C:\SB22\japi_dllc>

Support:
I converted the JAPI Mandelbrot Set to Simple Window to compare the speed of the two libraries.




--- Code: OxygenBasic ---' Simple Window DLLC JIT include "dllcinc.sb" oxy = dllfile("/sb22/modules/oxygen.dll") o2_basic = dllproc( oxy, "o2_basic i =(c*source) " )o2_exec  = dllproc( oxy, "o2_exec  i =(i call)   " )o2_error = dllproc( oxy, "o2_error c*=()         " )o2_errno = dllproc( oxy, "o2_errno i =()         " )o2_len   = dllproc( oxy, "o2_len   i =()         " )o2_mode  = dllproc( oxy, "o2_mode     (i mode)   " ) dllcall(o2_mode,1) src = """externfunction mandel(float zre,zim,sys maxiter) as sys    float mx,my,betrag    sys iter     while iter < maxiter and betrag < 4.0        iter = iter+1        tmp = mx*mx-my*my+zre        my = 2*mx*my+zim        mx = tmp        betrag = (mx*mx + my*my)    wend    return iterend function sub finish()  terminateend sub function link(sys n) as sys  select n    case 0      return @finish    case 1      return @mandel  end selectend function end extern addr link""" dllcall(o2_basic, src)dfn = dllcall(o2_exec,0)mandel = dllproc(dfn,"mandel i = (f zre, f zim, i maxiter)", dllcald(dfn, 1))finish = dllproc(dfn,"finish ()", dllcald(dfn, 0)) sw = dllfile("sw.dll") Window = dllproc(sw, "Window i = (i width, i height, i mode)")SetCaption = DLLC_Proc(sw, "SetCaption i = (c *capText)")SetPixel = dllproc(sw, "SetPixel i = (i xPos, i yPos, i color)")RGB = dllproc(sw, "RGB i = (i rValue, i gValue, i bValue)")Redraw = DLLC_Proc(sw, "Redraw ( )")WaitKey = dllproc(sw, "WaitKey i = ( )")Quit = DLLC_Proc(sw, "Quit i = ( )")  xstart = -1.8xend   =  0.8ystart = -1.0yend   =  1.0 hoehe  = 240breite = 320 dllcall(Window,320,240,1)dllcall(SetCaption,"SB SW DLLC JIT") st = dllsecs() x = -1y = -1 REPEAT  x = (x+1) % breite  if(x = 0) then y = (y+1) % hoehe  zre = xstart + x*(xend-xstart)/breite  zim = ystart + y*(yend-ystart)/hoehe  it = dllcall(mandel,zre,zim,512)  dllcall(SetPixel,x, y, dllcall(RGB,it*11,it*13,it*17))  dllcall(Redraw)UNTIL ((x = breite-1) and (y = hoehe-1))PRINT format("%g",dllsecs() - st),"\n"dllcall(WaitKey) dllcall(Finish)dllcall(Quit)dllfile 
C:\SB22\japi_dllc>scriba swmandeldllc.sb
5.57576

C:\SB22\japi_dllc>

If I remove the Redraw() function and wait until the it's done to refresh the screen.

C:\SB22\japi_dllc>scriba swmandeldllc.sb
1.05691

C:\SB22\japi_dllc>

This is stock SB with no JIT assist.


--- Code: OxygenBasic ---' Simple Window DLLC include "dllcinc.sb" sw = dllfile("sw.dll") Window = dllproc(sw, "Window i = (i width, i height, i mode)")SetCaption = DLLC_Proc(sw, "SetCaption i = (c *capText)")SetPixel = dllproc(sw, "SetPixel i = (i xPos, i yPos, i color)")RGB = dllproc(sw, "RGB i = (i rValue, i gValue, i bValue)")Redraw = DLLC_Proc(sw, "Redraw ( )")WaitKey = dllproc(sw, "WaitKey i = ( )")Quit = DLLC_Proc(sw, "Quit i = ( )") function mandel(zre,zim,maxiter)    mx = 0.0    my = 0.0    iter=0    betrag=0.0     while ((iter < maxiter) and (betrag < 4.0))        iter = iter+1        tmp = mx*mx-my*my+zre        my = 2*mx*my+zim        mx = tmp        betrag = (mx*mx + my*my)    wend    mandel=iterend function xstart = -1.8xend   =  0.8ystart = -1.0yend   =  1.0 hoehe  = 240breite = 320 dllcall(Window,320,240,1)dllcall(SetCaption,"SB SW DLLC") st = dllsecs() x = -1y = -1 REPEAT  x = (x+1) % breite  if(x = 0) then y = (y+1) % hoehe  zre = xstart + x*(xend-xstart)/breite  zim = ystart + y*(yend-ystart)/hoehe  it = mandel(zre,zim,512)  dllcall(SetPixel,x, y, dllcall(RGB,it*11,it*13,it*17))UNTIL ((x = breite-1) and (y = hoehe-1))dllcall(Redraw)PRINT format("%g",dllsecs() - st),"\n"dllcall(WaitKey) dllcall(Quit)dllfile 
With Redraw() in the loop.

C:\SB22\japi_dllc>scriba swnojit.sb
45.0972

C:\SB22\japi_dllc>

Wait until the end to display the results.

C:\SB22\japi_dllc>scriba swnojit.sb
39.637

C:\SB22\japi_dllc>

kryton9:
John this is impressive looking. Is the aim to get programs compiled for android via java, or I guess for any java supported platform?

Support:

--- Quote ---Is the aim to get programs compiled for android via java, or I guess for any java supported platform?
--- End quote ---

The JAPI interface is a great idea but 10 years before it's time. It was abandoned before Java got into full swing. (pun intended) There were a couple other BASIC like developers that showed interest in updating the library from AWT based to SWING based. That effort fizzled out and I have no room on my plate to take on another project. (alone) The other negative aspect is that the Java interface is a socket connection (like GTK-Server) and quickly reaches it limitations with todays processor speed. For this API to be worth using, a more direct interface to Java (JNI) needs to be in place and the full swing API exposed.

My efforts with this as with everything else I do was to try and create some interest in JAPI and see if others felt there was value in a rebirth of the API. Seems not at this time.  :-\

Thanks for the comments and feedback. It gets boring being the only one posting to this open source project.

As a side note, I plan on focusing ScriptBasic toward it's roots of being an embedded scripting solution. I must have been nuts trying to promote ScriptBasic's use to the BASIC hobby programming community. ALLBASIC.INFO will become a what's up with BASIC info/news site without interaction. I no longer have the free time I once had to promote and facilitate BASIC open source projects.

kryton9:
You have done a great job from all your posts I see on various platforms promoting BASIC and ScriptBasic. I am amazed on how much you could keep straight to deal with so many areas and to offer so many nice websites.

I just wish we had the BASIC developers working together instead of all on their own. But I guess everyone has their own ideas on what is best and go forward with their dream.

Navigation

[0] Message Index

[#] Next page

Go to full version