benchmark.py 13 KB

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