SlideShare a Scribd company logo
Updating gopy to support Python3 and PyPy
Dong-hee Na, Chungnam National University, Daejeon, Korea
Mentors: Sebastien Binet, Alexandre Claude
13. June. 2017
Main topics
• What is gopy?
• Why Go ..?
• Performance benchmark
• Support CFFI backend
What is gopy?
• gopy is heavily inspired from gomobile.
• gopy is a set of packages and build tools for using Go from python
interpreters.
• Generates (and compiles) a Python extension module from a Go package.
( https://github.com/golang/mobile)
• LHC: 90% of C++ codes and a bit of Python codes for steering.
Why Go? – Software at CERN
0
100
200
300
400
500
600
700
Users in CERN
Know_The_User_Communities_Results_Summary.pdf
Why Go …?
Powerful performance
Pros
Long long compiling times
Cons
Manual memory Management
Pros
Cons
- Easy to install libraries
with ‘go get’.
- Rich standard libraries.
- Built-in concurrency
support
- Compile fast.
- Elegant and simple built-in
build system.
- Garbage-collected
language
- Error detecting is
awesome.
- Learning curve is low
- Powerful performance.Learning curve is high
Global Interpreter Lock
Interpreter based
Library installation is easy
Learning curve is low
Useful Scientific Packages
Compiled language
gopy: Calculation of Pi Using the Monte Carlo Method
func monte_carlo_pi(reps int, result *int, wait *sync.WaitGroup) {
var x, y float64
count := 0
seed := rand.NewSource(time.Now().UnixNano())
random := rand.New(seed)
for i := 0; i < reps; i++ {
x = random.Float64() * 1.0
y = random.Float64() * 1.0
if num := math.Sqrt(x*x + y*y); num < 1.0 {
count++
}
}
*result = count
wait.Done()
}
http://tstra.us/code/goPi/
func GetPI(samples int) float64 {
cores := runtime.NumCPU()
runtime.GOMAXPROCS(cores)
var wait sync.WaitGroup
counts := make([]int, cores)
wait.Add(cores)
for i := 0; i < cores; i++ {
go monte_carlo_pi(samples/cores, &counts[i], &wait)
}
wait.Wait()
total := 0
for i := 0; i < cores; i++ {
total += counts[i]
}
pi := (float64(total) / float64(samples)) * 4
return pi
}
gopy vs Python:
Calculation of Pi Using the Monte Carlo Method
• gopy is very easy to install.
• Using a go get is all you have to do!
$> go get -u -v github.com/go-python/gopy github.com/go-python/gopy
(download) github.com/gonuts/commander (download) github.com/gonuts/flag
(download) github.com/gonuts/flag github.com/go-python/gopy/bind
github.com/gonuts/commander github.com/go-python/gopy
gopy vs Python:
Calculation of Pi Using the Monte Carlo Method
def monte_carlo_pi_part(n):
count = 0
for i in range(int(n)):
x=random.random()
y=random.random()
# if it is within the unit circle
if x*x + y*y <= 1:
count=count+1
#return
return count
def GetPI(n):
np = multiprocessing.cpu_count()
part_count=[n/np for i in range(np)]
pool = Pool(processes=np)
count=pool.map(monte_carlo_pi_part, part_count)
return sum(count)/(n*1.0)*4
https://gist.github.com/amitsaha/2036026
if __name__ == '__main__':
n = 100000
py_start = time.time()
result = GetPI(n)
py_end = time.time()
print("Python result: %f time_elapsed: %f" % (result, py_end-py_start))
go_start = time.time()
result = calculatePi.GetPI(n)
go_end = time.time()
print("gopy result: %f time_elapsed: %f" %(result, go_end-go_start))
gopy vs Python:
Calculation of Pi Using the Monte Carlo Method
• gopy helps to use Go’s useful features on the Python interpreter.
• End-user can easily run Go codes on the Python interpreter.
root@180a6474ebba:~/test# gopy bind github.com/go-python/gopy/_examples/calculatePi
2017/06/11 06:03:21 work: /tmp/gopy-546154656
root@180a6474ebba:~/test# python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import calculatePi
>>> calculatePi.GetPI(10000)
3.1564
root@180a6474ebba:~/test# python pi_mp.py
n: 100000
Python result: 3.145880 time_elapsed: 0.030254
gopy result: 3.137400 time_elapsed: 0.002960 ß Much Faster!!!
gopy: Limitation
• gopy does not supports CPython3 nor PyPy.
• Many go’s implementations/features are not yet implemented in gopy
root@180a6474ebba:~/test# pypy pi_mp.py
Traceback (most recent call last):
File "pi_mp.py", line 12, in <module>
import calculatePi
ImportError: No module named calculatePi
root@180a6474ebba:~/test# python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import calculatePi
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define module export function (PyInit_calculatePi)
GSoC Project: Support Python3 and PyPy
• Need to support Py2/3 and PyPy.
• PyPy’s implementation is not strictly 100% compatible with Ctypes.
• CFFI is a good choice to support various python compilers.
• CFFI interacts with almost any C code from Python.
root@180a6474ebba:~/test# gopy bind --lang=cffi github.com/go-
python/gopy/_examples/calculatePi
2017/06/11 06:06:46 work: /tmp/gopy-214312004
root@180a6474ebba:~/test# python pi_mp.py
n: 100000
Python result: 3.135280 time_elapsed: 0.024898
gopy result: 3.143200 time_elapsed: 0.006861 ß Much Faster!!!
root@180a6474ebba:~/test# pypy pi_mp.py
n: 100000
Python result: 3.147240 time_elapsed: 0.023687
gopy result: 3.145040 time_elapsed: 0.017225 ß Much Faster!!!
root@180a6474ebba:~/test# python3 pi_mp.py
Python result: 3.136560 time_elapsed: 0.037512
gopy result: 3.143920 time_elapsed: 0.003738 <- Much Faster
GSoC Project: Support Python3 and PyPy
1. Inspects a Go package
2. Extracts the exported types, funcs, vars and consts
3. Creates a Go package that cgo exports the exported entities
4. Designates which interface should be exported to CFFI.
ffi.cdef("""
typedef signed char GoInt8;
typedef unsigned char GoUint8;
.
.
.
extern void cgo_pkg_calculatePi_init();
extern GoFloat64 cgo_func_calculatePi_GetPI(GoInt p0);
""")
GSoC Project: Support Python3 and PyPy
1. Inspects a Go package
2. Extracts the exported types, funcs, vars and consts
3. Creates a Go package that cgo exports the exported entities
4. Designates which interface should be exported to CFFI.
5. Creates a wrapping codes for CFFI by Python.
# pythonization of: calculatePi.GetPI
def GetPI(samples):
c_samples = _cffi_helper.cffi_cnv_py2c_int(samples)
cret = _cffi_helper.lib.cgo_func_calculatePi_GetPI(c_samples)
ret = _cffi_helper.cffi_cnv_c2py_float64(cret)
return ret
GSoC Project: Support Python3 and PyPy
0
0.02
0.04
0.06
0.08
0.1
0.12
0.14
10 100 1000 10000 100000 1000000
Timeelapsed
Sample counts
CPython2 VS gopy
CPython2 gopy
GSoC Project: Support Python3 and PyPy
0
0.005
0.01
0.015
0.02
0.025
0.03
0.035
0.04
10 100 1000 10000 100000 1000000
Timeelapsed
Sample counts
PyPy VS gopy
pypy gopy
GSoC Project: Support Python3 and PyPy
0
0.005
0.01
0.015
0.02
0.025
0.03
0.035
0.04
10 100 1000 10000 100000 1000000
Timeelapsed
Sample counts
Cpython3 VS gopy
CPython3 gopy
GSoC Project: Project Plan
• Migrate into CFFI library to gencffi*.go for current implementation.
• Implement wrapping of functions with builtin arguments.
• Implement wrapping of functions with slices/arrays of builtin arguments.
• Implement wrapping of functions with user types.
• Detect functions returning a Go error and make them pythonic
(raising an Exception).
• Implement wrapping of user types / Go maps / Go interfaces.
• Write documents for English and Korean.
GSoC Project: Goal
• Able to use Go’s awesome features on Python 2/3 and PyPy.
Newcomers are always welcomed
• https://github.com/go-python/gopy
• https://groups.google.com/forum/#!forum/go-python
• https://gophers.slack.com/messages/go-python
Thank you
donghee.na92@gmail.com

More Related Content

PDF
Introduction to cython: example of GCoptimization
PDF
Writing a Python C extension
PPTX
Mixing C++ & Python II: Pybind11
PPT
Introduction to cython
PDF
Take advantage of C++ from Python
PDF
Notes about moving from python to c++ py contw 2020
PDF
Cython - close to metal Python
PDF
PyCon TW 2017 - PyPy's approach to construct domain-specific language runtime...
Introduction to cython: example of GCoptimization
Writing a Python C extension
Mixing C++ & Python II: Pybind11
Introduction to cython
Take advantage of C++ from Python
Notes about moving from python to c++ py contw 2020
Cython - close to metal Python
PyCon TW 2017 - PyPy's approach to construct domain-specific language runtime...

What's hot (20)

PDF
Go. why it goes v2
PDF
Python on a chip
PPTX
Boost.Python: C++ and Python Integration
PDF
Threads and Callbacks for Embedded Python
PDF
Boost.Python - domesticating the snake
PPTX
Go. Why it goes
PDF
Shared Memory Parallelism with Python by Dr.-Ing Mike Muller
PDF
Easy native wrappers with SWIG
PDF
Interfacing C/C++ and Python with SWIG
PDF
Trivadis TechEvent 2016 Go - The Cloud Programming Language by Andija Sisko
PPTX
carrow - Go bindings to Apache Arrow via C++-API
PDF
CGo for fun and profit
PDF
Python Developer Certification
PPTX
SWIG Hello World
PDF
Про асинхронность / Максим Щепелин / Web Developer Wargaming
PDF
Reversing the dropbox client on windows
PPTX
Python on pi
PDF
Stack Hybridization: A Mechanism for Bridging Two Compilation Strategies in a...
PDF
WAD : A Module for Converting Fatal Extension Errors into Python Exceptions
PDF
Two-level Just-in-Time Compilation with One Interpreter and One Engine
Go. why it goes v2
Python on a chip
Boost.Python: C++ and Python Integration
Threads and Callbacks for Embedded Python
Boost.Python - domesticating the snake
Go. Why it goes
Shared Memory Parallelism with Python by Dr.-Ing Mike Muller
Easy native wrappers with SWIG
Interfacing C/C++ and Python with SWIG
Trivadis TechEvent 2016 Go - The Cloud Programming Language by Andija Sisko
carrow - Go bindings to Apache Arrow via C++-API
CGo for fun and profit
Python Developer Certification
SWIG Hello World
Про асинхронность / Максим Щепелин / Web Developer Wargaming
Reversing the dropbox client on windows
Python on pi
Stack Hybridization: A Mechanism for Bridging Two Compilation Strategies in a...
WAD : A Module for Converting Fatal Extension Errors into Python Exceptions
Two-level Just-in-Time Compilation with One Interpreter and One Engine
Ad

Similar to [GSoC 2017] gopy: Updating gopy to support Python3 and PyPy (20)

PDF
Extending Python - EuroPython 2014
PDF
Mpi in-python
PDF
Cluj.py Meetup: Extending Python in C
PDF
Extending Python - FOSDEM 2015
PDF
PyCon2022 - Building Python Extensions
PDF
Call a C API from Python becomes more enjoyable with CFFI, Jean-Sébastien Bev...
PDF
SunPy: Python for solar physics
PDF
mpi4py.pdf
PDF
Call a C API from Python becomes more enjoyable with CFFI
PPT
go.ppt
PDF
Go vs C++ - CppRussia 2019 Piter BoF
PDF
Python于Web 2.0网站的应用 - QCon Beijing 2010
PDF
Extending Python with ctypes
ODP
C Types - Extending Python
PPTX
EuroPython 2016 - Do I Need To Switch To Golang
PDF
PyHEP 2018: Tools to bind to Python
PPTX
Python with a SWIG of c++
PDF
Python高级编程(二)
PDF
CuPy: A NumPy-compatible Library for GPU
PDF
Extending Python - EuroPython 2014
Mpi in-python
Cluj.py Meetup: Extending Python in C
Extending Python - FOSDEM 2015
PyCon2022 - Building Python Extensions
Call a C API from Python becomes more enjoyable with CFFI, Jean-Sébastien Bev...
SunPy: Python for solar physics
mpi4py.pdf
Call a C API from Python becomes more enjoyable with CFFI
go.ppt
Go vs C++ - CppRussia 2019 Piter BoF
Python于Web 2.0网站的应用 - QCon Beijing 2010
Extending Python with ctypes
C Types - Extending Python
EuroPython 2016 - Do I Need To Switch To Golang
PyHEP 2018: Tools to bind to Python
Python with a SWIG of c++
Python高级编程(二)
CuPy: A NumPy-compatible Library for GPU
Ad

Recently uploaded (20)

PPTX
Sustainable Sites - Green Building Construction
PPT
Project quality management in manufacturing
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
PPTX
additive manufacturing of ss316l using mig welding
PPTX
Welding lecture in detail for understanding
PDF
Embodied AI: Ushering in the Next Era of Intelligent Systems
PDF
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
PDF
Arduino robotics embedded978-1-4302-3184-4.pdf
PDF
Digital Logic Computer Design lecture notes
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
PPTX
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
PDF
PPT on Performance Review to get promotions
PPTX
UNIT 4 Total Quality Management .pptx
DOCX
573137875-Attendance-Management-System-original
PDF
Structs to JSON How Go Powers REST APIs.pdf
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
PPTX
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
PDF
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
PPTX
IOT PPTs Week 10 Lecture Material.pptx of NPTEL Smart Cities contd
PPTX
CH1 Production IntroductoryConcepts.pptx
Sustainable Sites - Green Building Construction
Project quality management in manufacturing
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
additive manufacturing of ss316l using mig welding
Welding lecture in detail for understanding
Embodied AI: Ushering in the Next Era of Intelligent Systems
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
Arduino robotics embedded978-1-4302-3184-4.pdf
Digital Logic Computer Design lecture notes
UNIT-1 - COAL BASED THERMAL POWER PLANTS
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
PPT on Performance Review to get promotions
UNIT 4 Total Quality Management .pptx
573137875-Attendance-Management-System-original
Structs to JSON How Go Powers REST APIs.pdf
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
IOT PPTs Week 10 Lecture Material.pptx of NPTEL Smart Cities contd
CH1 Production IntroductoryConcepts.pptx

[GSoC 2017] gopy: Updating gopy to support Python3 and PyPy

  • 1. Updating gopy to support Python3 and PyPy Dong-hee Na, Chungnam National University, Daejeon, Korea Mentors: Sebastien Binet, Alexandre Claude 13. June. 2017
  • 2. Main topics • What is gopy? • Why Go ..? • Performance benchmark • Support CFFI backend
  • 3. What is gopy? • gopy is heavily inspired from gomobile. • gopy is a set of packages and build tools for using Go from python interpreters. • Generates (and compiles) a Python extension module from a Go package. ( https://github.com/golang/mobile)
  • 4. • LHC: 90% of C++ codes and a bit of Python codes for steering. Why Go? – Software at CERN 0 100 200 300 400 500 600 700 Users in CERN Know_The_User_Communities_Results_Summary.pdf
  • 5. Why Go …? Powerful performance Pros Long long compiling times Cons Manual memory Management Pros Cons - Easy to install libraries with ‘go get’. - Rich standard libraries. - Built-in concurrency support - Compile fast. - Elegant and simple built-in build system. - Garbage-collected language - Error detecting is awesome. - Learning curve is low - Powerful performance.Learning curve is high Global Interpreter Lock Interpreter based Library installation is easy Learning curve is low Useful Scientific Packages Compiled language
  • 6. gopy: Calculation of Pi Using the Monte Carlo Method func monte_carlo_pi(reps int, result *int, wait *sync.WaitGroup) { var x, y float64 count := 0 seed := rand.NewSource(time.Now().UnixNano()) random := rand.New(seed) for i := 0; i < reps; i++ { x = random.Float64() * 1.0 y = random.Float64() * 1.0 if num := math.Sqrt(x*x + y*y); num < 1.0 { count++ } } *result = count wait.Done() } http://tstra.us/code/goPi/ func GetPI(samples int) float64 { cores := runtime.NumCPU() runtime.GOMAXPROCS(cores) var wait sync.WaitGroup counts := make([]int, cores) wait.Add(cores) for i := 0; i < cores; i++ { go monte_carlo_pi(samples/cores, &counts[i], &wait) } wait.Wait() total := 0 for i := 0; i < cores; i++ { total += counts[i] } pi := (float64(total) / float64(samples)) * 4 return pi }
  • 7. gopy vs Python: Calculation of Pi Using the Monte Carlo Method • gopy is very easy to install. • Using a go get is all you have to do! $> go get -u -v github.com/go-python/gopy github.com/go-python/gopy (download) github.com/gonuts/commander (download) github.com/gonuts/flag (download) github.com/gonuts/flag github.com/go-python/gopy/bind github.com/gonuts/commander github.com/go-python/gopy
  • 8. gopy vs Python: Calculation of Pi Using the Monte Carlo Method def monte_carlo_pi_part(n): count = 0 for i in range(int(n)): x=random.random() y=random.random() # if it is within the unit circle if x*x + y*y <= 1: count=count+1 #return return count def GetPI(n): np = multiprocessing.cpu_count() part_count=[n/np for i in range(np)] pool = Pool(processes=np) count=pool.map(monte_carlo_pi_part, part_count) return sum(count)/(n*1.0)*4 https://gist.github.com/amitsaha/2036026 if __name__ == '__main__': n = 100000 py_start = time.time() result = GetPI(n) py_end = time.time() print("Python result: %f time_elapsed: %f" % (result, py_end-py_start)) go_start = time.time() result = calculatePi.GetPI(n) go_end = time.time() print("gopy result: %f time_elapsed: %f" %(result, go_end-go_start))
  • 9. gopy vs Python: Calculation of Pi Using the Monte Carlo Method • gopy helps to use Go’s useful features on the Python interpreter. • End-user can easily run Go codes on the Python interpreter. root@180a6474ebba:~/test# gopy bind github.com/go-python/gopy/_examples/calculatePi 2017/06/11 06:03:21 work: /tmp/gopy-546154656 root@180a6474ebba:~/test# python Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import calculatePi >>> calculatePi.GetPI(10000) 3.1564 root@180a6474ebba:~/test# python pi_mp.py n: 100000 Python result: 3.145880 time_elapsed: 0.030254 gopy result: 3.137400 time_elapsed: 0.002960 ß Much Faster!!!
  • 10. gopy: Limitation • gopy does not supports CPython3 nor PyPy. • Many go’s implementations/features are not yet implemented in gopy root@180a6474ebba:~/test# pypy pi_mp.py Traceback (most recent call last): File "pi_mp.py", line 12, in <module> import calculatePi ImportError: No module named calculatePi root@180a6474ebba:~/test# python3 Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import calculatePi Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: dynamic module does not define module export function (PyInit_calculatePi)
  • 11. GSoC Project: Support Python3 and PyPy • Need to support Py2/3 and PyPy. • PyPy’s implementation is not strictly 100% compatible with Ctypes. • CFFI is a good choice to support various python compilers. • CFFI interacts with almost any C code from Python. root@180a6474ebba:~/test# gopy bind --lang=cffi github.com/go- python/gopy/_examples/calculatePi 2017/06/11 06:06:46 work: /tmp/gopy-214312004 root@180a6474ebba:~/test# python pi_mp.py n: 100000 Python result: 3.135280 time_elapsed: 0.024898 gopy result: 3.143200 time_elapsed: 0.006861 ß Much Faster!!! root@180a6474ebba:~/test# pypy pi_mp.py n: 100000 Python result: 3.147240 time_elapsed: 0.023687 gopy result: 3.145040 time_elapsed: 0.017225 ß Much Faster!!! root@180a6474ebba:~/test# python3 pi_mp.py Python result: 3.136560 time_elapsed: 0.037512 gopy result: 3.143920 time_elapsed: 0.003738 <- Much Faster
  • 12. GSoC Project: Support Python3 and PyPy 1. Inspects a Go package 2. Extracts the exported types, funcs, vars and consts 3. Creates a Go package that cgo exports the exported entities 4. Designates which interface should be exported to CFFI. ffi.cdef(""" typedef signed char GoInt8; typedef unsigned char GoUint8; . . . extern void cgo_pkg_calculatePi_init(); extern GoFloat64 cgo_func_calculatePi_GetPI(GoInt p0); """)
  • 13. GSoC Project: Support Python3 and PyPy 1. Inspects a Go package 2. Extracts the exported types, funcs, vars and consts 3. Creates a Go package that cgo exports the exported entities 4. Designates which interface should be exported to CFFI. 5. Creates a wrapping codes for CFFI by Python. # pythonization of: calculatePi.GetPI def GetPI(samples): c_samples = _cffi_helper.cffi_cnv_py2c_int(samples) cret = _cffi_helper.lib.cgo_func_calculatePi_GetPI(c_samples) ret = _cffi_helper.cffi_cnv_c2py_float64(cret) return ret
  • 14. GSoC Project: Support Python3 and PyPy 0 0.02 0.04 0.06 0.08 0.1 0.12 0.14 10 100 1000 10000 100000 1000000 Timeelapsed Sample counts CPython2 VS gopy CPython2 gopy
  • 15. GSoC Project: Support Python3 and PyPy 0 0.005 0.01 0.015 0.02 0.025 0.03 0.035 0.04 10 100 1000 10000 100000 1000000 Timeelapsed Sample counts PyPy VS gopy pypy gopy
  • 16. GSoC Project: Support Python3 and PyPy 0 0.005 0.01 0.015 0.02 0.025 0.03 0.035 0.04 10 100 1000 10000 100000 1000000 Timeelapsed Sample counts Cpython3 VS gopy CPython3 gopy
  • 17. GSoC Project: Project Plan • Migrate into CFFI library to gencffi*.go for current implementation. • Implement wrapping of functions with builtin arguments. • Implement wrapping of functions with slices/arrays of builtin arguments. • Implement wrapping of functions with user types. • Detect functions returning a Go error and make them pythonic (raising an Exception). • Implement wrapping of user types / Go maps / Go interfaces. • Write documents for English and Korean.
  • 18. GSoC Project: Goal • Able to use Go’s awesome features on Python 2/3 and PyPy.
  • 19. Newcomers are always welcomed • https://github.com/go-python/gopy • https://groups.google.com/forum/#!forum/go-python • https://gophers.slack.com/messages/go-python