For @Aaron who asked:
I am hoping to find a gdalwarp version of @wwnick's answer that utilizes the -multi option for enhanced multicore and multithreaded operations
Slight Disclaimer
This uses gdalwarp, though I'm not totally convinced there will be much performance gain. So far I've been I/O bound - running this script on a large raster cutting it into many smaller parts doesn't seem CPU intensive, so I assume the bottleneck is writing to disk. If you're planning on simultaneously re-projecting the tiles or something similar, then this might change. There are tuning tips here. A brief play didn't yield any improvement for me, and CPU never seemed to be the limiting factor.
Disclaimer aside, here's a script that will use gdalwarp to split up a raster into several smaller tiles. There might be some loss due to the floor division but this can be taken care of by picking the number of tiles you want. It will be n+1 where n is the number you divide by to get the tile_width and tile_height variables.
import subprocess
import gdal
import sys
def gdalwarp(*args):
return subprocess.check_call(['gdalwarp'] + list(args))
src_path = sys.argv[1]
ds = gdal.Open(src_path)
try:
out_base = sys.argv[2]
except IndexError:
out_base = '/tmp/test_'
gt = ds.GetGeoTransform()
width_px = ds.RasterXSize
height_px = ds.RasterYSize
# Get coords for lower left corner
xmin = int(gt[0])
xmax = int(gt[0] + (gt[1] * width_px))
# get coords for upper right corner
if gt[5] > 0:
ymin = int(gt[3] - (gt[5] * height_px))
else:
ymin = int(gt[3] + (gt[5] * height_px))
ymax = int(gt[3])
# split height and width into four - i.e. this will produce 25 tiles
tile_width = (xmax - xmin) // 4
tile_height = (ymax - ymin) // 4
for x in range(xmin, xmax, tile_width):
for y in range(ymin, ymax, tile_height):
gdalwarp('-te', str(x), str(y), str(x + tile_width),
str(y + tile_height), '-multi', '-wo', 'NUM_THREADS=ALL_CPUS',
'-wm', '500', src_path, out_base + '{}_{}.tif'.format(x, y))