Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Read by thought-leaders and decision-makers around the world. Phone Number: +1-650-246-9381 Email: pub@towardsai.net
228 Park Avenue South New York, NY 10003 United States
Website: Publisher: https://towardsai.net/#publisher Diversity Policy: https://towardsai.net/about Ethics Policy: https://towardsai.net/about Masthead: https://towardsai.net/about
Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Founders: Roberto Iriondo, , Job Title: Co-founder and Advisor Works for: Towards AI, Inc. Follow Roberto: X, LinkedIn, GitHub, Google Scholar, Towards AI Profile, Medium, ML@CMU, FreeCodeCamp, Crunchbase, Bloomberg, Roberto Iriondo, Generative AI Lab, Generative AI Lab Denis Piffaretti, Job Title: Co-founder Works for: Towards AI, Inc. Louie Peters, Job Title: Co-founder Works for: Towards AI, Inc. Louis-François Bouchard, Job Title: Co-founder Works for: Towards AI, Inc. Cover:
Towards AI Cover
Logo:
Towards AI Logo
Areas Served: Worldwide Alternate Name: Towards AI, Inc. Alternate Name: Towards AI Co. Alternate Name: towards ai Alternate Name: towardsai Alternate Name: towards.ai Alternate Name: tai Alternate Name: toward ai Alternate Name: toward.ai Alternate Name: Towards AI, Inc. Alternate Name: towardsai.net Alternate Name: pub.towardsai.net
5 stars – based on 497 reviews

Frequently Used, Contextual References

TODO: Remember to copy unique IDs whenever it needs used. i.e., URL: 304b2e42315e

Resources

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

Publication

How South Africa Is Solving One of HPC’s Biggest Challenges
Latest   Machine Learning

How South Africa Is Solving One of HPC’s Biggest Challenges

Last Updated on July 20, 2023 by Editorial Team

Author(s): Jan Rowell

Originally published on Towards AI.

The Future of HPC Leadership U+007C Towards AI

A strategic approach to a student cluster competition nets top prizes and helps address a critical skills shortage

High-performance computing (HPC) drives economic growth and scientific progress around the world. But HPC skills are in short supply, and the problem is growing more critical as HPC workloads increasingly encompass artificial intelligence (AI) and big data as well as modeling and simulation.

The Republic of South Africa is using international student cluster competitions as one way to expand its HPC workforce. Its efforts have been so successful that it has emerged as a global powerhouse, with other teams and national leaders asking how they do it. It also has South Africa looking toward a more pan-African focus for future competitions. We spoke with South African students and leaders to learn more.

A Global Challenge

South Africa has fielded a national team for the past seven years in the International Supercomputing Conference (ISC) Student Cluster Competition, held in Frankfurt, Germany, in conjunction with what is now known as the ISC High-Performance conference. The nation took top honors in 2019 and in three previous years. When they weren’t taking home the top prize, the South African teams secured two second-place finishes and one-third place, giving them major hardware all seven years. The 2019 team also earned honorable mention for its performance on the LINPACK benchmark.

South Africa’s leaders view the competition as a way to expose undergraduates to HPC, increase their knowledge of the field, and ultimately help fill South Africa’s HPC pipeline. “The paucity of skills is the biggest challenge in HPC, and it is not unique to South Africa,” said Dr. Happy Marumo Sithole, who directs South Africa’s Center for High Performance Computing (CHPC). “The student competition leads to more students getting excited about HPC and developing skills that are critical for South Africa and the rest of the world. It is helping us remove a major roadblock.”

Strategic Goals

South Africa is the continent’s leader in high-performance computing. Along with Australia, it will be one of two countries to host the massive radio telescopes and supercomputers that will comprise the Square Kilometer Array (SKA) project, an international collaboration to field a next-generation radio observatory. In 2016, CHPC installed Africa’s fastest supercomputer, a petaflops Dell cluster powered by Intel Xeon processors. The nation established the CHPC in 2007 under the management of its Council for Scientific and Industrial Research (CSIR). CHPC has since funded major research in areas ranging from astrophysics to climate change to HIV modeling.

