Пример #1
0
def variable_num_jobs(
    template_dir, output_dir, job_gen_type, topologies, num_nodes, repetition, **kwargs
):
    num_cores = num_cores_per_node * num_nodes

    for topology in topologies:
        num_leaves = common.prod(topology)
        jobs_per_leaf = [1, 4, 16, 64, 256, 1024, 4096]
        if len(topology) > 1:
            # prevent OOM from too many jobs per node
            jobs_per_leaf = jobs_per_leaf[:-1]

        for idx, num_jobs in enumerate([x * num_leaves for x in jobs_per_leaf]):
            est_minutes = common.estimate_num_minutes(
                num_jobs, num_leaves, kwargs["unique_id"]
            )
            hours = int(est_minutes // 60)
            minutes = int(est_minutes % 60)
            kwargs["timelimit"] = "{:02d}:{:02d}:00".format(hours, minutes)
            make_test(
                topology,
                num_jobs,
                num_nodes,
                num_cores_per_node,
                repetition,
                template_dir,
                output_dir,
                job_gen_type,
                **kwargs,
            )
def build_model(template_dir, output_dir, job_gen_type, repetition, **kwargs):
    num_nodes = 1
    num_cores = num_cores_per_node * num_nodes
    topologies = [[1], [1, num_cores_per_node]]
    for topology in topologies:
        jobs = [1, 4, 16, 64, 256, 1024, 4096]
        if len(topology) > 1:
            # prevent OOM from too many jobs per node
            jobs = jobs[:-1]

        if args.small_scale:
            jobs = jobs[:3]
        elif args.medium_scale:
            jobs = jobs[:6]

        for idx, jobs_per_leaf in enumerate(jobs):
            num_leaves = common.prod(topology)
            num_jobs = jobs_per_leaf * num_leaves
            est_minutes = common.estimate_num_minutes(num_jobs, num_leaves,
                                                      kwargs["unique_id"])
            hours = int(est_minutes // 60)
            minutes = int(est_minutes % 60)
            kwargs["timelimit"] = "{:02d}:{:02d}:00".format(hours, minutes)
            make_test(
                topology,
                num_jobs,
                num_nodes,
                num_cores_per_node,
                repetition,
                template_dir,
                output_dir,
                job_gen_type,
                **kwargs,
            )
def just_hierarchy_setup(template_dir, output_dir, job_gen_type, topologies,
                         num_nodes, repetition, **kwargs):
    fake_jobs_kwargs = kwargs.copy()
    fake_jobs_kwargs["command"] = "sleep 0"
    fake_jobs_kwargs["unique_id"] = "setup"
    fake_jobs_kwargs["timelimit"] = "00:05:00"
    fake_jobs_kwargs["just_setup"] = True

    for topology in topologies:
        for nnodes in [1, num_nodes]:
            num_jobs = common.prod(topology)
            make_test(
                topology,
                num_jobs,
                nnodes,
                num_cores_per_node,
                repetition,
                template_dir,
                output_dir,
                job_gen_type,
                **fake_jobs_kwargs,
            )

    fake_jobs_kwargs = kwargs.copy()
    fake_jobs_kwargs["command"] = "flux mini submit -n1 -c1 sleep 0"
    fake_jobs_kwargs["unique_id"] = "sleep0"
    fake_jobs_kwargs["timelimit"] = "00:15:00"

    branch_factors = {bf for topo in topologies for bf in topo}
    for bf in branch_factors:
        for nnodes in [1, num_nodes]:
            num_jobs = bf
            make_test(
                [1],
                num_jobs,
                nnodes,
                num_cores_per_node,
                repetition,
                template_dir,
                output_dir,
                job_gen_type,
                **fake_jobs_kwargs,
            )
Пример #4
0
        def runPWLoopModel(linfo, my_params):
            result = {}

            result['linenum'] = linfo['linenum']
            numSweeps = doParamSubs(linfo['sweeps'], my_params)
            result['range'] = (doParamSubs(numIters(linfo['ranges'][0]), my_params), \
                               doParamSubs(numIters(linfo['ranges'][1]), my_params), \
                               doParamSubs(numIters(linfo['ranges'][2]), my_params))
            blockx = my_params['X Block Size'] + (result['range'][0] -
                                                  my_params['X Problem Size'])
            blocky = my_params['Y Block Size'] + (result['range'][1] -
                                                  my_params['Y Problem Size'])
            blockz = my_params['Z Block Size'] + (result['range'][2] -
                                                  my_params['Z Problem Size'])
            result['block'] = [blockx, blocky, blockz]
            numBlocks = (my_params['X Problem Size'] * my_params['Y Problem Size'] * my_params['Z Problem Size']) / \
                         (my_params['X Block Size'] * my_params['Y Block Size'] * my_params['Z Block Size'])
            result['numBlocks'] = numBlocks

            # registers
            result['GPRegs'] = doParamSubs(
                linfo['registers']['ints'] + linfo['registers']['ptrs'],
                my_params)
            result['FPRegs'] = doParamSubs(linfo['registers']['floats'],
                                           my_params)
            result['regAlloc'] = regAllocModel(linfo, my_params)

            # save working set and memory traffic
            result['WSFinal'] = doParamSubs(
                my_params['Word Size'] * linfo['WS']['sizeBlocks'], my_params)
            if result['WSFinal'] <= my_params['$/thread group (kB)'] * 2**10:
                result['BWFinal'] = numBlocks * doParamSubs(my_params[ 'R cost'] * linfo['BW']['sizeBlocks']['R'] + \
                                                            my_params[ 'W cost'] * linfo['BW']['sizeBlocks']['W'] + \
                                                            my_params['RW cost'] * linfo['BW']['sizeBlocks']['RW'], my_params)
            else:
                # if not enough cache, punt on this method
                result['BWFinal'] = float('inf')

            # number of flops and weighted flops
            numCellIters = numSweeps * numBlocks * prod(result['block'])
            result['adds'] = numCellIters * doParamSubs(
                linfo['flops']['adds'], my_params)
            result['multiplies'] = numCellIters * doParamSubs(
                linfo['flops']['multiplies'], my_params)
            result['divides'] = numCellIters * doParamSubs(
                linfo['flops']['divides'], my_params)
            result['specials'] = numCellIters * doParamSubs(
                linfo['flops']['specials'], my_params)
            result['flops'] = result['adds'] + result['multiplies'] + result[
                'divides'] + result['specials']
            result['wflops'] = result['adds'] + result['multiplies'] + my_params['Division Cost'] * result['divides'] + \
                                                                       my_params['Special Cost'] * result['specials']

            # arithmetic intensity
            if result['wflops'] != 0:
                result['BF'] = float(result['BWFinal']) / result['wflops']
            else:
                result['BF'] = float('nan')

            # execution time
            result['cputime'] = float(result['wflops']) / \
                                (my_params['Gflop/s/thread'] * my_params['Threads'] * 10**9)
            result['ramtime'] = float(result['BWFinal']) / \
                                (my_params['GB/s/thread'] * my_params['Threads'] * 2**30)
            # assume perfect overlap
            if result['cputime'] > result['ramtime']:
                result['ramtime'] = 0
            else:
                result['cputime'] = 0
            result['time'] = max(result['cputime'], result['ramtime'])

            return result
Пример #5
0
        def runLoopModel(linfo, my_params):
            result = {}

            result['linenum'] = linfo['linenum']
            result['range'] = (doParamSubs(numIters(linfo['ranges'][0]), my_params), \
                               doParamSubs(numIters(linfo['ranges'][1]), my_params), \
                               doParamSubs(numIters(linfo['ranges'][2]), my_params))
            blockx = my_params['X Block Size']
            blocky = my_params['Y Block Size']
            blockz = my_params['Z Block Size']
            result['block'] = [blockx, blocky, blockz]
            result['numBlocks'] = float(prod(result['range'])) / prod(
                result['block'])

            # round blockx up to nearest cache line multiple
            CLWords = my_params['Cache Line Size'] / my_params['Word Size']
            blockx = math.ceil(float(blockx) / CLWords) * CLWords

            # registers
            result['GPRegs'] = doParamSubs(
                linfo['registers']['ints'] + linfo['registers']['ptrs'],
                my_params)
            result['FPRegs'] = doParamSubs(linfo['registers']['floats'],
                                           my_params)
            result['regAlloc'] = regAllocModel(linfo, my_params)

            # Compute working sets and memory traffic for read-only arrays
            arrays = []
            for ainfo in analyze.getR(linfo['arrays']):
                array = {}
                array['name'] = ainfo['name']
                array['access'] = map(lambda x, y: x + diff(y)[0],
                                      result['block'], ainfo['ghost'])
                accessx = array['access'][0]
                accessy = array['access'][1]
                accessz = array['access'][2]

                # round accessx up to nearest cache line multiple
                accessx = math.ceil(float(accessx) / CLWords) * CLWords

                # WS calculation for generic case
                array['WS'] = {'all'  : {'plane' : my_params['Word Size'] * ainfo['WS']['numPlanes'] * \
                                                   accessx * accessy, \
                                         'pencil': my_params['Word Size'] * ainfo['WS']['numPencils'] * \
                                                   accessx, \
                                         'cell'  : my_params['Word Size'] * ainfo['WS']['numCells'], \
                                        }, \
                               'reuse': {'plane' : my_params['Word Size'] * ainfo['WS']['numReusePlanes'] * \
                                                   accessx * accessy, \
                                         'pencil': my_params['Word Size'] * ainfo['WS']['numReusePencils'] * \
                                                   accessx, \
                                         'cell'  : my_params['Word Size'] * ainfo['WS']['numReuseCells'], \
                                        }, \
                              }
                # fix the plane WS for faces-only stencils
                if ainfo['stenciltype'] == 'faces':

                    array['WS']['all']['plane'] = my_params['Word Size'] * \
                        ((ainfo['WS']['numPlanes'] - 1) * (blockx * blocky) + \
                         1 * (blockx * accessy + accessx * blocky - blockx * blocky))
                    array['WS']['all']['pencil'] = my_params['Word Size'] * \
                        ((ainfo['WS']['numPencils'] - 1) * blockx + 1 * accessx)

                    array['WS']['reuse']['plane'] = my_params['Word Size'] * \
                        ((ainfo['WS']['numReusePlanes'] - 1) * (blockx * blocky) + \
                         1 * (blockx * accessy + accessx * blocky - blockx * blocky))
                    array['WS']['reuse']['pencil'] = my_params['Word Size'] * \
                        ((ainfo['WS']['numReusePencils'] - 1) * blockx + 1 * accessx)

                # BW calculation for generic case
                array['BW'] = {'block' : result['numBlocks'] * ainfo['BW']['numCopies'] * my_params['R cost'] * \
                                         accessx * accessy * accessz, \
                               'plane' : result['numBlocks'] * ainfo['BW']['numPlanes'] * my_params['R cost'] * \
                                         accessx * accessy * blockz, \
                               'pencil': result['numBlocks'] * ainfo['BW']['numPencils'] * my_params['R cost'] * \
                                         accessx * blocky * blockz, \
                               'cell'  : result['numBlocks'] * ainfo['BW']['numCells'] * my_params['R cost'] * \
                                         blockx * blocky * blockz, \
                              }
                # fix the block and plane BW for faces-only stencils
                if ainfo['stenciltype'] == 'faces':
                    array['BW']['block'] = result['numBlocks'] * ainfo['BW']['numCopies'] * my_params['R cost'] * \
                        (accessx * blocky * blockz + blockx * accessy * blockz + \
                         blockx * blocky * accessz - 2 * blockx * blocky * blockz)
                    array['BW']['plane'] = result['numBlocks'] * my_params['R cost'] * \
                        ((ainfo['BW']['numPlanes'] - 1) * (blockx * blocky) + \
                         1 * (accessx * blocky + blockx * accessy - blockx * blocky)) * blockz
                    array['BW']['pencil'] = result['numBlocks'] * my_params['R cost'] * \
                        ((ainfo['BW']['numPencils'] - 1) * blockx + 1 * accessx) * blocky * blockz

                arrays.append(array)

            sumWSAllPlane = sum(map(lambda x: x['WS']['all']['plane'], arrays))
            sumWSAllPencil = sum(
                map(lambda x: x['WS']['all']['pencil'], arrays))
            sumWSAllCell = sum(map(lambda x: x['WS']['all']['cell'], arrays))
            sumWSReusePlane = sum(
                map(lambda x: x['WS']['reuse']['plane'], arrays))
            sumWSReusePencil = sum(
                map(lambda x: x['WS']['reuse']['pencil'], arrays))
            sumWSReuseCell = sum(
                map(lambda x: x['WS']['reuse']['cell'], arrays))

            sumBWBlock = sum(map(lambda x: x['BW']['block'], arrays))
            sumBWPlane = sum(map(lambda x: x['BW']['plane'], arrays))
            sumBWPencil = sum(map(lambda x: x['BW']['pencil'], arrays))
            sumBWCell = sum(map(lambda x: x['BW']['cell'], arrays))

            result['arrays'] = arrays

            # Compute working sets for different scenarios
            result['WS'] = {'all'   : {'plane' : sumWSAllPlane + my_params['Word Size'] * \
                                                 (linfo['WS']['numPlanes']['RW'] + linfo['WS']['numPlanes']['W']) * \
                                                 blockx * blocky, \
                                       'pencil': sumWSAllPencil + my_params['Word Size'] * \
                                                 (linfo['WS']['numPencils']['RW'] + linfo['WS']['numPencils']['W']) * \
                                                 blockx, \
                                       'cell'  : sumWSAllCell + my_params['Word Size'] * \
                                                 (linfo['WS']['numCells']['RW'] + linfo['WS']['numCells']['W']), \
                                      }, \
                            'stream': {'plane' : sumWSAllPlane, \
                                       'pencil': sumWSAllPencil, \
                                       'cell'  : sumWSAllCell, \
                                      }, \
                            'reuse' : {'plane' : sumWSReusePlane, \
                                       'pencil': sumWSReusePencil, \
                                       'cell'  : sumWSReuseCell, \
                                      }, \
                           }

            # Determine actual working sets based on cache utilization policy
            if my_params['NTA Hints']:
                result['WS']['actual'] = result['WS']['reuse']
            elif my_params['Streaming Writes']:
                result['WS']['actual'] = result['WS']['stream']
            else:
                result['WS']['actual'] = result['WS']['all']

            # Compute memory traffic for different reuse scenarios
            numSweeps = doParamSubs(linfo['sweeps'], my_params)
            RWWBW = (linfo['BW']['numArrays']['RW'] * my_params['RW cost'] + \
                     linfo['BW']['numArrays']['W' ] * my_params['W cost' ]) * result['numBlocks'] * blockx * blocky * blockz
            result['BW'] = {'block' : numSweeps * (sumBWBlock  + RWWBW), \
                            'plane' : numSweeps * (sumBWPlane  + RWWBW), \
                            'pencil': numSweeps * (sumBWPencil + RWWBW), \
                            'cell'  : numSweeps * (sumBWCell   + RWWBW), \
                           }

            # do symbolic parameter substitutions
            for x in result['WS'].values():
                for (y, z) in x.iteritems():
                    x[y] = doParamSubs(z, my_params)
            for (y, z) in result['BW'].iteritems():
                result['BW'][y] = doParamSubs(z, my_params)

            # bandwidth should be no worse than model prediction for cases with worse reuse,
            #   but model approximations cause different inaccuracies for different cases
            result['BW']['pencil'] = min(result['BW']['pencil'],
                                         result['BW']['cell'])
            result['BW']['plane'] = min(result['BW']['plane'],
                                        result['BW']['pencil'])
            result['BW']['block'] = min(result['BW']['block'],
                                        result['BW']['plane'])

            # if there's no difference between memory traffic, working set is effectively reduced
            if result['BW']['pencil'] == result['BW']['cell']:
                result['WS']['actual']['cell'] = 0
            if result['BW']['plane'] == result['BW']['pencil']:
                result['WS']['actual']['pencil'] = result['WS']['actual'][
                    'cell']
            if result['BW']['block'] == result['BW']['plane']:
                result['WS']['actual']['plane'] = result['WS']['actual'][
                    'pencil']

            # Compute "actual" memory traffic based on type of reuse given available cache
            if result['WS']['actual'][
                    'plane'] <= my_params['$/thread group (kB)'] * 2**10:
                result['BW']['actual'] = result['BW']['block']
            elif result['WS']['actual'][
                    'pencil'] <= my_params['$/thread group (kB)'] * 2**10:
                result['BW']['actual'] = result['BW']['plane']
            elif result['WS']['actual'][
                    'cell'] <= my_params['$/thread group (kB)'] * 2**10:
                result['BW']['actual'] = result['BW']['pencil']
            else:
                result['BW']['actual'] = result['BW']['cell']

            # save final WS and BW
            result['WSFinal'] = result['WS']['actual']['plane']
            result['BWFinal'] = result['BW']['actual']

            # number of flops and weighted flops
            result['adds'] = numSweeps * prod(result['range']) * doParamSubs(
                linfo['flops']['adds'], my_params)
            result['multiplies'] = numSweeps * prod(
                result['range']) * doParamSubs(linfo['flops']['multiplies'],
                                               my_params)
            result['divides'] = numSweeps * prod(
                result['range']) * doParamSubs(linfo['flops']['divides'],
                                               my_params)
            result['specials'] = numSweeps * prod(
                result['range']) * doParamSubs(linfo['flops']['specials'],
                                               my_params)
            result['flops'] = result['adds'] + result['multiplies'] + result[
                'divides'] + result['specials']
            result['wflops'] = result['adds'] + result['multiplies'] + my_params['Division Cost'] * result['divides'] + \
                                                                       my_params['Special Cost'] * result['specials']

            # arithmetic intensity
            if result['wflops'] != 0:
                result['BF'] = float(result['BWFinal']) / result['wflops']
            else:
                result['BF'] = float('nan')

            # execution time
            result['cputime'] = float(result['wflops']) / \
                                (my_params['Gflop/s/thread'] * my_params['Threads'] * 10**9)
            result['ramtime'] = float(result['BW']['actual']) / \
                                (my_params['GB/s/thread'] * my_params['Threads'] * 2**30)
            # assume perfect overlap
            if result['cputime'] > result['ramtime']:
                result['ramtime'] = 0
            else:
                result['cputime'] = 0
            result['time'] = max(result['cputime'], result['ramtime'])

            return result
Пример #6
0
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
"""

g = [[int(i) for i in line.split()] for line in grid.strip().split('\n')]

maxprod = 0
o = list(range(0, 4))

for x in range(0, SIDE - 3):
    for y in range(0, SIDE - 3):
        p_v = [g[x + i][y] for i in o]
        p_h = [g[x][y + i] for i in o]
        p_d = [g[x + i][y + i] for i in o]
        p_d2 = [g[x + 3 - i][y + i] for i in o]

        maxprod = max(maxprod, prod(p_h), prod(p_v), prod(p_d), prod(p_d2))

print(maxprod)
Пример #7
0
 def __pow__(self, n):
     return common.prod([self]*n)
Пример #8
0
        def getLiveArrays(fname, finfo, memTableFlag=True):

            # first, some helper functions to compute and manipulate access ranges

            def computeAccessRange(ranges, ghost):
                return map(
                    lambda x, y: map(lambda w, z: doSymSubs(w) + z, x, y),
                    ranges, ghost)

            def mySymMin(x, y):
                # HACK: for now, assume ng equals 4 so we can compare access ranges
                if options.flag_warn and not 'ng==4' in options.warned:
                    options.warned.add('ng==4')
                    print >> sys.stderr, 'Warning: assuming ng == 4 for PW execution model'
                x = x.subs('ng', 4)
                y = y.subs('ng', 4)
                testExpr = ask(~Q.positive(x - y), Q.positive(Symbol('ng')))
                if type(testExpr) == type(True):
                    return x if testExpr else y
                else:
                    return parse_expr('min(%s, %s)' % (x, y))

            def mySymMax(x, y):
                # HACK: for now, assume ng equals 4 so we can compare access ranges
                if options.flag_warn and not 'ng==4' in options.warned:
                    options.warned.add('ng==4')
                    print >> sys.stderr, 'WARNING: assuming ng == 4 for PW execution model'
                x = x.subs('ng', 4)
                y = y.subs('ng', 4)
                testExpr = ask(~Q.negative(x - y), Q.positive(Symbol('ng')))
                if type(testExpr) == type(True):
                    return x if testExpr else y
                else:
                    return parse_expr('max(%s, %s)' % (x, y))

            def maxAccessRange(x, y):
                # unpack range and stencil type from inputs
                (x, xt) = x
                (y, yt) = y
                maxRange = map(
                    lambda w, z: (mySymMin(w[0], z[0]), mySymMax(w[1], z[1])),
                    x, y)
                if xt == 'all' or yt == 'all':
                    maxStencilType = 'all'
                elif xt == 'faces' or yt == 'faces':
                    maxStencilType = 'faces'
                elif xt == 'edges' or yt == 'edges':
                    maxStencilType = 'edges'
                else:
                    maxStencilType = 'cell'
                return (maxRange, maxStencilType)

            # if no custom execution order, use default
            numLoops = len(finfo['loops'])
            if 'execorder' in finfo:
                if len(finfo['execorder']) != numLoops or \
                   set(finfo['execorder']) != set(range(0, numLoops)):
                    raise Exception(
                        'custom execution order must be a permutation of range(0, len(loops))'
                    )
            else:
                finfo['execorder'] = range(0, numLoops)

            # gather RW information into table
            table = []
            arrays = {}
            loops_execorder = [finfo['loops'][i] for i in finfo['execorder']]
            for idx, linfo in enumerate(loops_execorder):
                lname = "%s.%03d" % (fname, linfo['linenum'])
                table.append({})
                for ainfo in linfo['arrays']:

                    aname = ainfo['name']
                    accesstype = ainfo['accesstype']
                    copies = ainfo['copies']

                    if accesstype == 'readonly':
                        table[idx][aname] = ('R', copies)
                    elif accesstype == 'writeonly':
                        table[idx][aname] = ('W', copies)
                    elif accesstype == 'readwrite':
                        table[idx][aname] = ('RW', copies)
                    elif accesstype == 'writeread':
                        table[idx][aname] = ('WR', copies)

                    if accesstype == 'readonly':
                        dirty = False
                    else:
                        dirty = True

                    if aname not in arrays:
                        # compute access range and initialize array analysis data
                        accessRange = (computeAccessRange(
                            linfo['ranges'],
                            ainfo['ghost']), ainfo['stenciltype'])
                        arrays[aname] = {'firstidx': idx, 'firstaccess': accesstype, \
                                         'copies': copies, 'accessrange': accessRange}
                    else:
                        # update max access range
                        accessRange = (computeAccessRange(
                            linfo['ranges'],
                            ainfo['ghost']), ainfo['stenciltype'])
                        arrays[aname]['accessrange'] = maxAccessRange(
                            arrays[aname]['accessrange'], accessRange)

                        # do some checks
                        lastidx = arrays[aname]['lastidx']
                        lastaccess = arrays[aname]['lastaccess']
                        dirty = dirty or arrays[aname]['dirty']

                        if arrays[aname][
                                'copies'] != copies and options.flag_warn:
                            print >> sys.stderr, 'Warning: number of copies mismatch: (%s, %s, %s)' % \
                                  (aname, arrays[aname]['copies'], copies)

                        if (lastaccess == 'writeonly' or lastaccess == 'readwrite') and \
                           (accesstype == 'writeonly' or accesstype == 'writeread') and options.flag_warn:
                            print >> sys.stderr, 'Warning: value not used between two writes: (%s, %s.%d, %s)' % \
                                  (aname, fname, loops_execorder[lastidx]['linenum'], lname)

                        # check if array needs to be present in cache since last access
                        if accesstype == 'readonly' or accesstype == 'readwrite':
                            for i in xrange(lastidx + 1, idx):
                                table[i][aname] = ('P', copies)

                    # update array analysis data
                    arrays[aname]['lastidx'] = idx
                    arrays[aname]['lastaccess'] = accesstype
                    arrays[aname]['dirty'] = dirty

            # compute block working set sizes using computed array max access ranges
            for (idx, linfo) in enumerate(loops_execorder):
                linfo['WS']['numBlocks'] = 0
                linfo['WS']['sizeBlocks'] = 0
                # for each array accessed (R/W/RW) or present (P) during this loop
                for aname in table[idx].keys():
                    array = arrays[aname]
                    if 'size' not in array:
                        box = (Symbol('__BoxX__'), Symbol('__BoxY__'),
                               Symbol('__BoxZ__'))
                        acc = map(doSymSubs,
                                  map(rangeSize, array['accessrange'][0]))
                        # check stencil shape to see if we can trim edges and corners from the box
                        if array['accessrange'][1] == 'faces':
                            array['size'] = array['copies'] * (acc[0]*box[1]*box[2] + box[0]*acc[1]*box[2] + \
                                                               box[0]*box[1]*acc[2] - 2*box[0]*box[1]*box[2])
                        elif array['accessrange'][1] == 'edges':
                            array['size'] = array['copies'] * (
                                prod(acc) - prod(map(sub, acc, box)))
                        else:
                            # this works for 'all' or 'cell'
                            array['size'] = array['copies'] * prod(acc)
                        # since this working set is for blocked execution, substitute block sizes for box sizes
                        array['size'] = array['size'].subs((('__BoxX__', '__BlockX__'), \
                                                            ('__BoxY__', '__BlockY__'), \
                                                            ('__BoxZ__', '__BlockZ__')))
                    linfo['WS']['numBlocks'] += array['copies']
                    linfo['WS']['sizeBlocks'] += array['size']

            # initialize bandwidth numbers to 0
            for linfo in loops_execorder:
                linfo['BW']['numBlocks'] = {'R': 0, 'RW': 0, 'W': 0}
                linfo['BW']['sizeBlocks'] = {'R': 0, 'RW': 0, 'W': 0}

            # for each array, figure out if/when it needs to be streamed to/from memory
            for aname in arrays:
                base = string.split(aname, '.')[0]
                firstidx = arrays[aname]['firstidx']
                lastidx = arrays[aname]['lastidx']

                if base in finfo['nonlocal']:
                    streamin = (arrays[aname]['firstaccess'] == 'readonly' or \
                                arrays[aname]['firstaccess'] == 'readwrite')
                    streamout = arrays[aname]['dirty']
                    if streamin:
                        loops_execorder[firstidx]['BW']['numBlocks'][
                            'R'] += arrays[aname]['copies']
                        loops_execorder[firstidx]['BW']['sizeBlocks'][
                            'R'] += arrays[aname]['size']
                        if memTableFlag:
                            for i in xrange(0, firstidx):
                                table[i][aname] = ('P',
                                                   arrays[aname]['copies'])
                    if streamout:
                        if streamin:
                            loops_execorder[lastidx]['BW']['numBlocks'][
                                'RW'] += arrays[aname]['copies']
                            loops_execorder[lastidx]['BW']['sizeBlocks'][
                                'RW'] += arrays[aname]['size']
                            # since we counted a read earlier, don't overcount the extra read
                            loops_execorder[lastidx]['BW']['numBlocks'][
                                'R'] -= arrays[aname]['copies']
                            loops_execorder[lastidx]['BW']['sizeBlocks'][
                                'R'] -= arrays[aname]['size']
                        else:
                            loops_execorder[lastidx]['BW']['numBlocks'][
                                'W'] += arrays[aname]['copies']
                            loops_execorder[lastidx]['BW']['sizeBlocks'][
                                'W'] += arrays[aname]['size']
                        if memTableFlag:
                            for i in xrange(lastidx + 1, len(table)):
                                table[i][aname] = ('P',
                                                   arrays[aname]['copies'])

            finfo['liveness'] = table
Пример #9
0
                #print("Rule: {} Ticket value: {}".format(rule_dict[field], ticket[i]))
                field_dict[field].remove(i)
                break

assigned_fields = {}

while len(assigned_fields) < len(field_dict):
    # Find which field has only a single ticket field index for which it is valid
    assigned_field = None
    for field in field_dict:
        if len(field_dict[field]) == 1:
            assigned_field = field_dict[field][0]
            assigned_fields[field] = assigned_field

    for field in field_dict:
        try:
            field_dict[field].remove(assigned_field)
        except:
            pass

#print(assigned_fields)

my_ticket_values = [int(val) for val in input[1][1].split(",")]
my_relevant_ticket_values = []
for field in assigned_fields:
    if re.match("^departure", field):
        my_relevant_ticket_values.append(
            my_ticket_values[assigned_fields[field]])

print(prod(my_relevant_ticket_values))
Пример #10
0
def num_factors(f1, f2):
    f1 = prime_factorize(f1)
    f2 = prime_factorize(f2)
    return prod(v + 1 for k, v in add_factors(f1, f2).items())
Пример #11
0
def add_factors(f1, f2):
    keys = set(f1) | set(f2)
    factors = {}
    for k in keys:
        factors[k] = f1.get(k, 0) + f2.get(k, 0)
    return factors


@cached
def prime_factorize(n):
    global sieve
    if n == 1:
        return {}
    for p in sieve.sift(int(n**0.5)):
        if n % p == 0:
            return add_factors({p: 1}, prime_factorize(n // p))
    return {n: 1}


def num_factors(f1, f2):
    f1 = prime_factorize(f1)
    f2 = prime_factorize(f2)
    return prod(v + 1 for k, v in add_factors(f1, f2).items())


for i in itertools.count(1):
    factors = [(j / 2 if j % 2 == 0 else j) for j in i, i + 1]
    if num_factors(*factors) > 500:
        print prod(factors)
        break
Пример #12
0
# Move right 20 times and down 20 times
# Number of routes is arrangements of 'r'*20 + 'd'*20
# 40!/(20! 20!)

from common import prod

print prod(range(21, 41)) / prod(range(1, 21))
Пример #13
0
def num_factors(f1, f2):
	f1 = prime_factorize(f1)
	f2 = prime_factorize(f2)
	return prod(v+1 for k,v in add_factors(f1, f2).items())
Пример #14
0
sieve = Sieve()

def add_factors(f1, f2):
	keys = set(f1) | set(f2)
	factors = {}
	for k in keys:
		factors[k] = f1.get(k,0) + f2.get(k,0)
	return factors

@cached
def prime_factorize(n):
	global sieve;
	if n == 1:
		return {}
	for p in sieve.sift(int(n**0.5)):
		if n%p == 0:
			return add_factors({p:1},prime_factorize(n//p))
	return {n:1}
	
def num_factors(f1, f2):
	f1 = prime_factorize(f1)
	f2 = prime_factorize(f2)
	return prod(v+1 for k,v in add_factors(f1, f2).items())

for i in itertools.count(1):
	factors = [(j/2 if j%2 == 0 else j) for j in i,i+1]
	if num_factors(*factors) > 500:
		print prod(factors)
		break
Пример #15
0
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48\
'''

numbers = [map(int, s.split()) for s in numbers.split('\n')]
n = 20
l = 4
max_prod = MaxAccumulator(0)

# search across and up/down
for i in range(n):
	for j in range(n-l):
		max_prod.update(
			prod(numbers[i][j:j+l])
		)
		max_prod.update(
			prod(lst[i] for lst in numbers[j:j+l])
		)

# search diagonals
for i in range(n-l-1):
	for j in range(n-l-1):
		max_prod.update(
			prod(numbers[i+x][j+x] for x in range(l))
		)

for i in range(l-1, n):
	for j in range(n-l-1):
		max_prod.update(
Пример #16
0
#!/usr/bin/env python

from itertools import count
from common import prod

lens = [1, 10, 100, 1000, 10000, 100000, 1000000]
MAX = max(lens)
s = "0"

for a in count(1):
    s += str(a)
    if len(s) > MAX:
        break

p = prod(int(s[a]) for a in lens)
print(p)
Пример #17
0
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48\
'''

numbers = [map(int, s.split()) for s in numbers.split('\n')]
n = 20
l = 4
max_prod = MaxAccumulator(0)

# search across and up/down
for i in range(n):
    for j in range(n - l):
        max_prod.update(prod(numbers[i][j:j + l]))
        max_prod.update(prod(lst[i] for lst in numbers[j:j + l]))

# search diagonals
for i in range(n - l - 1):
    for j in range(n - l - 1):
        max_prod.update(prod(numbers[i + x][j + x] for x in range(l)))

for i in range(l - 1, n):
    for j in range(n - l - 1):
        max_prod.update(prod(numbers[i - x][j + x] for x in range(l)))

print max_prod.max_val
Пример #18
0
        self.domain = len(self.grid[0])
        self.range = len(self.grid)

    def lookup(self, x, y):
        if isinstance(x, tuple):
            x, y = x

        return self.grid[y % self.range][x % self.domain]


m = RepeatMap(data)
path = [m.lookup(3 * i, i) for i in range(m.range)]
len_path = len(list(filter(lambda v: v == '#', path)))

#print(len_path)


# Day two
def trees_on_path(m, slope):
    path = [
        m.lookup(slope[0] * i, slope[1] * i)
        for i in range(0, ceil(m.range / slope[1]))
    ]
    return len(list(filter(lambda v: v == '#', path)))


print(
    prod(
        trees_on_path(m, slope)
        for slope in [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]))
Пример #19
0
def congruence_system(system):
    """Chinese remainder theorem, constructionist expansion"""
    N = prod(v[1] for v in system)
    return sum(a * N // n * invmod(N // n, n) for a, n in system) % N
Пример #20
0
from functools import partial, reduce
from itertools import combinations
from pprint import pprint

from common import drop, partitionby, prod, read_input

import numpy as np

data = [int(l) for l in read_input('data.input.day10')]
data = [0] + data + [max(data) + 3]
data = np.sort(np.array(data))

diffs = data[1:] - data[:-1]
#print(sum(diffs == 1) * sum(diffs == 3))

# part 2

f = lambda v: v == 1
ld = list(map(len, partitionby(f, diffs)))

# okay, so i use a diff map which has 1 less member per group of adapters, that's why we have "- 1"
# instead of "- 2", for each set of adapters we have the varying sequences we can turn on/off

# [(0, 1, 2, 3, 4), (0, 1, 2, 4), (0, 1, 4), (0, 1, 3, 4), (0, 3, 4), (0, 2, 3, 4)]
# notice there are (length - 2) * 2 choices.
# but then also the additional case: (0, 2, 4) and this occurs once for every 5 numbers, but every 4 diffs!

l = [(v - 1) * 2 + v // 4 for v in ld if v > 1]

print(prod(l))