@@ -68,10 +68,12 @@ namespace caspar {
6868{{ solver.struct_name }}::{{ solver.struct_name }}(
6969 const SolverParams<double > ¶ms,
7070 {% for thing in solver .size_contributors %}
71- size_t {{num_arg_key(thing)}}{{ ", " if not loop.last else "" }}
71+ size_t {{num_arg_key(thing)}}{{ ", " }}
7272 {% endfor %}
73+ int device_id
7374 )
7475 : params_(params),
76+ device_id_(device_id),
7577 {% for thing in solver .size_contributors %}
7678 {{num_key(thing)}}({{num_arg_key(thing)}}),
7779 {{num_max_key(thing)}}({{num_arg_key(thing)}}){{ ", " if not loop.last else "" }}
@@ -85,6 +87,20 @@ namespace caspar {
8587 throw std::runtime_error("params.diag_init must be positive");
8688 }
8789 allocation_size_ = get_nbytes();
90+
91+ if (device_id_ < 0) {
92+ throw std::runtime_error("Invalid CUDA device id: " + std::to_string(device_id_));
93+ }
94+ if (device_id_ != 0) {
95+ int deviceCount;
96+ cudaGetDeviceCount(&deviceCount);
97+ if (deviceCount <= device_id_) {
98+ throw std::runtime_error("CUDA detected " + std::to_string(deviceCount) +
99+ " devices, but device " + std::to_string(device_id_) +
100+ " was requested (0-indexed)");
101+ }
102+ }
103+ cudaSetDevice(device_id_);
88104 cudaMalloc(&origin_ptr_, allocation_size_);
89105
90106 size_t offset = 0;
@@ -97,6 +113,7 @@ namespace caspar {
97113}
98114
99115{{ solver.struct_name }}::~{{ solver.struct_name }}(){
116+ cudaSetDevice(device_id_);
100117 cudaFree(origin_ptr_);
101118}
102119
@@ -110,6 +127,7 @@ size_t {{ solver.struct_name }}::get_allocation_size(){
110127
111128
112129SolveResult {{ solver.struct_name }}::solve(bool print_progress, bool verbose_logging) {
130+ cudaSetDevice(device_id_);
113131 SolveResult result;
114132 result.exit_reason = ExitReason::MAX_ITERATIONS;
115133 {{solver.linear_t}} score_best;
@@ -634,6 +652,7 @@ void {{ solver.struct_name }}::finish_indices() {
634652
635653{% for nodetype in solver.node_types %}
636654void {{ solver.struct_name }}::Set{{nodetype.__name__}}Num(const size_t num) {
655+ cudaSetDevice(device_id_);
637656 if (num > {{num_max_key(nodetype)}}) {
638657 throw std::runtime_error(std::to_string(num) + " > {{num_max_key(nodetype)}}");
639658 }
@@ -642,6 +661,7 @@ void {{ solver.struct_name }}::Set{{nodetype.__name__}}Num(const size_t num) {
642661
643662void {{ solver.struct_name }}::Set{{nodetype.__name__}}NodesFromStackedHost(
644663 const {{solver.storage_t}}* const data, const size_t offset, const size_t num) {
664+ cudaSetDevice(device_id_);
645665 if (offset + num > {{num_key(nodetype)}}){
646666 throw std::runtime_error(std::to_string(offset + num) + " > {{num_key(nodetype)}}");
647667 }
@@ -654,6 +674,7 @@ void {{ solver.struct_name }}::Set{{nodetype.__name__}}NodesFromStackedHost(
654674
655675void {{ solver.struct_name }}::Set{{nodetype.__name__}}NodesFromStackedDevice(
656676 const {{solver.storage_t}}* const data, const size_t offset, const size_t num) {
677+ cudaSetDevice(device_id_);
657678 if (offset + num > {{num_key(nodetype)}}){
658679 throw std::runtime_error(std::to_string(offset + num) + " > {{num_key(nodetype)}}");
659680 }
@@ -663,6 +684,7 @@ void {{ solver.struct_name }}::Set{{nodetype.__name__}}NodesFromStackedDevice(
663684
664685void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedHost(
665686 {{solver.storage_t}}* const data, const size_t offset, const size_t num) {
687+ cudaSetDevice(device_id_);
666688 if (offset + num > {{num_key(nodetype)}}){
667689 throw std::runtime_error(std::to_string(offset + num) + " > {{num_key(nodetype)}}");
668690 }
@@ -675,6 +697,7 @@ void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedHost(
675697
676698void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedDevice(
677699 {{solver.storage_t}}* const data, const size_t offset, const size_t num) {
700+ cudaSetDevice(device_id_);
678701 if (offset + num > {{num_key(nodetype)}}){
679702 throw std::runtime_error(std::to_string(offset + num) + " > {{num_key(nodetype)}}");
680703 }
@@ -695,6 +718,7 @@ void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedDevice(
695718 {% if fac .isnodeshared [arg ] %}
696719 void {{ solver.struct_name }}::Set{{parts_to_pascal(fac.name)}}{{parts_to_pascal(arg)}}IndicesFromHost(
697720 const unsigned int* const indices, size_t num) {
721+ cudaSetDevice(device_id_);
698722 if (num != {{num_key(fac)}}){
699723 throw std::runtime_error(
700724 std::to_string(num)
@@ -708,7 +732,8 @@ void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedDevice(
708732 void {{ solver.struct_name }}::Set{{parts_to_pascal(fac.name)}}{{parts_to_pascal(arg)}}IndicesFromDevice(
709733 const unsigned int* const indices, size_t num) {
710734 indices_valid_ = false;
711-
735+ cudaSetDevice(device_id_);
736+
712737 if (num != {{num_key(fac)}}){
713738 throw std::runtime_error(
714739 std::to_string(num)
@@ -737,6 +762,7 @@ void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedDevice(
737762 const {{solver.storage_t}}* const data, size_t offset, size_t num
738763 {% endif %}
739764 ) {
765+ cudaSetDevice(device_id_);
740766 {% if fac .isconstuniq [arg ] %}
741767 const size_t offset = 0;
742768 const size_t num = 1;
@@ -769,6 +795,7 @@ void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedDevice(
769795 {% elif fac .isconstindexed [arg ] %}
770796 const {{solver.storage_t}}* const data, size_t offset, size_t num
771797 {% endif %} ) {
798+ cudaSetDevice(device_id_);
772799 {% if fac .isconstuniq [arg ] %}
773800 const size_t offset = 0;
774801 const size_t num = 1;
@@ -791,6 +818,7 @@ void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedDevice(
791818 {% if fac .isconstshared [arg ] %}
792819 void {{ solver.struct_name }}::Set{{parts_to_pascal(fac.name)}}{{parts_to_pascal(arg)}}IndicesFromHost(
793820 const unsigned int* const indices, size_t num) {
821+ cudaSetDevice(device_id_);
794822 if (num != {{num_key(fac)}}){
795823 throw std::runtime_error(
796824 std::to_string(num)
@@ -804,7 +832,7 @@ void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedDevice(
804832 void {{ solver.struct_name }}::Set{{parts_to_pascal(fac.name)}}{{parts_to_pascal(arg)}}IndicesFromDevice(
805833 const unsigned int* const indices, size_t num) {
806834 indices_valid_ = false;
807-
835+ cudaSetDevice(device_id_);
808836 if (num != {{num_key(fac)}}){
809837 throw std::runtime_error(
810838 std::to_string(num)
@@ -824,6 +852,7 @@ void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedDevice(
824852 void {{ solver.struct_name }}::Set{{parts_to_pascal(fac.name)}}{{parts_to_pascal(arg)}}IndicesFromHost(
825853 const unsigned int* const indices, size_t num) {
826854 indices_valid_ = false;
855+ cudaSetDevice(device_id_);
827856 if (num != {{num_key(fac)}}){
828857 throw std::runtime_error(
829858 std::to_string(num)
@@ -836,6 +865,7 @@ void {{solver.struct_name}}::Get{{nodetype.__name__}}NodesToStackedDevice(
836865 void {{ solver.struct_name }}::Set{{parts_to_pascal(fac.name)}}{{parts_to_pascal(arg)}}IndicesFromDevice(
837866 const unsigned int* const indices, size_t num) {
838867 indices_valid_ = false;
868+ cudaSetDevice(device_id_);
839869 if (num != {{num_key(fac)}}){
840870 throw std::runtime_error(
841871 std::to_string(num)
0 commit comments