1*5f39d1b3SJooyung Han# Copyright 2016 The Gemmlowp Authors. All rights reserved. 2*5f39d1b3SJooyung Han# 3*5f39d1b3SJooyung Han# Licensed under the Apache License, Version 2.0 (the "License"); 4*5f39d1b3SJooyung Han# you may not use this file except in compliance with the License. 5*5f39d1b3SJooyung Han# You may obtain a copy of the License at 6*5f39d1b3SJooyung Han# 7*5f39d1b3SJooyung Han# http://www.apache.org/licenses/LICENSE-2.0 8*5f39d1b3SJooyung Han# 9*5f39d1b3SJooyung Han# Unless required by applicable law or agreed to in writing, software 10*5f39d1b3SJooyung Han# distributed under the License is distributed on an "AS IS" BASIS, 11*5f39d1b3SJooyung Han# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*5f39d1b3SJooyung Han# See the License for the specific language governing permissions and 13*5f39d1b3SJooyung Han# limitations under the License. 14*5f39d1b3SJooyung Han""".""" 15*5f39d1b3SJooyung Hanimport collections 16*5f39d1b3SJooyung Han 17*5f39d1b3SJooyung Han_HEADER_COPYRIGHT = ( 18*5f39d1b3SJooyung Han '''// Copyright 2016 The Gemmlowp Authors. All Rights Reserved. 19*5f39d1b3SJooyung Han// 20*5f39d1b3SJooyung Han// Licensed under the Apache License, Version 2.0 (the "License"); 21*5f39d1b3SJooyung Han// you may not use this file except in compliance with the License. 22*5f39d1b3SJooyung Han// You may obtain a copy of the License at 23*5f39d1b3SJooyung Han// 24*5f39d1b3SJooyung Han// http://www.apache.org/licenses/LICENSE-2.0 25*5f39d1b3SJooyung Han// 26*5f39d1b3SJooyung Han// Unless required by applicable law or agreed to in writing, software 27*5f39d1b3SJooyung Han// distributed under the License is distributed on an "AS IS" BASIS, 28*5f39d1b3SJooyung Han// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29*5f39d1b3SJooyung Han// See the License for the specific language governing permissions and 30*5f39d1b3SJooyung Han// limitations under the License. 31*5f39d1b3SJooyung Han''') 32*5f39d1b3SJooyung Han 33*5f39d1b3SJooyung Han 34*5f39d1b3SJooyung Handef GenerateHeader(cc, header_name, preprocessor_directive): 35*5f39d1b3SJooyung Han cc.EmitCodeNoSemicolon(_HEADER_COPYRIGHT) 36*5f39d1b3SJooyung Han cc.EmitHeaderBegin(header_name) 37*5f39d1b3SJooyung Han 38*5f39d1b3SJooyung Han cc.EmitPreprocessor1('ifdef', preprocessor_directive) 39*5f39d1b3SJooyung Han cc.EmitNewline() 40*5f39d1b3SJooyung Han 41*5f39d1b3SJooyung Han cc.EmitInclude('<cassert>') 42*5f39d1b3SJooyung Han cc.EmitInclude('<cstdint>') 43*5f39d1b3SJooyung Han cc.EmitNewline() 44*5f39d1b3SJooyung Han 45*5f39d1b3SJooyung Han 46*5f39d1b3SJooyung Handef GenerateFooter(cc, message): 47*5f39d1b3SJooyung Han cc.EmitPreprocessor('else') 48*5f39d1b3SJooyung Han cc.EmitPreprocessor1('warning', '"%s"' % message) 49*5f39d1b3SJooyung Han cc.EmitPreprocessor('endif') 50*5f39d1b3SJooyung Han cc.EmitNewline() 51*5f39d1b3SJooyung Han cc.EmitHeaderEnd() 52*5f39d1b3SJooyung Han 53*5f39d1b3SJooyung Han 54*5f39d1b3SJooyung Handef GenerateDebugLog(cc, message): 55*5f39d1b3SJooyung Han cc.EmitPreprocessor1('ifdef', 'DEBUG') 56*5f39d1b3SJooyung Han cc.EmitPreprocessor1('ifdef', 'DEBUG_METAGEMM_VERBOSE') 57*5f39d1b3SJooyung Han cc.EmitCode('std::cout << __FILE__ << \"(\" << __LINE__ << \") %s\" ' 58*5f39d1b3SJooyung Han '<< std::endl << std::flush' % message) 59*5f39d1b3SJooyung Han cc.EmitPreprocessor('endif') 60*5f39d1b3SJooyung Han cc.EmitPreprocessor('endif') 61*5f39d1b3SJooyung Han 62*5f39d1b3SJooyung Han 63*5f39d1b3SJooyung Handef _TemplateName(base, params): 64*5f39d1b3SJooyung Han return '%s<%s>' % (base, ', '.join(map(str, params))) 65*5f39d1b3SJooyung Han 66*5f39d1b3SJooyung Han 67*5f39d1b3SJooyung Hanclass StreamGenerator(object): 68*5f39d1b3SJooyung Han """.""" 69*5f39d1b3SJooyung Han 70*5f39d1b3SJooyung Han def __init__(self, emitter, name): 71*5f39d1b3SJooyung Han self.name = name 72*5f39d1b3SJooyung Han self.emitter = emitter 73*5f39d1b3SJooyung Han 74*5f39d1b3SJooyung Han def SpecializeStream(self, in_type, lanes_count, pack_size, leftovers): 75*5f39d1b3SJooyung Han if isinstance(getattr(self, 'EmitPack', None), collections.Callable): 76*5f39d1b3SJooyung Han template_params = [in_type, lanes_count, pack_size, leftovers, self.name] 77*5f39d1b3SJooyung Han self.emitter.EmitMemberFunctionBegin( 78*5f39d1b3SJooyung Han 'Stream', [], template_params, 'Pack', 79*5f39d1b3SJooyung Han [['const %s*' % in_type, 'in'], ['const %s&' % self.name, 'params'], 80*5f39d1b3SJooyung Han ['%s*' % in_type, 'out']], 'inline void') 81*5f39d1b3SJooyung Han GenerateDebugLog(self.emitter, 82*5f39d1b3SJooyung Han '%s::Pack()' % _TemplateName(self.name, template_params)) 83*5f39d1b3SJooyung Han self.EmitPack(in_type, lanes_count, pack_size, leftovers) 84*5f39d1b3SJooyung Han self.emitter.EmitFunctionEnd() 85*5f39d1b3SJooyung Han 86*5f39d1b3SJooyung Han 87*5f39d1b3SJooyung Hanclass MulKernelGenerator(object): 88*5f39d1b3SJooyung Han """.""" 89*5f39d1b3SJooyung Han 90*5f39d1b3SJooyung Han def __init__(self, emitter, kernel_name, output_stream_name): 91*5f39d1b3SJooyung Han self.kernel_name = kernel_name 92*5f39d1b3SJooyung Han self.output_stream_name = output_stream_name 93*5f39d1b3SJooyung Han self.emitter = emitter 94*5f39d1b3SJooyung Han 95*5f39d1b3SJooyung Han def SpecializeMulKernel(self, in_type, out_type, kernel_m, kernel_n, 96*5f39d1b3SJooyung Han pack_size): 97*5f39d1b3SJooyung Han """Generates the kernel wrapped in a MulKernel template specialization.""" 98*5f39d1b3SJooyung Han template_params = [ 99*5f39d1b3SJooyung Han in_type, out_type, self.kernel_name, self.output_stream_name, kernel_m, 100*5f39d1b3SJooyung Han kernel_n, pack_size 101*5f39d1b3SJooyung Han ] 102*5f39d1b3SJooyung Han self.emitter.EmitMemberFunctionBegin( 103*5f39d1b3SJooyung Han 'MulKernel', [], template_params, 'Multiply', 104*5f39d1b3SJooyung Han [['const %s*' % in_type, 'lhs'], ['const %s*' % in_type, 'rhs'], [ 105*5f39d1b3SJooyung Han 'const FusedKernelParams<%s, %s>&' % (self.kernel_name, 106*5f39d1b3SJooyung Han self.output_stream_name), 107*5f39d1b3SJooyung Han 'params' 108*5f39d1b3SJooyung Han ], ['%s*' % out_type, 'result']], 'inline void') 109*5f39d1b3SJooyung Han GenerateDebugLog(self.emitter, '%s::Multiply()' % 110*5f39d1b3SJooyung Han _TemplateName(self.kernel_name + self.output_stream_name, 111*5f39d1b3SJooyung Han template_params)) 112*5f39d1b3SJooyung Han self.EmitMultiply(in_type, out_type, kernel_m, kernel_n, pack_size) 113*5f39d1b3SJooyung Han self.emitter.EmitFunctionEnd() 114*5f39d1b3SJooyung Han 115*5f39d1b3SJooyung Han 116*5f39d1b3SJooyung Hanclass Transform1DKernelGenerator(object): 117*5f39d1b3SJooyung Han """.""" 118*5f39d1b3SJooyung Han 119*5f39d1b3SJooyung Han def __init__(self, emitter, kernel_name): 120*5f39d1b3SJooyung Han self.kernel_name = kernel_name 121*5f39d1b3SJooyung Han self.emitter = emitter 122*5f39d1b3SJooyung Han 123*5f39d1b3SJooyung Han def SpecializeTransform1DKernel(self, in_type, out_type, kernel_size, 124*5f39d1b3SJooyung Han leftovers): 125*5f39d1b3SJooyung Han """Generates the kernel wrapped in a Transform1DKernel specialization.""" 126*5f39d1b3SJooyung Han template_params = [ 127*5f39d1b3SJooyung Han in_type, out_type, self.kernel_name, kernel_size, leftovers 128*5f39d1b3SJooyung Han ] 129*5f39d1b3SJooyung Han self.emitter.EmitMemberFunctionBegin( 130*5f39d1b3SJooyung Han 'Transform1DKernel', [], template_params, 'Transform', 131*5f39d1b3SJooyung Han [['const %s*' % in_type, 'input'], 132*5f39d1b3SJooyung Han ['const %s&' % self.kernel_name, 'params'], 133*5f39d1b3SJooyung Han ['%s*' % out_type, 'output']], 'inline void') 134*5f39d1b3SJooyung Han GenerateDebugLog(self.emitter, '%s::Transform()' % 135*5f39d1b3SJooyung Han _TemplateName(self.kernel_name, template_params)) 136*5f39d1b3SJooyung Han self.EmitTransform(in_type, out_type, kernel_size, leftovers) 137*5f39d1b3SJooyung Han self.emitter.EmitFunctionEnd() 138