“High-performance computing supports South Africa’s systems of research, innovation, and industry,” said Dr. Sithole. “It is essential to industrial modernization and large-scale science projects that will improve social and economic development and scientific understanding in South Africa, across the continent, and around the world.”

The student cluster competition emphasizes practical challenges and applications in high-performance computing. Each team designs and builds a cluster and uses it to run a set of industry-standard HPC benchmarks and widely used applications. Reflecting real-world constraints, the judging is based on the performance achieved without exceeding a power range of 3 kilowatts. The 2019 teams ran benchmarks that tested floating-point and integer performance, sustainable memory bandwidth, and other critical metrics. The applications were relevant to astrophysics, quantum chemistry, hydrodynamics and gravity, fluid dynamics, deep learning model training, climate modeling, and other areas.

“When students learn about HPC and see all that it can do, they become interested and excited,” Dr. Sithole said.

National Team, Year-Round Process

To fulfill their strategic objectives, South Africa’s HPC leaders decided to create the country’s team through a nationwide competition, choosing all new members each year. The 2019 team consisted of Kaamilah Desai and Anita de Mello Koch from the University of the Witwatersrand in Johannesburg, and Dillon Heald, Stefan Schroeder, Jehan Singh, and Clara Stassen from the University of Cape Town. They competed against 13 teams from China, Estonia, Germany, Poland, Scotland, Spain, Switzerland, and the United States.

The competition is a year-round activity in South Africa, with the first step toward selection taking place shortly after the Frankfurt competition concludes. In this first phase, CSIR invites universities around the country to send four-person teams to Cape Town, where students learn the basics of building a Linux-based cluster and create a prototype cluster in the cloud. The first-round competition for the 2020 team was held in early July in Cape Town and drew 20 teams from across the country.

The gender balance of the 2019 team came about “accidentally on purpose,” according to CHPC’s David Macleod, who, along with fellow CHPC computer engineer Matthew Cawood, coaches the team. “We bake diversity in at the start,” Macleod said. “We reach out to minorities and give them the encouragement to participate. For 2020, we’re requiring each team at this first level to have at least one woman. After the first level, we go strictly by merit.”

In the second round, held in December, teams build small clusters out of parts supplied by CHPC. They install software and run benchmarks, and are judged on the cluster design and application performance.

Designing a Powerful Cluster

Once the team is chosen, the students spend the next six months designing the cluster for the international competition and optimizing their software stack. Students conduct research and identify the technologies they believe will give them the best chance to win the competition. Then, team advisors work with global technology sponsors to secure hardware. The South African divisions of international enterprises have been supportive of the project from its earliest years, even before the teams started racking up wins.

“To have any chance of winning, you need excellent hardware,” said Macleod. “The final scores are often very close, so getting the best performance per watt and wringing every bit of performance out of the system can make the difference. If you’re not coming with the very, very best hardware you can, you’re going to have a difficult time.”

The 2019 team identified the Intel Xeon Platinum 8180 processor as offering the best capabilities, including performance/watt, for the competition’s diverse workloads and benchmarks. Intel provided the processor, and Dell donated a six-node PowerEdge with two 8180 processors per node. NVIDIA and Mellanox were also sponsors, and the cluster used V100 GPUs for training and inferencing for a climate modeling AI solution and for the HPL portion of the HPC Challenge benchmarks. All other codes ran on the Intel Xeon Platinum processors.

“We found the Intel Xeon Platinum processor had the best performance per watt and the best solutions for managing the power,” said Heald. “We used the model-specific registers to control the thermal design power when we needed to. We also had the libraries and compilers, which worked very well with the Intel processors.”

The processor’s high core count was another plus. “With 28 cores per processor, we had the flexibility to clock the cores lower to get better performance and power efficiency when we needed to,” said Singh.

The students said other elements of the Intel HPC environment delivered further value. Swift, the hydrodynamics and gravity code, benefited from Intel Advanced Vector Extensions 512. CP2K, the quantum chemistry, and solid-state physics package, got a boost from Intel OpenMP and the Intel Math Kernel Library. “We used Intel Parallel Studio to compile many of our codes because the Intel compilers gave us such good performance gains,” Singh added.

Beyond the Platform

