@@ -1909,23 +1909,90 @@ pi_result cuda_piProgramGetInfo(pi_program program, pi_program_info param_name,
1909
1909
return {};
1910
1910
}
1911
1911
1912
- pi_result cuda_piProgramLink ( // TODO: change interface to return error code
1912
+ pi_result cuda_piProgramLink (
1913
1913
pi_context context, pi_uint32 num_devices, const pi_device *device_list,
1914
1914
const char *options, pi_uint32 num_input_programs,
1915
1915
const pi_program *input_programs,
1916
1916
void (*pfn_notify)(pi_program program, void *user_data), void *user_data,
1917
1917
pi_program *ret_program) {
1918
- cl::sycl::detail::pi::die (" cuda_piProgramLink not implemented" );
1919
- return {};
1918
+
1919
+ assert (ret_program != nullptr );
1920
+ assert (num_devices == 1 || num_devices == 0 );
1921
+ assert (device_list != nullptr || num_devices == 0 );
1922
+ assert (pfn_notify == nullptr );
1923
+ assert (user_data == nullptr );
1924
+ pi_result retError = PI_SUCCESS;
1925
+
1926
+ try {
1927
+ ScopedContext active (context);
1928
+
1929
+ CUlinkState state;
1930
+ std::unique_ptr<_pi_program> retProgram{new _pi_program{context}};
1931
+
1932
+ // TODO: Linker options
1933
+ retError = PI_CHECK_ERROR (cuLinkCreate (0 , nullptr , nullptr , &state));
1934
+ try {
1935
+ for (size_t i; i < num_input_programs; ++i) {
1936
+ pi_program program = input_programs[i];
1937
+ std::vector<char > source (program->source_ ,
1938
+ program->source_ + program->sourceLength_ );
1939
+ retError = PI_CHECK_ERROR (cuLinkAddData (
1940
+ state, CU_JIT_INPUT_PTX, source.data (), program->sourceLength_ ,
1941
+ nullptr , 0 , nullptr , nullptr ));
1942
+ }
1943
+ void *cubin = nullptr ;
1944
+ size_t cubinSize = 0 ;
1945
+ retError = PI_CHECK_ERROR (cuLinkComplete (state, &cubin, &cubinSize));
1946
+
1947
+ retError = retProgram->create_from_source (
1948
+ static_cast <const char *>(cubin), cubinSize);
1949
+
1950
+ if (retError != PI_SUCCESS) {
1951
+ return retError;
1952
+ }
1953
+
1954
+ retError = retProgram->build_program (options);
1955
+
1956
+ if (retError != PI_SUCCESS) {
1957
+ return retError;
1958
+ }
1959
+ } catch (...) {
1960
+ // Upon error attempt cleanup
1961
+ PI_CHECK_ERROR (cuLinkDestroy (state));
1962
+ throw ;
1963
+ }
1964
+
1965
+ retError = PI_CHECK_ERROR (cuLinkDestroy (state));
1966
+ *ret_program = retProgram.release ();
1967
+
1968
+ } catch (pi_result err) {
1969
+ retError = err;
1970
+ }
1971
+ return retError;
1920
1972
}
1921
1973
1922
1974
pi_result cuda_piProgramCompile (
1923
1975
pi_program program, pi_uint32 num_devices, const pi_device *device_list,
1924
1976
const char *options, pi_uint32 num_input_headers,
1925
1977
const pi_program *input_headers, const char **header_include_names,
1926
1978
void (*pfn_notify)(pi_program program, void *user_data), void *user_data) {
1927
- cl::sycl::detail::pi::die (" cuda_piProgramCompile not implemented" );
1928
- return {};
1979
+ assert (program != nullptr );
1980
+ assert (num_devices == 1 || num_devices == 0 );
1981
+ assert (device_list != nullptr || num_devices == 0 );
1982
+ assert (pfn_notify == nullptr );
1983
+ assert (user_data == nullptr );
1984
+ assert (num_input_headers == 0 );
1985
+ pi_result retError = PI_SUCCESS;
1986
+
1987
+ try {
1988
+ ScopedContext active (program->get_context ());
1989
+
1990
+ program->build_program (options);
1991
+
1992
+ } catch (pi_result err) {
1993
+ retError = err;
1994
+ }
1995
+ return retError;
1929
1996
}
1930
1997
1931
1998
pi_result cuda_piProgramGetBuildInfo (pi_program program, pi_device device,
0 commit comments