pytorch/scripts/xcode_build.rb
Edward Yang ec30d9028a Split libtorch.so back into libtorch_{cpu,cuda,hip} (#29731)
Summary:
Pull Request resolved: https://github.com/pytorch/pytorch/pull/29731

The new structure is that libtorch_cpu contains the bulk of our
code, and libtorch depends on libtorch_cpu and libtorch_cuda.

Some subtleties about the patch:
- There were a few functions that crossed CPU-CUDA boundary without API macros. I just added them, easy enough. An inverse situation was aten/src/THC/THCTensorRandom.cu where we weren't supposed to put API macros directly in a cpp file.
- DispatchStub wasn't getting all of its symbols related to static members on DispatchStub exported properly. I tried a few fixes but in the end I just moved everyone off using DispatchStub to dispatch CUDA/HIP (so they just use normal dispatch for those cases.) Additionally, there were some mistakes where people incorrectly were failing to actually import the declaration of the dispatch stub, so added includes for those cases.
- torch/csrc/cuda/nccl.cpp was added to the wrong list of SRCS, now fixed (this didn't matter before because previously they were all in the same library)
- The dummy file for libtorch was brought back from the dead; it was previously deleted in #20774
- In an initial version of the patch, I forgot to make torch_cuda explicitly depend on torch_cpu. This lead to some very odd errors, most notably "bin/blob_test: hidden symbol `_ZNK6google8protobuf5Arena17OnArenaAllocationEPKSt9type_infom' in lib/l
ibprotobuf.a(arena.cc.o) is referenced by DSO"
- A number of places in Android/iOS builds have to add torch_cuda explicitly as a library, as they do not have transitive dependency calculation working correctly. This situation also happens with custom C++ extensions.
- There's a ROCm compiler bug where extern "C" on functions is not respected. There's a little workaround to handle this.
- Because I was too lazy to check if HIPify was converting TORCH_CUDA_API into TORCH_HIP_API, I just made it so HIP build also triggers the TORCH_CUDA_API macro. Eventually, we should translate and keep the nature of TORCH_CUDA_API constant in all cases.

Fixes #27215 (as our libraries are smaller), and executes on
part of the plan in #29235.

Signed-off-by: Edward Z. Yang <ezyang@fb.com>

Test Plan: Imported from OSS

Differential Revision: D18632773

Pulled By: ezyang

fbshipit-source-id: ea717c81e0d7554ede1dc404108603455a81da82
2019-11-21 11:27:33 -08:00

80 lines
2.7 KiB
Ruby

require 'optparse'
require 'xcodeproj'
options = {}
option_parser = OptionParser.new do |opts|
opts.banner = 'Tools for building PyTorch iOS framework on MacOS'
opts.on('-i', '--install_path ', 'path to the cmake install folder') { |value|
options[:install] = value
}
opts.on('-x', '--xcodeproj_path ', 'path to the XCode project file') { |value|
options[:xcodeproj] = value
}
opts.on('-p', '--platform ', 'platform for the current build, OS or SIMULATOR') { |value|
options[:platform] = value
}
opts.on('-c', '--provisioning_profile ', 'provisioning profile for code signing') { |value|
options[:profile] = value
}
opts.on('-t', '--team_id ', 'developemnt team ID') { |value|
options[:team_id] = value
}
end.parse!
puts options.inspect
install_path = File.expand_path(options[:install])
if not Dir.exist? (install_path)
raise "path don't exist:#{install_path}!"
end
xcodeproj_path = File.expand_path(options[:xcodeproj])
if not File.exist? (xcodeproj_path)
raise "path don't exist:#{xcodeproj_path}!"
end
project = Xcodeproj::Project.open(xcodeproj_path)
target = project.targets.first #TestApp
header_search_path = ['$(inherited)', "#{install_path}/include"]
libraries_search_path = ['$(inherited)', "#{install_path}/lib"]
other_linker_flags = ['$(inherited)', "-all_load"]
target.build_configurations.each do |config|
config.build_settings['HEADER_SEARCH_PATHS'] = header_search_path
config.build_settings['LIBRARY_SEARCH_PATHS'] = libraries_search_path
config.build_settings['OTHER_LDFLAGS'] = other_linker_flags
config.build_settings['ENABLE_BITCODE'] = 'No'
dev_team_id = options[:team_id]
if not dev_team_id
raise "Please sepecify a valid development team id for code signing"
end
config.build_settings['DEVELOPMENT_TEAM'] = dev_team_id
end
# link static libraries
target.frameworks_build_phases.clear
libs = ['libc10.a', 'libclog.a', 'libnnpack.a', 'libeigen_blas.a', 'libcpuinfo.a', 'libpytorch_qnnpack.a', 'libtorch_cpu.a', 'libtorch.a']
for lib in libs do
path = "#{install_path}/lib/#{lib}"
if File.exist?(path)
libref = project.frameworks_group.new_file(path)
target.frameworks_build_phases.add_file_reference(libref)
end
end
project.save
sdk = nil
if options[:platform] == 'SIMULATOR'
sdk = 'iphonesimulator'
elsif options[:platform] == 'OS'
sdk = 'iphoneos'
else
raise "unsupported platform #{options[:platform]}"
end
profile = options[:profile]
if not profile
raise "no provisioning profile found!"
end
# run xcodebuild
exec "xcodebuild clean build -project #{xcodeproj_path} -target #{target.name} -sdk #{sdk} -configuration Release PROVISIONING_PROFILE_SPECIFIER=#{profile}"