benchmark.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Sat Jun 16 20:24:56 2012
  4. @author: soeren
  5. """
  6. from __future__ import (
  7. nested_scopes,
  8. generators,
  9. division,
  10. absolute_import,
  11. with_statement,
  12. print_function,
  13. unicode_literals,
  14. )
  15. import optparse
  16. # import numpy as np
  17. import time
  18. import collections
  19. import copy
  20. import cProfile
  21. import sys
  22. import os
  23. from jinja2 import Template
  24. sys.path.append(os.getcwd())
  25. sys.path.append("%s/.." % (os.getcwd()))
  26. import grass.lib.gis as libgis
  27. import grass.lib.raster as libraster
  28. import grass.script as core
  29. import grass.pygrass
  30. import ctypes
  31. def test__RasterSegment_value_access__if():
  32. test_a = pygrass.RasterSegment(name="test_a")
  33. test_a.open(mode="r")
  34. test_c = pygrass.RasterSegment(name="test_c")
  35. test_c.open(mode="w", mtype="CELL", overwrite=True)
  36. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  37. for row in range(test_a.rows):
  38. test_a.get_row(row, buff_a)
  39. for col in range(test_a.cols):
  40. test_c.put(row, col, buff_a[col] > 50)
  41. test_a.close()
  42. test_c.close()
  43. def test__RasterSegment_value_access__add():
  44. test_a = pygrass.RasterSegment(name="test_a")
  45. test_a.open(mode="r")
  46. test_b = pygrass.RasterSegment(name="test_b")
  47. test_b.open(mode="r")
  48. test_c = pygrass.RasterSegment(name="test_c")
  49. test_c.open(mode="w", mtype="DCELL", overwrite=True)
  50. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  51. buff_b = pygrass.Buffer(test_b.cols, test_b.mtype)
  52. for row in range(test_a.rows):
  53. test_a.get_row(row, buff_a)
  54. test_b.get_row(row, buff_b)
  55. for col in range(test_a.cols):
  56. test_c.put(row, col, buff_a[col] + buff_b[col])
  57. test_a.close()
  58. test_b.close()
  59. test_c.close()
  60. def test__RasterSegment_row_access__if():
  61. test_a = pygrass.RasterSegment(name="test_a")
  62. test_a.open(mode="r")
  63. test_c = pygrass.RasterSegment(name="test_c")
  64. test_c.open(mode="w", mtype="CELL", overwrite=True)
  65. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  66. for row in range(test_a.rows):
  67. test_a.get_row(row, buff_a)
  68. test_c.put_row(row, buff_a > 50)
  69. test_a.close()
  70. test_c.close()
  71. def test__RasterSegment_row_access__add():
  72. test_a = pygrass.RasterSegment(name="test_a")
  73. test_a.open(mode="r")
  74. test_b = pygrass.RasterSegment(name="test_b")
  75. test_b.open(mode="r")
  76. test_c = pygrass.RasterSegment(name="test_c")
  77. test_c.open(mode="w", mtype="DCELL", overwrite=True)
  78. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  79. buff_b = pygrass.Buffer(test_b.cols, test_b.mtype)
  80. for row in range(test_a.rows):
  81. test_a.get_row(row, buff_a)
  82. test_b.get_row(row, buff_b)
  83. test_c.put_row(row, buff_a + buff_b)
  84. test_a.close()
  85. test_b.close()
  86. test_c.close()
  87. def test__RasterRow_value_access__add():
  88. test_a = pygrass.RasterRow(name="test_a")
  89. test_a.open(mode="r")
  90. test_b = pygrass.RasterRow(name="test_b")
  91. test_b.open(mode="r")
  92. test_c = pygrass.RasterRow(name="test_c")
  93. test_c.open(mode="w", mtype="FCELL", overwrite=True)
  94. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  95. buff_b = pygrass.Buffer(test_b.cols, test_b.mtype)
  96. buff_c = pygrass.Buffer(test_b.cols, test_b.mtype)
  97. for row in range(test_a.rows):
  98. test_a.get_row(row, buff_a)
  99. test_b.get_row(row, buff_b)
  100. for col in range(test_a.cols):
  101. buff_c[col] = buff_a[col] + buff_b[col]
  102. test_c.put_row(buff_c)
  103. test_a.close()
  104. test_b.close()
  105. test_c.close()
  106. def test__RasterRow_value_access__if():
  107. test_a = pygrass.RasterRow(name="test_a")
  108. test_a.open(mode="r")
  109. test_c = pygrass.RasterRow(name="test_c")
  110. test_c.open(mode="w", mtype="CELL", overwrite=True)
  111. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  112. buff_c = pygrass.Buffer(test_a.cols, test_a.mtype)
  113. for row in range(test_a.rows):
  114. test_a.get_row(row, buff_a)
  115. for col in range(test_a.cols):
  116. buff_c[col] = buff_a[col] > 50
  117. test_c.put_row(buff_c)
  118. test_a.close()
  119. test_c.close()
  120. def test__RasterRowIO_row_access__add():
  121. test_a = pygrass.RasterRowIO(name="test_a")
  122. test_a.open(mode="r")
  123. test_b = pygrass.RasterRowIO(name="test_b")
  124. test_b.open(mode="r")
  125. test_c = pygrass.RasterRowIO(name="test_c")
  126. test_c.open(mode="w", mtype="FCELL", overwrite=True)
  127. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  128. buff_b = pygrass.Buffer(test_b.cols, test_b.mtype)
  129. for row in range(test_a.rows):
  130. test_a.get_row(row, buff_a)
  131. test_b.get_row(row, buff_b)
  132. test_c.put_row(buff_a + buff_b)
  133. test_a.close()
  134. test_b.close()
  135. test_c.close()
  136. def test__RasterRowIO_row_access__if():
  137. test_a = pygrass.RasterRowIO(name="test_a")
  138. test_a.open(mode="r")
  139. test_c = pygrass.RasterRowIO(name="test_c")
  140. test_c.open(mode="w", mtype="CELL", overwrite=True)
  141. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  142. for row in range(test_a.rows):
  143. test_a.get_row(row, buff_a)
  144. test_c.put_row(buff_a > 50)
  145. test_a.close()
  146. test_c.close()
  147. def test__RasterRow_row_access__add():
  148. test_a = pygrass.RasterRow(name="test_a")
  149. test_a.open(mode="r")
  150. test_b = pygrass.RasterRow(name="test_b")
  151. test_b.open(mode="r")
  152. test_c = pygrass.RasterRow(name="test_c")
  153. test_c.open(mode="w", mtype="FCELL", overwrite=True)
  154. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  155. buff_b = pygrass.Buffer(test_b.cols, test_b.mtype)
  156. for row in range(test_a.rows):
  157. test_a.get_row(row, buff_a)
  158. test_b.get_row(row, buff_b)
  159. test_c.put_row(buff_a + buff_b)
  160. test_a.close()
  161. test_b.close()
  162. test_c.close()
  163. def test__RasterRow_row_access__if():
  164. test_a = pygrass.RasterRow(name="test_a")
  165. test_a.open(mode="r")
  166. test_c = pygrass.RasterRow(name="test_c")
  167. test_c.open(mode="w", mtype="CELL", overwrite=True)
  168. buff_a = pygrass.Buffer(test_a.cols, test_a.mtype)
  169. for row in range(test_a.rows):
  170. test_a.get_row(row, buff_a)
  171. test_c.put_row(buff_a > 50)
  172. test_a.close()
  173. test_c.close()
  174. def test__mapcalc__add():
  175. core.mapcalc("test_c = test_a + test_b", quite=True, overwrite=True)
  176. def test__mapcalc__if():
  177. core.mapcalc("test_c = if(test_a > 50, 1, 0)", quite=True, overwrite=True)
  178. def mytimer(func, runs=1):
  179. times = []
  180. t = 0.0
  181. for _ in range(runs):
  182. start = time.time()
  183. func()
  184. end = time.time()
  185. times.append(end - start)
  186. t = t + end - start
  187. return t / runs, times
  188. def run_benchmark(resolution_list, runs, testdict, profile):
  189. regions = []
  190. for resolution in resolution_list:
  191. core.use_temp_region()
  192. core.run_command(
  193. "g.region", e=50, w=-50, n=50, s=-50, res=resolution, flags="p"
  194. )
  195. # Adjust the computational region for this process
  196. region = libgis.Cell_head()
  197. libraster.Rast_get_window(ctypes.byref(region))
  198. region.e = 50
  199. region.w = -50
  200. region.n = 50
  201. region.s = -50
  202. region.ew_res = resolution
  203. region.ns_res = resolution
  204. libgis.G_adjust_Cell_head(ctypes.byref(region), 0, 0)
  205. libraster.Rast_set_window(ctypes.byref(region))
  206. libgis.G_set_window(ctypes.byref(region))
  207. # Create two raster maps with random numbers
  208. core.mapcalc("test_a = rand(0, 100)", quite=True, overwrite=True)
  209. core.mapcalc("test_b = rand(0.0, 1.0)", quite=True, overwrite=True)
  210. result = collections.OrderedDict()
  211. result["res"] = resolution
  212. result["cols"] = region.cols
  213. result["rows"] = region.rows
  214. result["cells"] = region.rows * region.cols
  215. result["results"] = copy.deepcopy(testdict)
  216. for execmode, operation in result["results"].items():
  217. print(execmode)
  218. for oper, operdict in operation.items():
  219. operdict["time"], operdict["times"] = mytimer(operdict["func"], runs)
  220. if profile:
  221. filename = "{0}_{1}_{2}".format(execmode, oper, profile)
  222. cProfile.runctx(
  223. operdict["func"].__name__ + "()",
  224. globals(),
  225. locals(),
  226. filename=filename,
  227. )
  228. print((" {0}: {1: 40.6f}s".format(oper, operdict["time"])))
  229. del operdict["func"]
  230. regions.append(result)
  231. core.del_temp_region()
  232. return regions
  233. def get_testlist(loc):
  234. testlist = [test for test in list(loc.keys()) if "test" in test[:5]]
  235. testlist.sort()
  236. return testlist
  237. def get_testdict(testlist):
  238. testdict = collections.OrderedDict()
  239. for testfunc in testlist:
  240. # import pdb; pdb.set_trace()
  241. dummy, execmode, operation = testfunc.split("__")
  242. if execmode in list(testdict.keys()):
  243. testdict[execmode][operation] = collections.OrderedDict()
  244. testdict[execmode][operation]["func"] = loc[testfunc]
  245. else:
  246. testdict[execmode] = collections.OrderedDict()
  247. testdict[execmode][operation] = collections.OrderedDict()
  248. testdict[execmode][operation]["func"] = loc[testfunc]
  249. return testdict
  250. def print_test(testdict):
  251. for execmode, operation in testdict.items():
  252. print(execmode)
  253. for oper, operdict in operation.items():
  254. print(" ", oper)
  255. for key, value in operdict.items():
  256. print(" ", key)
  257. TXT = """
  258. {% for region in regions %}
  259. {{ '#'*60 }}
  260. ### Benchmark cols = {{ region.cols }} rows = {{ region.rows}} cells = {{ region.cells }}
  261. {{ '#'*60 }}
  262. # equation: c = a + b
  263. {% for execmode, operation in region.results.iteritems() %}
  264. {{ "%-30s - %5s % 12.6fs"|format(execmode, 'add', operation.add.time) }}
  265. {%- endfor %}
  266. # equation: c = if a > 50 then 1 else 0
  267. {% for execmode, operation in region.results.iteritems() %}
  268. {{ "%-30s - %5s % 12.6fs"|format(execmode, 'if', operation.if.time) }}
  269. {%- endfor %}
  270. {%- endfor %}
  271. """
  272. CSV = """Class; Mode; Operation;
  273. """
  274. RST = """
  275. """
  276. # >>> txt = Template(TxT)
  277. # >>> txt.render(name='John Doe')
  278. def get_txt(results):
  279. txt = Template(TXT)
  280. return txt.render(regions=results)
  281. # classes for required options
  282. strREQUIRED = "required"
  283. class OptionWithDefault(optparse.Option):
  284. ATTRS = optparse.Option.ATTRS + [strREQUIRED]
  285. def __init__(self, *opts, **attrs):
  286. if attrs.get(strREQUIRED, False):
  287. attrs["help"] = "(Required) " + attrs.get("help", "")
  288. optparse.Option.__init__(self, *opts, **attrs)
  289. class OptionParser(optparse.OptionParser):
  290. def __init__(self, **kwargs):
  291. kwargs["option_class"] = OptionWithDefault
  292. optparse.OptionParser.__init__(self, **kwargs)
  293. def check_values(self, values, args):
  294. for option in self.option_list:
  295. if hasattr(option, strREQUIRED) and option.required:
  296. if not getattr(values, option.dest):
  297. self.error("option {} is required".format(str(option)))
  298. return optparse.OptionParser.check_values(self, values, args)
  299. def main(testdict):
  300. """Main function"""
  301. # usage
  302. usage = "usage: %prog [options] raster_map"
  303. parser = OptionParser(usage=usage)
  304. # ntime
  305. parser.add_option(
  306. "-n",
  307. "--ntimes",
  308. dest="ntime",
  309. default=5,
  310. type="int",
  311. help="Number of run for each test.",
  312. )
  313. # res
  314. parser.add_option(
  315. "-r",
  316. "--resolution",
  317. action="store",
  318. type="string",
  319. dest="res",
  320. default="1,0.25",
  321. help="Resolution list separate by comma.",
  322. )
  323. # fmt
  324. parser.add_option(
  325. "-f",
  326. "--fmt",
  327. action="store",
  328. type="string",
  329. dest="fmt",
  330. default="txt",
  331. help="Choose the output format: 'txt', 'csv', 'rst'.",
  332. )
  333. # output
  334. parser.add_option(
  335. "-o",
  336. "--output",
  337. action="store",
  338. type="string",
  339. dest="output",
  340. help="The output filename.",
  341. )
  342. # store
  343. parser.add_option(
  344. "-s",
  345. "--store",
  346. action="store",
  347. type="string",
  348. dest="store",
  349. help="The filename of pickle obj.",
  350. )
  351. # profile
  352. parser.add_option(
  353. "-p",
  354. "--profile",
  355. action="store",
  356. type="string",
  357. dest="profile",
  358. help="The filename of the profile results.",
  359. )
  360. # return options and argument
  361. options, args = parser.parse_args()
  362. res = [float(r) for r in options.res.split(",")]
  363. # res = [1, 0.25, 0.1, 0.05]
  364. results = run_benchmark(res, options.ntime, testdict, options.profile)
  365. if options.store:
  366. import pickle
  367. output = open(options.store, "wb")
  368. pickle.dump(results, output)
  369. output.close()
  370. # import pdb; pdb.set_trace()
  371. print(get_txt(results))
  372. # add options
  373. if __name__ == "__main__":
  374. # import pdb; pdb.set_trace()
  375. loc = locals()
  376. testlist = get_testlist(loc)
  377. testdict = get_testdict(testlist)
  378. # print_test(testdict)
  379. # import pdb; pdb.set_trace()
  380. main(testdict)