In addition to donating the students’ desired hardware elements, the team’s sponsors and advisors were generous with advice, encouragement, and insights. Dell brought the students to visit its Texas headquarters, where they discussed design considerations and reviewed their eventual design with HPC experts from Dell and the Texas Advanced Computer Center (TACC). TACC, which houses the world’s fifth most powerful supercomputer, has a longstanding relationship with CHPC and waterfalls its end-of-life clusters to South Africa.

“The conversations with Dell and TACC were extremely helpful when we were learning about different types of processors and how the implementations can affect things within a cluster like latency, maximum throughput, and power limitations,” said Heald.

Fostering teamwork was also important. Each team member had primary responsibility for one application or benchmark, and each shadowed or provided backup for another teammate. Everyone emphasized having fun, keeping the atmosphere light, and encouraging questions. Students practiced on the available hardware and received the final hardware a week or two before they left for the competition. Once they arrived in Frankfurt, they reassembled the cluster, installed the software stack, and performed power profiling. When the starter bell rang, they were ready to go.

“It takes three things to win the competition,” Macleod said in summary. “You need talented students with an aptitude for the tasks. You need the right equipment. And you need to prepare. The team spent six months — from December, when they were chosen, to June, when they went to Frankfurt — and it showed. They were able to go in calm and stay focused. It really is a simple recipe.”

Advancing HPC, Advancing Africa

South Africa’s commitment to the student cluster competition is helping the nation grow a new crop of HPC leaders, expand its supply of human capital, and accelerate its scientific, technological, and economic progress.

Student competitors have gone from being unfamiliar with HPC to be eager to pursue a career in the field.

For example, Koch, who is majoring in electrical engineering, said, “The competition introduced me to HPC. If I hadn’t done the competition, I wouldn’t have been thinking of HPC and maybe never would have looked into it. Now, I can see that this field is going to become even more important as the world changes. It will be important to be part of this field.”

Similarly, Schroeder stated, “Our sponsors and CHPC have made possible an amazing opportunity that has opened my eyes to supercomputing and altered my career path. I hope to work with supercomputers in the future at the KSA project.”

The competition’s impact is poised to reach beyond South Africa. “Other African nations have realized the value of the student challenge and would like to see it in their countries,” said Dr. Sithole. “We have received interest in how they can develop their own competitive teams or participate in our program. Our intention is to move toward a more continental approach, and we have received funding from the South African government to start the process. We expect to see more involvement at ISC next year and over the long term.”

____________________

Jan Rowell is an award-winning writer who covers technology trends and advances in HPC, AI, healthcare, and other areas.

Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

Published via Towards AI

Feedback ↓

