static int get_ofi_provider()

in src/nccl_ofi_net.c [565:634]


static int get_ofi_provider(char *prov_include, struct fi_info **prov_info_list)
{
	int idx = 0, prov_idx = 0, i, rc = 0;
	struct fi_info *providers = NULL, *prov = NULL;
	struct fi_info *prov_info_vec[MAX_PROV_INFO] = {NULL};
	int info_count[MAX_PROV_INFO] = {0};
	char *prov_name;

	rc = find_ofi_provider(&providers);
	if (rc != 0)
		goto error;

	/*
	 * Create an array of providers where each index represents
	 * a info structure list for a single provider name.
	 */
	prov_info_vec[idx] = providers;

	prov = providers;
	prov_name = prov->fabric_attr->prov_name;
	while (prov != NULL && prov->next != NULL) {

		/* Increment number of devices found for the given provider */
		info_count[idx]++;

		char *name = prov->next->fabric_attr->prov_name;
		if (strcmp(prov_name, name) != 0) {
			prov_name = name;
			prov_info_vec[++idx] = prov->next;
			prov->next = NULL;
			prov = prov_info_vec[idx];
		}
		else {
			prov = prov->next;
		}
	}

	/* To account for the last prov object */
	if (prov != NULL)
		info_count[idx]++;

	if (prov_include == NULL) {
		*prov_info_list = prov_info_vec[0];
		ofi_ndevices = info_count[0];
	}
	else {
		for (prov_idx = 0; prov_idx <= idx; prov_idx++) {
			prov_name = prov_info_vec[prov_idx]->fabric_attr->prov_name;
			if (in_list(prov_name, prov_include)) {
				*prov_info_list = prov_info_vec[prov_idx];
				ofi_ndevices = info_count[prov_idx];
				break;
			}
		}
	}

	/* Free unused fi_info objects */
	for (i = 0; i <= idx; i++) {
		if ((i != prov_idx) && prov_info_vec[i]) {
			fi_freeinfo(prov_info_vec[i]);
		}
	}

	return ncclSuccess;

error:
	if (providers)
		fi_freeinfo(providers);
	return ncclSystemError;
}