class BOAST::Procedure

@!parse module Functors; functorize Procedure; end

Constants

ANNOTATIONS

Attributes

constants[R]
headers[R]
locals[R]
name[R]
parameters[R]
properties[R]

Public Class Methods

new(name, parameters=[], properties={}, &block) click to toggle source

Creates a new Procedure @param [#to_s] name Procedure identifier @param [Array<Variable>] parameters list of the procedure parameters. @param [Hash] properties set of named properties for the Procedure. @option properties [Array<Variables>] :constants list of constant variables that are used in the Procedure. (see parameter in Fortran). @option properties [Array<#to_s>] :headers list of headers that need to be included in order to compile the Procedure @option properties [Variable] :return a Variable that will be returned. Procedure becomes a function, return type is the same as the returned variable. The variable will be declared at the start of the procedure. @option properties [Procedure] :functions sub functions used by this Procedure (FORTRAN return type of functions are problematic)

# File lib/BOAST/Language/Procedure.rb, line 26
def initialize(name, parameters=[], properties={}, &block)
  @name = name
  @parameters = parameters
  @constants = properties[:constants]
  @constants = [] unless @constants
  @locals = properties[:locals]
  @locals = [] unless @locals
  @block = block
  @properties = properties
  @headers = properties[:headers]
  @headers = [] unless @headers
end

Public Instance Methods

boast_header(lang=C) click to toggle source

@private

# File lib/BOAST/Language/Procedure.rb, line 40
def boast_header(lang=C)
  s = boast_header_s(lang)
  s << ";\n"
  output.print s
  return self
end
call(*parameters) click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 47
def call(*parameters)
  prefix = ""
  prefix << "call " if lang==FORTRAN and @properties[:return].nil?
  f = FuncCall::new(@name, *parameters, :return => @properties[:return] )
  f.prefix = prefix
  return f
end
ckernel(* args) click to toggle source

Returns a {CKernel} with the Procedure as entry point.

# File lib/BOAST/Language/Procedure.rb, line 61
def ckernel(* args)
  old_output = output
  k = CKernel::new(* args)
  k.procedure = self
  self.pr
  set_output( old_output )
  return k
end
close() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 55
def close
  return close_fortran if lang==FORTRAN
  return close_c if [C, CL, CUDA].include?( lang )
end
decl() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 79
def decl
  return decl_fortran if lang==FORTRAN
  return decl_c if [C, CL, CUDA].include?( lang )
end
open() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 84
def open
  return open_fortran if lang==FORTRAN
  return open_c if [C, CL, CUDA].include?( lang )
end
pr() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 70
def pr
  open
  if @block then
    @block.call
    close
  end
  return self
end
to_s() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 89
def to_s
  return decl_c_s if [C, CL, CUDA].include?( lang )
  return to_s_fortran if lang==FORTRAN
end

Protected Instance Methods

fortran_type() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 96
def fortran_type
  raise "No return type for procedure!" unless @properties[:return]
  output.puts indent + "#{@properties[:return].type.decl} :: #{@name}"
end

Private Instance Methods

boast_header_s( lang=C ) click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 271
def boast_header_s( lang=C )
  s = ""
  headers.each { |h|
    s << "#include <#{h}>\n"
  }
  if lang == CL then
    s << "__kernel "
    wgs = @properties[:reqd_work_group_size]
    if wgs then
      s << "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
    end
  end
  trailer = ""
  trailer << "_" if lang == FORTRAN
  trailer << "_wrapper" if lang == CUDA
  if @properties[:return] then
    s << "#{@properties[:return].type.decl} "
  elsif lang == CUDA
    s << "unsigned long long int "
  else
    s << "void "
  end
  s << "#{@name}#{trailer}("
  if @parameters.first then
    s << @parameters.first.boast_header(lang)
    @parameters[1..-1].each { |p|
      s << ", "
      s << p.boast_header(lang)
    }
  end
  if lang == CUDA then
    s << ", " if parameters.first
    s << "size_t *_boast_block_number, size_t *_boast_block_size, int _boast_repeat"
  end
  s << ")"
  return s
end
close_c() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 248
def close_c
  s = ""
  s << indent + "return #{@properties[:return]};\n" if @properties[:return]
  decrement_indent_level
  s << indent + "}"
  output.puts s
  return self
end
close_fortran() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 257
def close_fortran
  s = ""
  if @properties[:return] then
    s << indent + "#{@name} = #{@properties[:return]}\n"
    decrement_indent_level
    s << indent + "END FUNCTION #{@name}"
  else
    decrement_indent_level
    s << indent + "END SUBROUTINE #{@name}"
  end
  output.puts s
  return self
end
decl_c() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 164
def decl_c
  s = indent + decl_c_s + ";"
  output.puts s
  return self
end
decl_c_s() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 113
def decl_c_s
  s = ""
  if lang == CL then
    if @properties[:local] then
      s << "#if __OPENCL_C_VERSION__ && __OPENCL_C_VERSION__ >= 120\n"
      s << "static\n"
      s << "#endif\n"
    else
      s << "__kernel "
      wgs = @properties[:reqd_work_group_size]
      if wgs then
        s << "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
      end
    end
  elsif lang == CUDA then
    if @properties[:local] then
      s << "static __device__ "
    else
      s << "__global__ "
      wgs = @properties[:reqd_work_group_size]
      if wgs then
        s << "__launch_bounds__(#{wgs[0]}*#{wgs[1]}*#{wgs[2]}) "
      end
    end
  elsif lang == C then
    if @properties[:local] then
      s << "static "
    end
    if @properties[:inline] then
      s << "inline "
    end
  end
  if @properties[:qualifiers] then
    s << "#{@properties[:qualifiers]} "
  end
  if @properties[:return] then
    s << "#{@properties[:return].type.decl} "
  else
    s << "void "
  end
  s << "#{@name}("
  if @parameters.first then
    s << @parameters.first.send(:decl_c_s, @properties[:local])
    @parameters[1..-1].each { |p|
      s << ", "+p.send(:decl_c_s, @properties[:local])
    }
  end
  s << ")"
  return s
end
decl_fortran() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 103
def decl_fortran
  output.puts indent + "INTERFACE"
  increment_indent_level
  open_fortran
  close_fortran
  decrement_indent_level
  output.puts indent + "END INTERFACE"
  return self
end
open_c() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 182
def open_c
  s = indent + decl_c_s + "{"
  output.puts s
  increment_indent_level
  @constants.each { |c|
    BOAST::decl c
  }
  if lang == C then
    @parameters.each { |p|
      align = p.align
      BOAST::pr align if align and not p.send(:__attr_align?)
    }
  end
  if @properties[:return] then
    BOAST::decl @properties[:return]
  end
  @locals.each { |l|
    BOAST::decl l
    align = l.align
    BOAST::pr align if align and not l.send(:__attr_align?)
  }
  return self
end
open_fortran() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 206
    def open_fortran
      s = indent + to_s_fortran
      s << "\n"
      increment_indent_level
      tmp_buff = StringIO::new
      push_env( :output => tmp_buff ) {
        @parameters.each { |p|
          p.type.define if p.type.kind_of? CStruct
        }
      }
      tmp_buff.rewind
      s << tmp_buff.read
      s << indent + "integer, parameter :: wp=kind(1.0d0)"
      output.puts s
      @constants.each { |c|
        BOAST::decl c
      }
      @parameters.each { |p|
        BOAST::decl p
#        align = p.align
#        BOAST::pr align if align
      }
      @locals.each { |l|
        BOAST::decl l
#        align = l.align
#        BOAST::pr align if align
      }
      if @properties[:functions] then
        @properties[:functions].each { |f|
          f.fortran_type
        }
      end
      if @properties[:return] then
        BOAST::decl @properties[:return]
      end
      (@parameters + @locals).each { |v|
        align = v.align
        BOAST::pr align if align and not v.send(:__attr_align?)
      }
      return self
    end
to_s_fortran() click to toggle source
# File lib/BOAST/Language/Procedure.rb, line 170
def to_s_fortran
  s = ""
  if @properties[:return] then
    s << "#{@properties[:return].type.decl} FUNCTION "
  else
    s << "SUBROUTINE "
  end
  s << "#{@name}("
  s << @parameters.collect(&:name).join(", ")
  s << ")"
end