Sign Up for the Course
`; } else { console.error('Element with id="subscribe" not found within the page with class "home".'); } } }); // Remove duplicate text from articles /* Backup: 09/11/24 function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag elements.forEach(el => { const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 2) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); */ // Remove duplicate text from articles function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag // List of classes to be excluded const excludedClasses = ['medium-author', 'post-widget-title']; elements.forEach(el => { // Skip elements with any of the excluded classes if (excludedClasses.some(cls => el.classList.contains(cls))) { return; // Skip this element if it has any of the excluded classes } const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 10) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); //Remove unnecessary text in blog excerpts document.querySelectorAll('.blog p').forEach(function(paragraph) { // Replace the unwanted text pattern for each paragraph paragraph.innerHTML = paragraph.innerHTML .replace(/Author\(s\): [\w\s]+ Originally published on Towards AI\.?/g, '') // Removes 'Author(s): XYZ Originally published on Towards AI' .replace(/This member-only story is on us\. Upgrade to access all of Medium\./g, ''); // Removes 'This member-only story...' }); //Load ionic icons and cache them if ('localStorage' in window && window['localStorage'] !== null) { const cssLink = 'https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css'; const storedCss = localStorage.getItem('ionicons'); if (storedCss) { loadCSS(storedCss); } else { fetch(cssLink).then(response => response.text()).then(css => { localStorage.setItem('ionicons', css); loadCSS(css); }); } } function loadCSS(css) { const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); } //Remove elements from imported content automatically function removeStrongFromHeadings() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, h6, span'); elements.forEach(el => { const strongTags = el.querySelectorAll('strong'); strongTags.forEach(strongTag => { while (strongTag.firstChild) { strongTag.parentNode.insertBefore(strongTag.firstChild, strongTag); } strongTag.remove(); }); }); } removeStrongFromHeadings(); "use strict"; window.onload = () => { /* //This is an object for each category of subjects and in that there are kewords and link to the keywods let keywordsAndLinks = { //you can add more categories and define their keywords and add a link ds: { keywords: [ //you can add more keywords here they are detected and replaced with achor tag automatically 'data science', 'Data science', 'Data Science', 'data Science', 'DATA SCIENCE', ], //we will replace the linktext with the keyword later on in the code //you can easily change links for each category here //(include class="ml-link" and linktext) link: 'linktext', }, ml: { keywords: [ //Add more keywords 'machine learning', 'Machine learning', 'Machine Learning', 'machine Learning', 'MACHINE LEARNING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ai: { keywords: [ 'artificial intelligence', 'Artificial intelligence', 'Artificial Intelligence', 'artificial Intelligence', 'ARTIFICIAL INTELLIGENCE', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, nl: { keywords: [ 'NLP', 'nlp', 'natural language processing', 'Natural Language Processing', 'NATURAL LANGUAGE PROCESSING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, des: { keywords: [ 'data engineering services', 'Data Engineering Services', 'DATA ENGINEERING SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, td: { keywords: [ 'training data', 'Training Data', 'training Data', 'TRAINING DATA', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ias: { keywords: [ 'image annotation services', 'Image annotation services', 'image Annotation services', 'image annotation Services', 'Image Annotation Services', 'IMAGE ANNOTATION SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, l: { keywords: [ 'labeling', 'labelling', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, pbp: { keywords: [ 'previous blog posts', 'previous blog post', 'latest', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, mlc: { keywords: [ 'machine learning course', 'machine learning class', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, }; //Articles to skip let articleIdsToSkip = ['post-2651', 'post-3414', 'post-3540']; //keyword with its related achortag is recieved here along with article id function searchAndReplace(keyword, anchorTag, articleId) { //selects the h3 h4 and p tags that are inside of the article let content = document.querySelector(`#${articleId} .entry-content`); //replaces the "linktext" in achor tag with the keyword that will be searched and replaced let newLink = anchorTag.replace('linktext', keyword); //regular expression to search keyword var re = new RegExp('(' + keyword + ')', 'g'); //this replaces the keywords in h3 h4 and p tags content with achor tag content.innerHTML = content.innerHTML.replace(re, newLink); } function articleFilter(keyword, anchorTag) { //gets all the articles var articles = document.querySelectorAll('article'); //if its zero or less then there are no articles if (articles.length > 0) { for (let x = 0; x < articles.length; x++) { //articles to skip is an array in which there are ids of articles which should not get effected //if the current article's id is also in that array then do not call search and replace with its data if (!articleIdsToSkip.includes(articles[x].id)) { //search and replace is called on articles which should get effected searchAndReplace(keyword, anchorTag, articles[x].id, key); } else { console.log( `Cannot replace the keywords in article with id ${articles[x].id}` ); } } } else { console.log('No articles found.'); } } let key; //not part of script, added for (key in keywordsAndLinks) { //key is the object in keywords and links object i.e ds, ml, ai for (let i = 0; i < keywordsAndLinks[key].keywords.length; i++) { //keywordsAndLinks[key].keywords is the array of keywords for key (ds, ml, ai) //keywordsAndLinks[key].keywords[i] is the keyword and keywordsAndLinks[key].link is the link //keyword and link is sent to searchreplace where it is then replaced using regular expression and replace function articleFilter( keywordsAndLinks[key].keywords[i], keywordsAndLinks[key].link ); } } function cleanLinks() { // (making smal functions is for DRY) this function gets the links and only keeps the first 2 and from the rest removes the anchor tag and replaces it with its text function removeLinks(links) { if (links.length > 1) { for (let i = 2; i < links.length; i++) { links[i].outerHTML = links[i].textContent; } } } //arrays which will contain all the achor tags found with the class (ds-link, ml-link, ailink) in each article inserted using search and replace let dslinks; let mllinks; let ailinks; let nllinks; let deslinks; let tdlinks; let iaslinks; let llinks; let pbplinks; let mlclinks; const content = document.querySelectorAll('article'); //all articles content.forEach((c) => { //to skip the articles with specific ids if (!articleIdsToSkip.includes(c.id)) { //getting all the anchor tags in each article one by one dslinks = document.querySelectorAll(`#${c.id} .entry-content a.ds-link`); mllinks = document.querySelectorAll(`#${c.id} .entry-content a.ml-link`); ailinks = document.querySelectorAll(`#${c.id} .entry-content a.ai-link`); nllinks = document.querySelectorAll(`#${c.id} .entry-content a.ntrl-link`); deslinks = document.querySelectorAll(`#${c.id} .entry-content a.des-link`); tdlinks = document.querySelectorAll(`#${c.id} .entry-content a.td-link`); iaslinks = document.querySelectorAll(`#${c.id} .entry-content a.ias-link`); mlclinks = document.querySelectorAll(`#${c.id} .entry-content a.mlc-link`); llinks = document.querySelectorAll(`#${c.id} .entry-content a.l-link`); pbplinks = document.querySelectorAll(`#${c.id} .entry-content a.pbp-link`); //sending the anchor tags list of each article one by one to remove extra anchor tags removeLinks(dslinks); removeLinks(mllinks); removeLinks(ailinks); removeLinks(nllinks); removeLinks(deslinks); removeLinks(tdlinks); removeLinks(iaslinks); removeLinks(mlclinks); removeLinks(llinks); removeLinks(pbplinks); } }); } //To remove extra achor tags of each category (ds, ml, ai) and only have 2 of each category per article cleanLinks(); */ //Recommended Articles var ctaLinks = [ /* ' ' + '

Subscribe to our AI newsletter!

' + */ '

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

'+ '

Towards AI has published Building LLMs for Production—our 470+ page guide to mastering LLMs with practical projects and expert insights!

' + '
' + '' + '' + '

Note: Content contains the views of the contributing authors and not Towards AI.
Disclosure: This website may contain sponsored content and affiliate links.

' + 'Discover Your Dream AI Career at Towards AI Jobs' + '

Towards AI has built a jobs board tailored specifically to Machine Learning and Data Science Jobs and Skills. Our software searches for live AI jobs each hour, labels and categorises them and makes them easily searchable. Explore over 10,000 live jobs today with Towards AI Jobs!

' + '
' + '

🔥 Recommended Articles 🔥

' + 'Why Become an LLM Developer? Launching Towards AI’s New One-Stop Conversion Course'+ 'Testing Launchpad.sh: A Container-based GPU Cloud for Inference and Fine-tuning'+ 'The Top 13 AI-Powered CRM Platforms
' + 'Top 11 AI Call Center Software for 2024
' + 'Learn Prompting 101—Prompt Engineering Course
' + 'Explore Leading Cloud Providers for GPU-Powered LLM Training
' + 'Best AI Communities for Artificial Intelligence Enthusiasts
' + 'Best Workstations for Deep Learning
' + 'Best Laptops for Deep Learning
' + 'Best Machine Learning Books
' + 'Machine Learning Algorithms
' + 'Neural Networks Tutorial
' + 'Best Public Datasets for Machine Learning
' + 'Neural Network Types
' + 'NLP Tutorial
' + 'Best Data Science Books
' + 'Monte Carlo Simulation Tutorial
' + 'Recommender System Tutorial
' + 'Linear Algebra for Deep Learning Tutorial
' + 'Google Colab Introduction
' + 'Decision Trees in Machine Learning
' + 'Principal Component Analysis (PCA) Tutorial
' + 'Linear Regression from Zero to Hero
'+ '

', /* + '

Join thousands of data leaders on the AI newsletter. It’s free, we don’t spam, and we never share your email address. Keep up to date with the latest work in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

',*/ ]; var replaceText = { '': '', '': '', '
': '
' + ctaLinks + '
', }; Object.keys(replaceText).forEach((txtorig) => { //txtorig is the key in replacetext object const txtnew = replaceText[txtorig]; //txtnew is the value of the key in replacetext object let entryFooter = document.querySelector('article .entry-footer'); if (document.querySelectorAll('.single-post').length > 0) { //console.log('Article found.'); const text = entryFooter.innerHTML; entryFooter.innerHTML = text.replace(txtorig, txtnew); } else { // console.log('Article not found.'); //removing comment 09/04/24 } }); var css = document.createElement('style'); css.type = 'text/css'; css.innerHTML = '.post-tags { display:none !important } .article-cta a { font-size: 18px; }'; document.body.appendChild(css); //Extra //This function adds some accessibility needs to the site. function addAlly() { // In this function JQuery is replaced with vanilla javascript functions const imgCont = document.querySelector('.uw-imgcont'); imgCont.setAttribute('aria-label', 'AI news, latest developments'); imgCont.title = 'AI news, latest developments'; imgCont.rel = 'noopener'; document.querySelector('.page-mobile-menu-logo a').title = 'Towards AI Home'; document.querySelector('a.social-link').rel = 'noopener'; document.querySelector('a.uw-text').rel = 'noopener'; document.querySelector('a.uw-w-branding').rel = 'noopener'; document.querySelector('.blog h2.heading').innerHTML = 'Publication'; const popupSearch = document.querySelector$('a.btn-open-popup-search'); popupSearch.setAttribute('role', 'button'); popupSearch.title = 'Search'; const searchClose = document.querySelector('a.popup-search-close'); searchClose.setAttribute('role', 'button'); searchClose.title = 'Close search page'; // document // .querySelector('a.btn-open-popup-search') // .setAttribute( // 'href', // 'https://medium.com/towards-artificial-intelligence/search' // ); } // Add external attributes to 302 sticky and editorial links function extLink() { // Sticky 302 links, this fuction opens the link we send to Medium on a new tab and adds a "noopener" rel to them var stickyLinks = document.querySelectorAll('.grid-item.sticky a'); for (var i = 0; i < stickyLinks.length; i++) { /* stickyLinks[i].setAttribute('target', '_blank'); stickyLinks[i].setAttribute('rel', 'noopener'); */ } // Editorial 302 links, same here var editLinks = document.querySelectorAll( '.grid-item.category-editorial a' ); for (var i = 0; i < editLinks.length; i++) { editLinks[i].setAttribute('target', '_blank'); editLinks[i].setAttribute('rel', 'noopener'); } } // Add current year to copyright notices document.getElementById( 'js-current-year' ).textContent = new Date().getFullYear(); // Call functions after page load extLink(); //addAlly(); setTimeout(function() { //addAlly(); //ideally we should only need to run it once ↑ }, 5000); }; function closeCookieDialog (){ document.getElementById("cookie-consent").style.display = "none"; return false; } setTimeout ( function () { closeCookieDialog(); }, 15000); console.log(`%c 🚀🚀🚀 ███ █████ ███████ █████████ ███████████ █████████████ ███████████████ ███████ ███████ ███████ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ Towards AI is looking for contributors! │ │ Join us in creating awesome AI content. │ │ Let's build the future of AI together → │ │ https://towardsai.net/contribute │ │ │ └───────────────────────────────────────────────────────────────────┘ `, `background: ; color: #00adff; font-size: large`); //Remove latest category across site document.querySelectorAll('a[rel="category tag"]').forEach(function(el) { if (el.textContent.trim() === 'Latest') { // Remove the two consecutive spaces (  ) if (el.nextSibling && el.nextSibling.nodeValue.includes('\u00A0\u00A0')) { el.nextSibling.nodeValue = ''; // Remove the spaces } el.style.display = 'none'; // Hide the element } }); // Add cross-domain measurement, anonymize IPs 'use strict'; //var ga = gtag; ga('config', 'G-9D3HKKFV1Q', 'auto', { /*'allowLinker': true,*/ 'anonymize_ip': true/*, 'linker': { 'domains': [ 'medium.com/towards-artificial-intelligence', 'datasets.towardsai.net', 'rss.towardsai.net', 'feed.towardsai.net', 'contribute.towardsai.net', 'members.towardsai.net', 'pub.towardsai.net', 'news.towardsai.net' ] } */ }); ga('send', 'pageview'); -->